diff --git a/bsp/dev3210/SConstruct b/bsp/dev3210/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..daef69507919b65975c6cc03a910379c70a9d2f8 --- /dev/null +++ b/bsp/dev3210/SConstruct @@ -0,0 +1,40 @@ +import os +import sys +import rtconfig + +RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] + +target = 'rtthread' +projects = [] + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +Export('env') +Export('RTT_ROOT') +Export('rtconfig') +Export('projects') + +# kernel building script +objs = SConscript(RTT_ROOT + '/src/SConscript', variant_dir='build/src', duplicate=0) +# arch building script +objs = objs + SConscript(RTT_ROOT + '/libcpu/SConscript', variant_dir='build/libcpu', duplicate=0) + +# component script +Repository(RTT_ROOT) +objs = objs + SConscript('components/SConscript') + +# board build script +objs = objs + SConscript('SConscript', variant_dir='build/bsp', duplicate=0) + +if rtconfig.RT_USING_RTGUI: + objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0) + +TARGET = target + '.' + rtconfig.TARGET_EXT +env.Program(TARGET, objs) +env.AddPostAction(TARGET, rtconfig.POST_ACTION) diff --git a/bsp/dev3210/application.c b/bsp/dev3210/application.c new file mode 100644 index 0000000000000000000000000000000000000000..4400f2caf0d86bb90bc6dcd08f8d5d9b9e8a3932 --- /dev/null +++ b/bsp/dev3210/application.c @@ -0,0 +1,132 @@ +/* + * File : app.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-06-25 Bernard first version + */ + +/** + * @addtogroup Loongson SoC3210 + */ +/*@{*/ +#include +#include + +struct rt_thread thread; +ALIGN(4) +rt_uint8_t thread_stack[1024]; + +#include +void thread_entry(void* parameter) +{ + int i = 0; + + while (1) + { + rt_kprintf("i = %d, cause: 0x%08x, config: 0x%08x\n", i++, read_c0_cause(), read_c0_config()); + rt_kprintf("HSB_MISC_CFG 0x%08x\n", HSB_MISC_REG); + rt_thread_delay(100); + } +} +void thread_test() +{ + rt_err_t result = rt_thread_init(&thread, + "tid", + thread_entry, RT_NULL, + &thread_stack, sizeof(thread_stack), + 200, + 5); + if (result == RT_EOK) + rt_thread_startup(&thread); + else + rt_kprintf("init thread failed\n"); +} +FINSH_FUNCTION_EXPORT(thread_test, test thread!!); + +#include +#include +#include + +int rt_application_init() +{ + rtgui_rect_t rect; + + rtgui_system_server_init(); + + /* register dock panel */ + rect.x1 = 0; + rect.y1 = 0; + rect.x2 = 400; + rect.y2 = 480; + rtgui_panel_register("panel", &rect); + + /* register main panel */ + rect.x1 = 400; + rect.y1 = 0; + rect.x2 = 800; + rect.y2 = 480; + rtgui_panel_register("main", &rect); + rtgui_panel_set_default_focused("main"); + + rt_hw_lcd_init(); + + /* init example workbench */ + // workbench_init(); + + return 0; +} + +/* key simulator */ +static struct rtgui_event_kbd kbd_event; +void key_simulator(int key) +{ + /* init keyboard event */ + RTGUI_EVENT_KBD_INIT(&kbd_event); + kbd_event.mod = RTGUI_KMOD_NONE; + kbd_event.unicode = 0; + kbd_event.type = RTGUI_KEYDOWN; + kbd_event.key = key; + + /* post down event */ + rtgui_server_post_event(&(kbd_event.parent), sizeof(kbd_event)); + + /* delay to post up event */ + rt_thread_delay(50); + + /* post up event */ + kbd_event.type = RTGUI_KEYUP; + rtgui_server_post_event(&(kbd_event.parent), sizeof(kbd_event)); +} + +void left() +{ + key_simulator(RTGUIK_LEFT); +} +FINSH_FUNCTION_EXPORT(left, left key); + +void right() +{ + key_simulator(RTGUIK_LEFT); +} +FINSH_FUNCTION_EXPORT(right, right key); + +void down() +{ + key_simulator(RTGUIK_DOWN); +} +FINSH_FUNCTION_EXPORT(down, down key); + +void up() +{ + key_simulator(RTGUI_KEYUP); +} +FINSH_FUNCTION_EXPORT(up, up key); + +/*@}*/ diff --git a/bsp/dev3210/board.c b/bsp/dev3210/board.c new file mode 100644 index 0000000000000000000000000000000000000000..c0f6710f02ce61bf8f74cb2e7a87a57e80631374 --- /dev/null +++ b/bsp/dev3210/board.c @@ -0,0 +1,102 @@ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-06-25 Bernard first version + */ + +#include +#include + +#include "board.h" +#include "uart.h" +#include + +/** + * @addtogroup Loongson SoC3210 + */ +/*@{*/ + +/** + * This is the timer interrupt service routine. + */ +void rt_hw_timer_handler() +{ + unsigned int count; + + count = read_c0_compare(); + write_c0_compare(count); + write_c0_count(0); + + /* increase a OS tick */ + rt_tick_increase(); +} + +/** + * This function will initial OS timer + */ +void rt_hw_timer_init() +{ + write_c0_compare(CPU_HZ/2/RT_TICK_PER_SECOND); + write_c0_count(0); +} + +/** + * This function will initial sam7s64 board. + */ +void rt_hw_board_init() +{ +#ifdef RT_USING_UART + /* init hardware UART device */ + rt_hw_uart_init(); +#endif + +#ifdef RT_USING_CONSOLE + /* set console device */ + rt_console_set_device("uart"); +#endif + + /* init operating system timer */ + rt_hw_timer_init(); + + rt_kprintf("current sr: 0x%08x\n", read_c0_status()); +} +/*@}*/ + +/* UART line status register value */ +#define UARTLSR_ERROR (1 << 7) +#define UARTLSR_TE (1 << 6) +#define UARTLSR_TFE (1 << 5) +#define UARTLSR_BI (1 << 4) +#define UARTLSR_FE (1 << 3) +#define UARTLSR_PE (1 << 2) +#define UARTLSR_OE (1 << 1) +#define UARTLSR_DR (1 << 0) +void rt_hw_console_output(const char* ptr) +{ + /* stream mode */ + while (*ptr) + { + if (*ptr == '\n') + { + /* FIFO status, contain valid data */ + while (!(UART_LSR(UART0_BASE) & (UARTLSR_TE | UARTLSR_TFE))); + /* write data */ + UART_DAT(UART0_BASE) = '\r'; + } + + /* FIFO status, contain valid data */ + while (!(UART_LSR(UART0_BASE) & (UARTLSR_TE | UARTLSR_TFE))); + /* write data */ + UART_DAT(UART0_BASE) = *ptr; + + ptr ++; + } +} diff --git a/bsp/dev3210/board.h b/bsp/dev3210/board.h new file mode 100644 index 0000000000000000000000000000000000000000..51c083310f31274bd8de000f5e0cab04a7e1d8dc --- /dev/null +++ b/bsp/dev3210/board.h @@ -0,0 +1,24 @@ +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006-2010, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-06-25 Bernard first version + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +void rt_hw_board_init(void); + +/* 32M SDRAM */ +#define RT_HW_HEAP_END (0x80000000 + 32 * 1024 * 1024) +#define CPU_HZ (250 * 1000000) + +#endif diff --git a/bsp/dev3210/dev3210_ram.lds b/bsp/dev3210/dev3210_ram.lds new file mode 100644 index 0000000000000000000000000000000000000000..d3e177d02b8393581481a3f7e1192bd869b2ac7b --- /dev/null +++ b/bsp/dev3210/dev3210_ram.lds @@ -0,0 +1,153 @@ +/* + * File : jz47xx_ram.lds + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-05-17 swkyer first version + * 2010-09-04 bernard move the beginning entry to 0x80200000 + */ + +OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlittlemips") +OUTPUT_ARCH(mips) + +MEMORY +{ + /* 16M SDRAM */ + DRAM : ORIGIN = 0x80200000, LENGTH = 0x01000000 + /* 16K SRAM */ + IRAM : ORIGIN = 0x80000000, LENGTH = 0x00004000 +} + +ENTRY(_start) +SECTIONS +{ + . = 0x80200000 ; + + .start : + { + *(.start); + } > DRAM + + . = ALIGN(4); + + .text : + { + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + *(.rodata1) + *(.rodata1.*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + } > DRAM + + . = ALIGN(4); + + .data : + { + *(.data) + *(.data.*) + + *(.data1) + *(.data1.*) + + . = ALIGN(8); + _gp = ABSOLUTE(.); /* Base of small data */ + + *(.sdata) + *(.sdata.*) + } > DRAM + + . = ALIGN(4); + _iramat = .; + + .iram : AT(_iramat) + { + _iramstart = .; + *(.vectors.1); + . = 0x100; + *(.vectors.2); + . = 0x180; + *(.vectors.3); + . = 0x200; + *(.vectors.4); + *(.vectors); + + *(.icode); + *(.irodata); + *(.idata); + KEEP(*(.vectors*)) + _iramend = .; + } > IRAM + _iramcopy = LOADADDR(.iram); + + .sbss : + { + __bss_start = .; + *(.sbss) + *(.sbss.*) + *(.dynsbss) + *(.scommon) + } > DRAM + + .bss : + { + *(.bss) + *(.bss.*) + *(.dynbss) + *(COMMON) + __bss_end = .; + } > DRAM + + _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) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/dev3210/dw.txt b/bsp/dev3210/dw.txt new file mode 100644 index 0000000000000000000000000000000000000000..e58da7fea407d652c97a33e594d0fdd44ea98d16 --- /dev/null +++ b/bsp/dev3210/dw.txt @@ -0,0 +1,6 @@ +ifaddr dmfe0 192.168.1.100 +load tftp://192.168.1.5/boot_3210 0x80200000 + +ifaddr dmfe0 192.168.1.100 +load tftp://192.168.1.5/rtthread.elf 0x80200000 +oload tftp://192.168.1.5/rtthread.bin 0x80200000 diff --git a/bsp/dev3210/lnn800x480.c b/bsp/dev3210/lnn800x480.c new file mode 100644 index 0000000000000000000000000000000000000000..380034de840e64f1323b3db64e5299593b9aff48 --- /dev/null +++ b/bsp/dev3210/lnn800x480.c @@ -0,0 +1,184 @@ +/* + * File : lcd_800480.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2010, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-01-01 bernard first version from QiuYi's driver + */ + +#include +#include +#include +#include + +/* LCD driver for 800x480 16bit */ +#define RT_HW_LCD_WIDTH 800 +#define RT_HW_LCD_HEIGHT 480 + +ALIGN(4) +volatile rt_uint16_t _rt_framebuffer[RT_HW_LCD_HEIGHT][RT_HW_LCD_WIDTH]; + +#define K1BASE 0xA0000000 +#define KSEG1(addr) ((void *)(K1BASE | (rt_uint32_t)(addr))) +#define HW_FB_ADDR KSEG1(_rt_framebuffer) +#define HW_FB_PIXEL(x, y) *(volatile rt_uint16_t*)((rt_uint8_t*)HW_FB_ADDR + (y * RT_HW_LCD_WIDTH * 2) + x * 2) + +void rt_hw_lcd_update(rtgui_rect_t *rect) +{ +} + +rt_uint8_t * rt_hw_lcd_get_framebuffer(void) +{ + return (rt_uint8_t *)HW_FB_ADDR; +} + +void rt_hw_lcd_set_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + if (x < RT_HW_LCD_WIDTH && y < RT_HW_LCD_HEIGHT) + { + HW_FB_PIXEL(x, y) = rtgui_color_to_565p(*c); + } +} + +void rt_hw_lcd_get_pixel(rtgui_color_t *c, rt_base_t x, rt_base_t y) +{ + if (x < RT_HW_LCD_WIDTH && y < RT_HW_LCD_HEIGHT) + { + *c = rtgui_color_from_565p(HW_FB_PIXEL(x, y)); + } + + return ; +} + +void rt_hw_lcd_draw_hline(rtgui_color_t *c, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_uint32_t idx; + rt_uint16_t color; + + /* get color pixel */ + color = rtgui_color_to_565p(*c); + + for (idx = x1; idx < x2; idx ++) + { + HW_FB_PIXEL(idx, y) = color; + } +} + +void rt_hw_lcd_draw_vline(rtgui_color_t *c, rt_base_t x, rt_base_t y1, rt_base_t y2) +{ + rt_uint32_t idy; + rt_uint16_t color; + + /* get color pixel */ + color = rtgui_color_to_565p(*c); + + for (idy = y1; idy < y2; idy ++) + { + HW_FB_PIXEL(x, idy) = color; + } +} + +void rt_hw_lcd_draw_raw_hline(rt_uint8_t *pixels, rt_base_t x1, rt_base_t x2, rt_base_t y) +{ + rt_uint8_t* ptr; + + ptr = (rt_uint8_t*)&HW_FB_PIXEL(x1, y); + rt_memcpy(ptr, pixels, (x2 - x1) * 2); +} + +struct rtgui_graphic_driver _rtgui_lcd_driver = +{ + "lcd", + 2, + RT_HW_LCD_WIDTH, + RT_HW_LCD_HEIGHT, + rt_hw_lcd_update, + rt_hw_lcd_get_framebuffer, + rt_hw_lcd_set_pixel, + rt_hw_lcd_get_pixel, + rt_hw_lcd_draw_hline, + rt_hw_lcd_draw_vline, + rt_hw_lcd_draw_raw_hline +}; + +#include "finsh.h" +void hline(rt_uint32_t c, int x1, int x2, int y) +{ + rtgui_color_t color = (rtgui_color_t)c; + rt_hw_lcd_draw_hline(&color, x1, x2, y); +} +FINSH_FUNCTION_EXPORT(hline, draw a hline); + +void vline(rt_uint32_t c, int x, int y1, int y2) +{ + rtgui_color_t color = (rtgui_color_t)c; + rt_hw_lcd_draw_vline(&color, x, y1, y2); +} +FINSH_FUNCTION_EXPORT(vline, draw a vline); + +void clear() +{ + int y; + + for (y = 0; y < _rtgui_lcd_driver.height; y ++) + { + rt_hw_lcd_draw_hline((rtgui_color_t*)&white, 0, 240, y); + } +} +FINSH_FUNCTION_EXPORT(clear, clear screen); + +void fill(rt_uint32_t c) +{ + int y; + rtgui_color_t color = (rtgui_color_t)c; + + for (y = 0; y < _rtgui_lcd_driver.height; y ++) + { + rt_hw_lcd_draw_hline(&color, 0, _rtgui_lcd_driver.width, y); + } +} +FINSH_FUNCTION_EXPORT(fill, fill screen with color); + +void lcd_init() +{ + /* disable LCD controller */ + LCD_CTRL = LCD_CTRL & 0xfffe; + + /* set LCD clock */ + HSB_MISC_REG = (HSB_MISC_REG & 0xFFFD01FF) | + (0x01 << 17) | /* enable LCD */ + (0x05 << 9); /* clock */ + + LCD_VBARA = (rt_uint32_t)_rt_framebuffer - 0x80000000; + LCD_VBARB = (rt_uint32_t)_rt_framebuffer - 0x80000000; + + LCD_HTIM = 0x12c031f; + LCD_VTIM = 0x11501df; + LCD_HVLEN = 0x41e0279; + + LCD_CTRL = 0x8709; + + rt_kprintf("VBARA 0x%08x\n", LCD_VBARA); + rt_kprintf("CTRL 0x%08x\n", LCD_CTRL); + rt_kprintf("HTIM 0x%08x\n", LCD_HTIM); + rt_kprintf("VTIM 0x%08x\n", LCD_VTIM); + rt_kprintf("HVLEN 0x%08x\n", LCD_HVLEN); + rt_kprintf("HSB_MISC 0x%08x\n", HSB_MISC_REG); + +#ifdef RT_USING_RTGUI + /* add lcd driver into graphic driver */ + rtgui_graphic_driver_add(&_rtgui_lcd_driver); +#endif +} +FINSH_FUNCTION_EXPORT(lcd_init, init lcd); + +void rt_hw_lcd_init() +{ + lcd_init(); +} diff --git a/bsp/dev3210/rtconfig.h b/bsp/dev3210/rtconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..7b8b32600f1c7c35a803ebeef652c6a23bd89f47 --- /dev/null +++ b/bsp/dev3210/rtconfig.h @@ -0,0 +1,154 @@ +/* RT-Thread config file */ +#ifndef __RTTHREAD_CFG_H__ +#define __RTTHREAD_CFG_H__ + +/* RT_NAME_MAX*/ +#define RT_NAME_MAX 10 + +/* RT_ALIGN_SIZE*/ +#define RT_ALIGN_SIZE 4 + +/* PRIORITY_MAX */ +#define RT_THREAD_PRIORITY_MAX 256 + +/* Tick per Second */ +#define RT_TICK_PER_SECOND 100 + +/* SECTION: RT_DEBUG */ +/* Thread Debug */ +#define RT_DEBUG +#define RT_USING_OVERFLOW_CHECK + +/* Using Hook */ +#define RT_USING_HOOK + +/* Using Software Timer */ +/* #define RT_USING_TIMER_SOFT */ +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_TIMER_TICK_PER_SECOND 10 + +/* SECTION: IPC */ +/* Using Semaphore */ +#define RT_USING_SEMAPHORE + +/* Using Mutex */ +#define RT_USING_MUTEX + +/* Using Event */ +#define RT_USING_EVENT + +/* Using MailBox */ +#define RT_USING_MAILBOX + +/* Using Message Queue */ +#define RT_USING_MESSAGEQUEUE + +/* SECTION: Memory Management */ +/* Using Memory Pool Management*/ +#define RT_USING_MEMPOOL + +/* Using Dynamic Heap Management */ +#define RT_USING_HEAP + +/* Using SLAB MM */ +#define RT_USING_SLAB + +/* SECTION: Device System */ +/* Using Device System */ +#define RT_USING_DEVICE +#define RT_USING_UART +#define RT_USING_UART1 +#define RT_UART_RX_BUFFER_SIZE 64 + +/* SECTION: Console options */ +/* the buffer size of console */ +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 128 + +/* SECTION: finsh, a C-Express shell */ +/* Using FinSH as Shell*/ +#define RT_USING_FINSH +/* Using symbol table */ +#define FINSH_USING_SYMTAB +#define FINSH_USING_DESCRIPTION +#define FINSH_DEVICE_NAME "uart" + +/* SECTION: device filesystem support */ +/* #define RT_USING_DFS */ +#define RT_USING_DFS_ELMFAT + +/* the max number of mounted filesystem */ +#define DFS_FILESYSTEMS_MAX 2 +/* the max number of opened files */ +#define DFS_FD_MAX 4 +/* the max number of cached sector */ +#define DFS_CACHE_MAX_NUM 4 + +/* SECTION: lwip, a lighwight TCP/IP protocol stack */ +/* #define RT_USING_LWIP */ +#define RT_LWIP_USING_RT_MEM + +/* Enable ICMP protocol*/ +#define RT_LWIP_ICMP +/* Enable UDP protocol*/ +#define RT_LWIP_UDP +/* Enable TCP protocol*/ +#define RT_LWIP_TCP +/* Enable DNS */ +#define RT_LWIP_DNS + +/* the number of simulatenously active TCP connections*/ +#define RT_LWIP_TCP_PCB_NUM 5 + +/* ip address of target*/ +#define RT_LWIP_IPADDR0 192 +#define RT_LWIP_IPADDR1 168 +#define RT_LWIP_IPADDR2 1 +#define RT_LWIP_IPADDR3 30 + +/* gateway address of target*/ +#define RT_LWIP_GWADDR0 192 +#define RT_LWIP_GWADDR1 168 +#define RT_LWIP_GWADDR2 1 +#define RT_LWIP_GWADDR3 1 + +/* mask address of target*/ +#define RT_LWIP_MSKADDR0 255 +#define RT_LWIP_MSKADDR1 255 +#define RT_LWIP_MSKADDR2 255 +#define RT_LWIP_MSKADDR3 0 + +/* tcp thread options */ +#define RT_LWIP_TCPTHREAD_PRIORITY 12 +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 4 +#define RT_LWIP_TCPTHREAD_STACKSIZE 1024 + +/* ethernet if thread options */ +#define RT_LWIP_ETHTHREAD_PRIORITY 15 +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 4 +#define RT_LWIP_ETHTHREAD_STACKSIZE 512 + +/* SECTION: RT-Thread/GUI */ +#define RT_USING_RTGUI + +/* name length of RTGUI object */ +#define RTGUI_NAME_MAX 12 +/* support 16 weight font */ +#define RTGUI_USING_FONT16 +/* support 12 weight font */ +#define RTGUI_USING_FONT12 +/* support Chinese font */ +#define RTGUI_USING_FONTHZ +/* use DFS as file interface */ +#define RTGUI_USING_DFS_FILERW +/* use bmp font as Chinese font */ +#define RTGUI_USING_HZ_BMP +/* use small size in RTGUI */ +#define RTGUI_USING_SMALL_SIZE +/* use mouse cursor */ +/* #define RTGUI_USING_MOUSE_CURSOR */ +/* default font size in RTGUI */ +#define RTGUI_DEFAULT_FONT_SIZE 16 + +#endif diff --git a/bsp/dev3210/rtconfig.py b/bsp/dev3210/rtconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..2f7b09c52f62b70ede86023e0816b2e39e96b80d --- /dev/null +++ b/bsp/dev3210/rtconfig.py @@ -0,0 +1,88 @@ +import SCons.cpp + +# component options + +# make all component false +RT_USING_FINSH = False +RT_USING_DFS = False +RT_USING_DFS_ELMFAT = False +RT_USING_DFS_YAFFS2 = False +RT_USING_LWIP = False +RT_USING_WEBSERVER = False +RT_USING_RTGUI = False +RT_USING_MODULE = False + +# parse rtconfig.h to get used component +PreProcessor = SCons.cpp.PreProcessor() +f = file('rtconfig.h', 'r') +contents = f.read() +f.close() +PreProcessor.process_contents(contents) +rtconfig_ns = PreProcessor.cpp_namespace + +# finsh shell options +if rtconfig_ns.has_key('RT_USING_FINSH'): + RT_USING_FINSH = True + +# device virtual filesystem options +if rtconfig_ns.has_key('RT_USING_DFS'): + RT_USING_DFS = True + + if rtconfig_ns.has_key('RT_USING_DFS_ELMFAT'): + RT_USING_DFS_ELMFAT = True + if rtconfig_ns.has_key('RT_USING_DFS_YAFFS2'): + RT_USING_DFS_YAFFS2 = True + +# lwip options +if rtconfig_ns.has_key('RT_USING_LWIP'): + RT_USING_LWIP = True + if rtconfig_ns.has_key('RT_USING_WEBSERVER'): + RT_USING_WEBSERVER = True + +# rtgui options +if rtconfig_ns.has_key('RT_USING_RTGUI'): + RT_USING_RTGUI = True + +# module options +if rtconfig_ns.has_key('RT_USING_MODULE'): + RT_USING_MODULE = True + +# CPU options +ARCH='mips' +CPU ='loongson' + +# toolchains options +CROSS_TOOL = 'gcc' +PLATFORM = 'gcc' +EXEC_PATH = 'E:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' +BUILD = 'debug' + +PREFIX = 'mips-sde-elf-' +CC = PREFIX + 'gcc' +AS = PREFIX + 'gcc' +AR = PREFIX + 'ar' +LINK = PREFIX + 'gcc' +TARGET_EXT = 'elf' +SIZE = PREFIX + 'size' +OBJDUMP = PREFIX + 'objdump' +OBJCPY = PREFIX + 'objcopy' +READELF = PREFIX + 'readelf' + +DEVICE = ' -mips2' +CFLAGS = DEVICE + ' -EL -G0 -DRT_USING_MINILIBC -mno-abicalls -fno-pic -fno-builtin -fno-exceptions -ffunction-sections -fomit-frame-pointer' +AFLAGS = ' -c' + DEVICE + ' -EL -fno-pic -fno-builtin -mno-abicalls -x assembler-with-cpp' +LFLAGS = DEVICE + ' -EL -Wl,--gc-sections,-Map=rtthread-3210.map,-cref,-u,Reset_Handler -T dev3210_ram.lds' + +CPATH = '' +LPATH = '' + +if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' +else: + CFLAGS += ' -O2' + +RT_USING_MINILIBC = True +DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n' +READELF_ACTION = READELF + ' -a $TARGET > rtt.map\n' +POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + READELF_ACTION diff --git a/bsp/dev3210/startup.c b/bsp/dev3210/startup.c new file mode 100644 index 0000000000000000000000000000000000000000..29aa38e2ec235eba45c55ea6cdec61a940994122 --- /dev/null +++ b/bsp/dev3210/startup.c @@ -0,0 +1,103 @@ +/* + * File : startup.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-06-25 Bernard first version + */ + +#include +#include +#include + +#include "board.h" + +/** + * @addtogroup Loongson SoC3210 + */ + +/*@{*/ +extern unsigned char __bss_start; +extern unsigned char __bss_end; + +extern int rt_application_init(void); + +void dump_mem(const unsigned char* addr) +{ + int size; + rt_kprintf("---- memory: 0x%08x ----\n", addr); + for (size = 0; size < 32 * 4; size ++) + { + rt_kprintf("%02x ", (*addr) & 0xff); + addr ++; + if ((size + 1) % 16 == 0) + rt_kprintf("\n"); + } + rt_kprintf("\n"); +} + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* init cache */ + rt_hw_cache_init(); + /* init hardware interrupt */ + rt_hw_interrupt_init(); + + /* + dump_mem((rt_uint8_t*)0x80000000); + dump_mem((rt_uint8_t*)0x80000100); + dump_mem((rt_uint8_t*)0x80000180); + dump_mem((rt_uint8_t*)0x80000200); + */ + + /* init board */ + rt_hw_board_init(); + rt_show_version(); + + /* init tick */ + rt_system_tick_init(); + + /* init timer system */ + rt_system_timer_init(); + +#ifdef RT_USING_HEAP + rt_system_heap_init((void*)&__bss_end, (void*)RT_HW_HEAP_END); +#endif + + /* init scheduler system */ + rt_system_scheduler_init(); + +#ifdef RT_USING_DEVICE + /* init all device */ + rt_device_init_all(); +#endif + + /* init application */ + rt_application_init(); + +#ifdef RT_USING_FINSH + /* init finsh */ + finsh_system_init(); + finsh_set_device(FINSH_DEVICE_NAME); +#endif + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +/*@}*/ diff --git a/bsp/dev3210/uart.c b/bsp/dev3210/uart.c new file mode 100644 index 0000000000000000000000000000000000000000..8851678e68612f0a731e8bed15034809f420742b --- /dev/null +++ b/bsp/dev3210/uart.c @@ -0,0 +1,282 @@ +#include +#include + +#include + +/** + * @addtogroup Loongson SoC3210 + */ + +/*@{*/ +#if defined(RT_USING_UART) && defined(RT_USING_DEVICE) + +/* UART interrupt enable register value */ +#define UARTIER_IME (1 << 3) +#define UARTIER_ILE (1 << 2) +#define UARTIER_ITXE (1 << 1) +#define UARTIER_IRXE (1 << 0) + +/* UART line control register value */ +#define UARTLCR_DLAB (1 << 7) +#define UARTLCR_BCB (1 << 6) +#define UARTLCR_SPB (1 << 5) +#define UARTLCR_EPS (1 << 4) +#define UARTLCR_PE (1 << 3) +#define UARTLCR_SB (1 << 2) + +/* UART line status register value */ +#define UARTLSR_ERROR (1 << 7) +#define UARTLSR_TE (1 << 6) +#define UARTLSR_TFE (1 << 5) +#define UARTLSR_BI (1 << 4) +#define UARTLSR_FE (1 << 3) +#define UARTLSR_PE (1 << 2) +#define UARTLSR_OE (1 << 1) +#define UARTLSR_DR (1 << 0) + +struct rt_uart_soc3210 +{ + struct rt_device parent; + + rt_uint32_t hw_base; + rt_uint32_t irq; + + /* buffer for reception */ + rt_uint8_t read_index, save_index; + rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE]; +}uart_device; + +static void rt_uart_irqhandler(int irqno) +{ + rt_ubase_t level; + rt_uint8_t isr; + struct rt_uart_soc3210* uart = &uart_device; + + /* read interrupt status and clear it */ + isr = UART_IIR(uart->hw_base); + isr = (isr >> 1) & 0x3; + + if (isr & 0x02) /* receive data available */ + { + /* Receive Data Available */ + while (UART_LSR(uart->hw_base) & UARTLSR_DR) + { + uart->rx_buffer[uart->save_index] = UART_DAT(uart->hw_base); + + level = rt_hw_interrupt_disable(); + uart->save_index ++; + if (uart->save_index >= RT_UART_RX_BUFFER_SIZE) + uart->save_index = 0; + rt_hw_interrupt_enable(level); + } + + /* invoke callback */ + if(uart->parent.rx_indicate != RT_NULL) + { + rt_size_t length; + if (uart->read_index > uart->save_index) + length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index; + else + length = uart->save_index - uart->read_index; + + uart->parent.rx_indicate(&uart->parent, length); + } + } + + return; +} + +static rt_err_t rt_uart_init (rt_device_t dev) +{ + rt_uint32_t baud_div; + struct rt_uart_soc3210 *uart = (struct rt_uart_soc3210*)dev; + + RT_ASSERT(uart != RT_NULL); + +#if 0 + /* init UART Hardware */ + UART_IER(uart->hw_base) = 0; /* clear interrupt */ + UART_FCR(uart->hw_base) = 0x60; /* reset UART Rx/Tx */ + + /* enable UART clock */ + /* set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ + UART_LCR(uart->hw_base) = 0x3; + + /* set baudrate */ + baud_div = DEV_CLK / 16 / UART_BAUDRATE; + UART_LCR(uart->hw_base) |= UARTLCR_DLAB; + + UART_MSB(uart->hw_base) = (baud_div >> 8) & 0xff; + UART_LSB(uart->hw_base) = baud_div & 0xff; + + UART_LCR(uart->hw_base) &= ~UARTLCR_DLAB; + + /* Enable UART unit, enable and clear FIFO */ + UART_FCR(uart->hw_base) = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS; +#endif + + return RT_EOK; +} + +static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag) +{ + struct rt_uart_soc3210 *uart = (struct rt_uart_soc3210*)dev; + + RT_ASSERT(uart != RT_NULL); + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* Enable the UART Interrupt */ + UART_IER(uart->hw_base) |= UARTIER_IRXE; + + /* install interrupt */ + rt_hw_interrupt_install(uart->irq, rt_uart_irqhandler, RT_NULL); + rt_hw_interrupt_umask(uart->irq); + } + return RT_EOK; +} + +static rt_err_t rt_uart_close(rt_device_t dev) +{ + struct rt_uart_soc3210 *uart = (struct rt_uart_soc3210*)dev; + + RT_ASSERT(uart != RT_NULL); + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* Disable the UART Interrupt */ + UART_IER(uart->hw_base) &= ~(UARTIER_IRXE); + } + + return RT_EOK; +} + +static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + rt_uint8_t* ptr; + struct rt_uart_soc3210 *uart = (struct rt_uart_soc3210*)dev; + + RT_ASSERT(uart != RT_NULL); + + /* point to buffer */ + ptr = (rt_uint8_t*) buffer; + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + while (size) + { + /* interrupt receive */ + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + if (uart->read_index != uart->save_index) + { + *ptr = uart->rx_buffer[uart->read_index]; + + uart->read_index ++; + if (uart->read_index >= RT_UART_RX_BUFFER_SIZE) + uart->read_index = 0; + } + else + { + /* no data in rx buffer */ + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + break; + } + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + ptr ++; + size --; + } + + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; + } + + return 0; +} + +static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + char *ptr; + struct rt_uart_soc3210 *uart = (struct rt_uart_soc3210*)dev; + + RT_ASSERT(uart != RT_NULL); + + ptr = (char*)buffer; + + if (dev->flag & RT_DEVICE_FLAG_STREAM) + { + /* stream mode */ + while (size) + { + if (*ptr == '\n') + { + /* FIFO status, contain valid data */ + while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE))); + /* write data */ + UART_DAT(uart->hw_base) = '\r'; + } + + /* FIFO status, contain valid data */ + while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE))); + /* write data */ + UART_DAT(uart->hw_base) = *ptr; + + ptr ++; + size --; + } + } + else + { + while ( size != 0 ) + { + /* FIFO status, contain valid data */ + while (!(UART_LSR(uart->hw_base) & (UARTLSR_TE | UARTLSR_TFE))); + + /* write data */ + UART_DAT(uart->hw_base) = *ptr; + + ptr++; + size--; + } + } + + return (rt_size_t) ptr - (rt_size_t) buffer; +} + +void rt_hw_uart_init(void) +{ + struct rt_uart_soc3210* uart; + + /* get uart device */ + uart = &uart_device; + + /* device initialization */ + uart->parent.type = RT_Device_Class_Char; + rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer)); + uart->read_index = uart->save_index = 0; +#if defined(RT_USING_UART1) + uart->hw_base = UART0_BASE; + uart->irq = IRQ_UART0; +#elif defined(RT_USING_UART2) + uart->hw_base = UART1_BASE; + uart->irq = IRQ_UART1; +#endif + + /* device interface */ + uart->parent.init = rt_uart_init; + uart->parent.open = rt_uart_open; + uart->parent.close = rt_uart_close; + uart->parent.read = rt_uart_read; + uart->parent.write = rt_uart_write; + uart->parent.control = RT_NULL; + uart->parent.private = RT_NULL; + + rt_device_register(&uart->parent, + "uart", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX); +} +#endif /* end of UART */ + +/*@}*/ diff --git a/bsp/dev3210/uart.h b/bsp/dev3210/uart.h new file mode 100644 index 0000000000000000000000000000000000000000..7b4663aa3d92aff506e26c3ef69b9657f994ae04 --- /dev/null +++ b/bsp/dev3210/uart.h @@ -0,0 +1,6 @@ +#ifndef __UART_H__ +#define __UART_H__ + +void rt_hw_uart_init(void); + +#endif diff --git a/examples/gui/demo_fnview.c b/examples/gui/demo_fnview.c index 36817228618c002b2fd3173e6351a1052dfd1b3c..cac944f8a434575b377edb986a2d86cd04c539ec 100644 --- a/examples/gui/demo_fnview.c +++ b/examples/gui/demo_fnview.c @@ -9,6 +9,7 @@ #include #include +#ifdef RT_USING_DFS /* 用于显示选择文件名的文本标签 */ static rtgui_label_t* label; /* 触发文件列表视图的按钮回调函数 */ @@ -86,3 +87,4 @@ rtgui_view_t* demo_fn_view(rtgui_workbench_t* workbench) return view; } +#endif diff --git a/examples/gui/demo_view_image.c b/examples/gui/demo_view_image.c index bb658377469208c41ad0532db7857d268f3a5535..55310ce02da3a95d5766e63ef06f201263ae37b6 100644 --- a/examples/gui/demo_view_image.c +++ b/examples/gui/demo_view_image.c @@ -12,6 +12,7 @@ static rtgui_image_t* image = RT_NULL; static rtgui_view_t* _view = RT_NULL; +#ifdef RT_USING_DFS /* 打开按钮的回调函数 */ static void open_btn_onbutton(rtgui_widget_t* widget, struct rtgui_event* event) { @@ -127,3 +128,4 @@ rtgui_view_t* demo_view_image(rtgui_workbench_t* workbench) return _view; } +#endif diff --git a/examples/gui/demo_workbench.c b/examples/gui/demo_workbench.c index 3595672925046a50f8388442444673913b5ddc78..30db0ef2922231bfdb05362bd48d06ad8c4e29b8 100644 --- a/examples/gui/demo_workbench.c +++ b/examples/gui/demo_workbench.c @@ -52,7 +52,7 @@ static void workbench_entry(void* parameter) /* 鍒濆鍖栧悇涓緥瀛愮殑瑙嗗浘 */ #if RT_VERSION == 4 - demo_view_benchmark(workbench); + // demo_view_benchmark(workbench); #endif demo_view_dc(workbench); @@ -81,13 +81,17 @@ static void workbench_entry(void* parameter) demo_view_listbox(workbench); demo_view_slider(workbench); demo_view_mywidget(workbench); +#ifdef RT_USING_DFS demo_view_image(workbench); +#endif #ifdef RT_USING_MODULE demo_view_module(workbench); #endif demo_listview_view(workbench); demo_listview_icon_view(workbench); +#ifdef RT_USING_DFS demo_fn_view(workbench); +#endif /* 鏄剧ず瑙嗗浘 */ demo_view_show(); diff --git a/libcpu/SConscript b/libcpu/SConscript index 19487d7f8122787f88f958e70ad28eb51ff81e64..bd854aa5f7ac1c59cdbe4f660a96dbfd046e2763 100644 --- a/libcpu/SConscript +++ b/libcpu/SConscript @@ -21,7 +21,7 @@ group = {} group['name'] = rtconfig.CPU.upper() group['src'] = File(src_local) group['CCFLAGS'] = '' -group['CPPPATH'] = [RTT_ROOT + '/libcpu/' + rtconfig.ARCH + '/' + rtconfig.CPU] +group['CPPPATH'] = [RTT_ROOT + '/libcpu/' + rtconfig.ARCH + '/' + rtconfig.CPU, RTT_ROOT + '/libcpu/' + rtconfig.ARCH + '/common'] group['CPPDEFINES'] = '' group['LINKFLAGS'] = '' diff --git a/libcpu/mips/common/exception.h b/libcpu/mips/common/exception.h index 07ffcd7a293b678f1125ddb8f21cdff8f0092faf..cd776a77cb3c1d66e0f7e0ec600a46c06c98f464 100644 --- a/libcpu/mips/common/exception.h +++ b/libcpu/mips/common/exception.h @@ -140,8 +140,6 @@ #define GDB_FR_SIZE ((((GDB_FR_CP0_PRID) + LONGSIZE) + (PTRSIZE-1)) & ~(PTRSIZE-1)) - - /* * This is the same as above, but for the high-level * part of the INT stub. @@ -161,7 +159,7 @@ typedef struct pt_regs_s typedef void (* exception_func_t)(pt_regs_t *regs); -extern exception_func_t sys_exception_handlers[33]; +extern exception_func_t sys_exception_handlers[]; exception_func_t rt_set_except_vector(int n, exception_func_t func); void install_default_execpt_handle(void); diff --git a/libcpu/mips/common/mips.inc b/libcpu/mips/common/mips.inc index 59388fd7f1f4df9e5c258de66ce7524cfa1406fe..c1e3e2d4185124cda361d99466da0bfdcc822fb4 100644 --- a/libcpu/mips/common/mips.inc +++ b/libcpu/mips/common/mips.inc @@ -14,15 +14,15 @@ #ifndef __MIPS_INC__ #define __MIPS_INC__ -#define zero $0 -#define at $1 -#define v0 $2 +#define zero $0 /* wired zero */ +// #define at $1 +#define v0 $2 /* return value */ #define v1 $3 -#define a0 $4 +#define a0 $4 /* argument registers */ #define a1 $5 #define a2 $6 #define a3 $7 -#define t0 $8 +#define t0 $8 /* caller saved */ #define t1 $9 #define t2 $10 #define t3 $11 @@ -30,7 +30,7 @@ #define t5 $13 #define t6 $14 #define t7 $15 -#define s0 $16 +#define s0 $16 /* callee saved */ #define s1 $17 #define s2 $18 #define s3 $19 @@ -38,14 +38,15 @@ #define s5 $21 #define s6 $22 #define s7 $23 -#define t8 $24 +#define t8 $24 /* caller saved */ #define t9 $25 -#define k0 $26 +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel scratch */ #define k1 $27 -#define gp $28 -#define sp $29 -#define fp $30 -#define ra $31 - +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* same like fp! */ +#define ra $31 /* return address */ #endif /* end of __MIPS_INC__ */ diff --git a/libcpu/mips/loongson/cache.c b/libcpu/mips/loongson/cache.c new file mode 100644 index 0000000000000000000000000000000000000000..bca01a61f40404bf2ea2f146334970aedad7d6e5 --- /dev/null +++ b/libcpu/mips/loongson/cache.c @@ -0,0 +1,188 @@ +#include "../common/mipsregs.h" +#include "cache.h" + +#define K0BASE 0x80000000 +#define PRID_3210I 0x4200 + +typedef struct cacheinfo_t { + unsigned int icache_size; + unsigned int dcache_size; + unsigned int icacheline_size; + unsigned int dcacheline_size; +} cacheinfo_t ; + +typedef struct cacheop_t { + void (*Clear_TagLo) (void); + void (*Invalidate_Icache) (unsigned int); + void (*Invalidate_Dcache_Fill) (unsigned int); + void (*Invalidate_Dcache_ClearTag) (unsigned int); + void (*Init_Cache)(void); +} cacheop_t ; + +static cacheop_t cacheop, *pcacheop; +static cacheinfo_t cacheinfo, *pcacheinfo; + +int identify_cpu (void) +{ + unsigned int cpu_id; + void invalidate_cache (void); + + pcacheop = &cacheop; + pcacheinfo = &cacheinfo; + + rt_kprintf("CPU configure: 0x%08x\n", read_c0_config()); + cpu_id = read_c0_prid(); + switch (cpu_id) + { + case PRID_3210I: + rt_kprintf ("CPU:SoC3210\n"); + pcacheop->Clear_TagLo = Clear_TagLo; + pcacheop->Invalidate_Icache = Invalidate_Icache_Gc3210I; + pcacheop->Invalidate_Dcache_Fill = Invalidate_Dcache_Fill_Gc3210I; + pcacheop->Invalidate_Dcache_ClearTag = Invalidate_Dcache_ClearTag_Gc3210I; + break; + default: + rt_kprintf ("Unknown CPU type, system halted!\n"); + while (1) {} + break; + } + + return 0; +} + +void probe_cache(void) +{ + unsigned int config = read_c0_config (); + unsigned int icache_size, ic_lsize; + unsigned int dcache_size, dc_lsize; + + icache_size = 1 << (12 + ((config >> 9) & 7)); + dcache_size = 1 << (12 + ((config >> 6) & 7)); + ic_lsize = 16 << ((config >> 5) & 1); + dc_lsize = 16 << ((config >> 4) & 1); + + rt_kprintf("DCache %2dkb, linesize %d bytes.\n", + dcache_size >> 10, dc_lsize); + rt_kprintf("ICache %2dkb, linesize %d bytes.\n", + icache_size >> 10, ic_lsize); + + pcacheinfo->icache_size = icache_size; + pcacheinfo->dcache_size = dcache_size; + pcacheinfo->icacheline_size = ic_lsize; + pcacheinfo->dcacheline_size = dc_lsize; + + return ; +} + +void invalidate_writeback_dcache_all(void) +{ + unsigned int start = K0BASE; + unsigned int end = (start + pcacheinfo->dcache_size); + + start = K0BASE; + while(start < end) { + Writeback_Invalidate_Dcache(start); //hit writeback invalidate + start += pcacheinfo->dcacheline_size; + } +} + +void invalidate_writeback_dcache(unsigned long addr, int size) +{ + unsigned long start, end; + + start = (addr +pcacheinfo->dcacheline_size -1) & (- pcacheinfo->dcacheline_size); + end = (end + size + pcacheinfo->dcacheline_size -1) & ( -pcacheinfo->dcacheline_size); + + while(start dcacheline_size; + } +} + + +void invalidate_icache_all(void) +{ + unsigned int start = K0BASE; + unsigned int end = (start + pcacheinfo->icache_size); + + while(start < end) { + pcacheop->Invalidate_Icache(start); + start += pcacheinfo->icacheline_size; + } +} + +void invalidate_dcache_all() +{ + unsigned int start = K0BASE; + unsigned int end = (start + pcacheinfo->dcache_size); + while(start icacheline_size; + } +} + +//with cache disabled +void init_dcache(void) +{ + unsigned int start = K0BASE; + unsigned int end = (start + pcacheinfo->dcache_size); + + while(start < end){ + pcacheop->Invalidate_Dcache_ClearTag(start); + start += pcacheinfo->dcacheline_size; + } + +} + +void rt_hw_cache_init(void) +{ + unsigned int start, end; + + /* 1. identify cpu and probe cache */ + identify_cpu(); + probe_cache(); + + start = K0BASE; + end = (start + pcacheinfo->icache_size); + + /* + * 2. clear CP0 taglo/taghi register; + */ + pcacheop->Clear_TagLo(); + + /* + * 3. invalidate instruction cache; + */ + while(start < end) { + pcacheop->Invalidate_Icache(start); //index invalidate icache + start += pcacheinfo->icacheline_size; + } + + /* + * 4. invalidate data cache; + */ + start = K0BASE; + end = (start + pcacheinfo->dcache_size); + while(start < end) { + pcacheop->Invalidate_Dcache_ClearTag(start); + start += pcacheinfo->dcacheline_size; + } + + start = K0BASE; + while(start < end) { + pcacheop->Invalidate_Dcache_Fill(start); //index invalidate dcache + start += pcacheinfo->dcacheline_size; + } + + start = K0BASE; + while(start < end) { + pcacheop->Invalidate_Dcache_ClearTag(start); + start += pcacheinfo->dcacheline_size; + } + + /* enable cache */ + enable_cpu_cache(); + rt_kprintf("enable cpu cache done\n"); + + return ; +} diff --git a/libcpu/mips/loongson/cache.h b/libcpu/mips/loongson/cache.h new file mode 100644 index 0000000000000000000000000000000000000000..fb4899a6b294095e364c41a5ff4d5fcaefe3e531 --- /dev/null +++ b/libcpu/mips/loongson/cache.h @@ -0,0 +1,47 @@ +#ifndef __CACHE_H__ +#define __CACHE_H__ + +/* + * Cache Operations + */ +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_I 0x04 +#define Index_Load_Tag_D 0x05 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_I 0x08 +#define Index_Store_Tag_D 0x09 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_D 0x0d +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_I 0x10 +#define Hit_Invalidate_D 0x11 +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Fill 0x14 +#define Hit_Writeback_Inv_D 0x15 +/* 0x16 is unused */ +#define Hit_Writeback_Inv_SD 0x17 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 +/* 0x1a is unused */ +#define Hit_Writeback_SD 0x1b +/* 0x1c is unused */ +/* 0x1e is unused */ +#define Hit_Set_Virtual_SI 0x1e +#define Hit_Set_Virtual_SD 0x1f + +extern void Clear_TagLo (void); + +extern void Invalidate_Icache_Gc3210I (unsigned int); +extern void Invalidate_Dcache_ClearTag_Gc3210I (unsigned int); +extern void Invalidate_Dcache_Fill_Gc3210I(unsigned int); +extern void Writeback_Invalidate_Dcache(unsigned int); + +void rt_hw_cache_init(void); + +#endif diff --git a/libcpu/mips/loongson/cache_gcc.S b/libcpu/mips/loongson/cache_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..00fd861eec3ea800e8ac3398a32e4ef0c7ed04bb --- /dev/null +++ b/libcpu/mips/loongson/cache_gcc.S @@ -0,0 +1,202 @@ +#include "../common/mipsregs.h" +#include "../common/mips.inc" +#include "../common/asm.h" +#include "cache.inc" + + .ent cache_init + .global cache_init + .set noreorder +cache_init: + move t1,ra +####part 2#### +cache_detect_4way: + mfc0 t4, CP0_CONFIG + andi t5, t4, 0x0e00 + srl t5, t5, 9 #ic + andi t6, t4, 0x01c0 + srl t6, t6, 6 #dc + addiu t8, $0, 1 + addiu t9, $0, 2 + #set dcache way + beq t6, $0, cache_d1way + addiu t7, $0, 1 #1 way + beq t6, t8, cache_d2way + addiu t7, $0, 2 #2 way + beq $0, $0, cache_d4way + addiu t7, $0, 4 #4 way +cache_d1way: + beq $0, $0, 1f + addiu t6, t6, 12 #1 way +cache_d2way: + beq $0, $0, 1f + addiu t6, t6, 11 #2 way +cache_d4way: + addiu t6, t6, 10 #4 way (10), 2 way(11), 1 way(12) +1: #set icache way + beq t5, $0, cache_i1way + addiu t3, $0, 1 #1 way + beq t5, t8, cache_i2way + addiu t3, $0, 2 #2 way + beq $0, $0, cache_i4way + addiu t3, $0, 4 #4 way +cache_i1way: + beq $0, $0, 1f + addiu t5, t5, 12 +cache_i2way: + beq $0, $0, 1f + addiu t5, t5, 11 +cache_i4way: + addiu t5, t5, 10 #4 way (10), 2 way(11), 1 way(12) + +1: addiu t4, $0, 1 + sllv t6, t4, t6 + sllv t5, t4, t5 +#if 0 + la t0, memvar + sw t7, 0x0(t0) #ways + sw t5, 0x4(t0) #icache size + sw t6, 0x8(t0) #dcache size +#endif +####part 3#### + .set mips3 + lui a0, 0x8000 + addu a1, $0, t5 + addu a2, $0, t6 +cache_init_d2way: +#a0=0x80000000, a1=icache_size, a2=dcache_size +#a3, v0 and v1 used as local registers + mtc0 $0, CP0_TAGHI + addu v0, $0, a0 + addu v1, a0, a2 +1: slt a3, v0, v1 + beq a3, $0, 1f + nop + mtc0 $0, CP0_TAGLO + beq t7, 1, 4f + cache Index_Store_Tag_D, 0x0(v0) # 1 way + beq t7, 2 ,4f + cache Index_Store_Tag_D, 0x1(v0) # 2 way + cache Index_Store_Tag_D, 0x2(v0) # 4 way + cache Index_Store_Tag_D, 0x3(v0) +4: beq $0, $0, 1b + addiu v0, v0, 0x20 +1: +cache_flush_i2way: + addu v0, $0, a0 + addu v1, a0, a1 +1: slt a3, v0, v1 + beq a3, $0, 1f + nop + beq t3, 1, 4f + cache Index_Invalidate_I, 0x0(v0) # 1 way + beq t3, 2, 4f + cache Index_Invalidate_I, 0x1(v0) # 2 way + cache Index_Invalidate_I, 0x2(v0) + cache Index_Invalidate_I, 0x3(v0) # 4 way +4: beq $0, $0, 1b + addiu v0, v0, 0x20 +1: +cache_flush_d2way: + addu v0, $0, a0 + addu v1, a0, a2 +1: slt a3, v0, v1 + beq a3, $0, 1f + nop + beq t7, 1, 4f + cache Index_Writeback_Inv_D, 0x0(v0) #1 way + beq t7, 2, 4f + cache Index_Writeback_Inv_D, 0x1(v0) # 2 way + cache Index_Writeback_Inv_D, 0x2(v0) + cache Index_Writeback_Inv_D, 0x3(v0) # 4 way +4: beq $0, $0, 1b + addiu v0, v0, 0x20 +1: +cache_init_finish: + jr t1 + nop + .set reorder + .end cache_init + +########################### +# Enable CPU cache # +########################### + +LEAF(enable_cpu_cache) + .set noreorder + mfc0 t0, CP0_CONFIG + nop + and t0, ~0x03 + or t0, 0x03 + mtc0 t0, CP0_CONFIG + nop + .set reorder + j ra +END (enable_cpu_cache) + +########################### +# disable CPU cache # +########################### + +LEAF(disable_cpu_cache) + .set noreorder + mfc0 t0, CP0_CONFIG + nop + and t0, ~0x03 + or t0, 0x2 + mtc0 t0, CP0_CONFIG + nop + .set reorder + j ra +END (disable_cpu_cache) + +/**********************************/ +/* Invalidate Instruction Cache */ +/**********************************/ +LEAF(Clear_TagLo) + .set noreorder + mtc0 zero, CP0_TAGLO + nop + .set reorder + j ra +END(Clear_TagLo) + + .set mips3 +/**********************************/ +/* Invalidate Instruction Cache */ +/**********************************/ +LEAF(Invalidate_Icache_Gc3210I) + .set noreorder + cache Index_Invalidate_I,0(a0) + cache Index_Invalidate_I,1(a0) + cache Index_Invalidate_I,2(a0) + cache Index_Invalidate_I,3(a0) + .set reorder + j ra +END(Invalidate_Icache_Gc3210I) + +/**********************************/ +/* Invalidate Data Cache */ +/**********************************/ +LEAF(Invalidate_Dcache_ClearTag_Gc3210I) + .set noreorder + cache Index_Store_Tag_D, 0(a0) # BDSLOT: clear tag + cache Index_Store_Tag_D, 1(a0) # BDSLOT: clear tag + .set reorder + j ra +END(Invalidate_Dcache_ClearTag_Gc3210I) + +LEAF(Invalidate_Dcache_Fill_Gc3210I) + .set noreorder + cache Index_Writeback_Inv_D, 0(a0) # BDSLOT: clear tag + cache Index_Writeback_Inv_D, 1(a0) # BDSLOT: clear tag + .set reorder + j ra +END(Invalidate_Dcache_Fill_Gc3210I) + +LEAF(Writeback_Invalidate_Dcache) + .set noreorder + cache Hit_Writeback_Inv_D, (a0) + .set reorder + j ra +END(Writeback_Invalidate_Dcache) + .set mips0 diff --git a/libcpu/mips/loongson/context_gcc.S b/libcpu/mips/loongson/context_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..1611f1cd86e2a2006ca398774668b6dc268411ca --- /dev/null +++ b/libcpu/mips/loongson/context_gcc.S @@ -0,0 +1,141 @@ +/* + * File : context_gcc.S + * Change Logs: + * Date Author Notes + * 2010-05-17 swkyer first version + * 2010-09-11 bernard port to Loongson SoC3210 + */ +#include "../common/mips.inc" +#include "../common/stackframe.h" +#include "soc3210.h" + + .section ".text", "ax" + .set noreorder + +/* + * rt_base_t rt_hw_interrupt_disable() + */ + .globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mfc0 v0, CP0_STATUS + and v1, v0, 0xfffffffe + mtc0 v1, CP0_STATUS + jr ra + nop + +/* + * void rt_hw_interrupt_enable(rt_base_t level) + */ + .globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + mtc0 a0, CP0_STATUS + jr ra + nop + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) + * a0 --> from + * a1 --> to + */ + .globl rt_hw_context_switch +rt_hw_context_switch: + mtc0 ra, CP0_EPC + SAVE_ALL + + sw sp, 0(a0) /* store sp in preempted tasks TCB */ + lw sp, 0(a1) /* get new task stack pointer */ + + RESTORE_ALL_AND_RET + +/* + * void rt_hw_context_switch_to(rt_uint32 to)/* + * a0 --> to + */ + .globl rt_hw_context_switch_to +rt_hw_context_switch_to: + lw sp, 0(a0) /* get new task stack pointer */ + + RESTORE_ALL_AND_RET + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/* + */ + .globl rt_thread_switch_interrput_flag + .globl rt_interrupt_from_thread + .globl rt_interrupt_to_thread + .globl rt_hw_context_switch_interrupt +rt_hw_context_switch_interrupt: + la t0, rt_thread_switch_interrput_flag + lw t1, 0(t0) + nop + bnez t1, _reswitch + nop + li t1, 0x01 /* set rt_thread_switch_interrput_flag to 1 */ + sw t1, 0(t0) + la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ + sw a0, 0(t0) +_reswitch: + la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */ + sw a1, 0(t0) + jr ra + nop + +/* + * void rt_hw_context_switch_interrupt_do(rt_base_t flag) + */ + .globl rt_interrupt_enter + .globl rt_interrupt_leave + .globl mips_irq_handle +mips_irq_handle: + SAVE_ALL + + mfc0 t0, CP0_CAUSE + and t1, t0, 0xff + bnez t1, spurious_interrupt /* check exception */ + nop + + /* let k0 keep the current context sp */ + move k0, sp + /* switch to kernel stack */ + li sp, SYSTEM_STACK + + jal rt_interrupt_enter + nop + jal rt_interrupt_dispatch + nop + jal rt_interrupt_leave + nop + + /* switch sp back to thread's context */ + move sp, k0 + + /* + * if rt_thread_switch_interrput_flag set, jump to + * rt_hw_context_switch_interrupt_do and don't return + */ + la k0, rt_thread_switch_interrput_flag + lw k1, 0(k0) + beqz k1, spurious_interrupt + nop + sw zero, 0(k0) /* clear flag */ + nop + + /* + * switch to the new thread + */ + la k0, rt_interrupt_from_thread + lw k1, 0(k0) + nop + sw sp, 0(k1) /* store sp in preempted tasks's TCB */ + + la k0, rt_interrupt_to_thread + lw k1, 0(k0) + nop + lw sp, 0(k1) /* get new task's stack pointer */ + j spurious_interrupt + nop + +spurious_interrupt: + RESTORE_ALL_AND_RET + + .set reorder diff --git a/libcpu/mips/loongson/cpu.c b/libcpu/mips/loongson/cpu.c new file mode 100644 index 0000000000000000000000000000000000000000..06673bcbb9e008901c2d91856f56b71bd0072248 --- /dev/null +++ b/libcpu/mips/loongson/cpu.c @@ -0,0 +1,49 @@ +/* + * File : cpu.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-07-09 Bernard first version + * 2010-09-11 Bernard add CPU reset implementation + */ +#include +#include + +/** + * @addtogroup Loogonson SoC3210 + */ +/*@{*/ + +/** + * this function will reset CPU + * + */ +void rt_hw_cpu_reset() +{ + /* open the watch-dog */ + WD_TIMER = 0x01; /* watch dog will be timeout after 1 tick */ + WD_CTRL |= 0x01; + + rt_kprintf("reboot system...\n"); + while (1); +} + +/** + * this function will shutdown CPU + * + */ +void rt_hw_cpu_shutdown() +{ + rt_kprintf("shutdown...\n"); + + while (1); +} + +/*@}*/ + diff --git a/libcpu/mips/loongson/exception.c b/libcpu/mips/loongson/exception.c new file mode 100644 index 0000000000000000000000000000000000000000..77d1414a29a79ab9f92ba39f16f63eb08a5d6396 --- /dev/null +++ b/libcpu/mips/loongson/exception.c @@ -0,0 +1,83 @@ +/* + * File : exception.c + * Change Logs: + * Date Author Notes + * 2010-05-17 swkyer first version + */ +#include +#include +#include "../common/exception.h" +#include "../common/mipsregs.h" + +/** + * @addtogroup SoC3210 + */ +/*@{*/ + +/** + * exception handle table + */ +#define RT_EXCEPTION_MAX 8 +exception_func_t sys_exception_handlers[RT_EXCEPTION_MAX]; + +/** + * setup the exception handle + */ +exception_func_t rt_set_except_vector(int n, exception_func_t func) +{ + exception_func_t old_handler = sys_exception_handlers[n]; + + if ((n == 0) || (n > RT_EXCEPTION_MAX) || (!func)) + { + return 0; + } + + sys_exception_handlers[n] = func; + + return old_handler; +} + +void tlb_refill_handler(void) +{ + rt_kprintf("tlb-miss happens, epc: 0x%08x\n", read_c0_epc()); + rt_hw_cpu_shutdown(); +} + +void cache_error_handler(void) +{ + rt_kprintf("cache exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_hw_cpu_shutdown(); +} + +static void unhandled_exception_handle(pt_regs_t *regs) +{ + rt_kprintf("exception happens, epc: 0x%08x, cause: 0x%08x\n", regs->cp0_epc, read_c0_cause()); +} + +void install_default_execpt_handle(void) +{ + rt_int32_t i; + + for (i=0; i> 8; + + for (index = RT_EXCEPTION_MAX; index > 0; index --) + { + if (cause & (1 << index)) + { + sys_exception_handlers[index](regs); + cause &= ~(1 << index); + } + } +} + +/*@}*/ diff --git a/libcpu/mips/loongson/interrupt.c b/libcpu/mips/loongson/interrupt.c new file mode 100644 index 0000000000000000000000000000000000000000..2d354269aa079aa2e1f485073f9ecd23be802ed9 --- /dev/null +++ b/libcpu/mips/loongson/interrupt.c @@ -0,0 +1,129 @@ +/* + * File : interrupt.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-10-15 Bernard first version + */ +#include +#include "soc3210.h" + +#define MAX_INTR 32 + +extern rt_uint32_t rt_interrupt_nest; +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrput_flag; + +static rt_isr_handler_t irq_handle_table[MAX_INTR]; +void rt_interrupt_dispatch(void *ptreg); +void rt_hw_timer_handler(); + +/** + * @addtogroup Loogonson SoC3210 + */ +/*@{*/ + +void rt_hw_interrupt_handler(int vector) +{ + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init() +{ + rt_int32_t index; + + for (index = 0; index < MAX_INTR; index ++) + { + irq_handle_table[index] = (rt_isr_handler_t)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_interrput_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(int vector) +{ + /* mask interrupt */ + INT_EN &= ~(1 << vector); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + INT_EN |= (1 << vector); +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +{ + if (vector >= 0 && vector < MAX_INTR) + { + if (old_handler != RT_NULL) + *old_handler = irq_handle_table[vector]; + if (new_handler != RT_NULL) + irq_handle_table[vector] = (rt_isr_handler_t)new_handler; + } +} + +void rt_interrupt_dispatch(void *ptreg) +{ + int i; + rt_isr_handler_t irq_func; + static rt_uint32_t status = 0; + rt_uint32_t c0_status; + + /* check os timer */ + c0_status = read_c0_status(); + if (c0_status & 0x8000) + { + rt_hw_timer_handler(); + } + + if (c0_status & 0x0400) + { + /* the hardware interrupt */ + status |= INT_ISR; + if (!status) return; + + for (i = MAX_INTR; i > 0; --i) + { + if ((status & (1< +#include "../common/mipsregs.h" +#include "../common/mipscfg.h" + +mips32_core_cfg_t g_mips_core = +{ + 16, /* icache_line_size */ + 256, /* icache_lines_per_way */ + 4, /* icache_ways */ + 16, /* dcache_line_size */ + 256, /* dcache_lines_per_way */ + 4, /* dcache_ways */ + 16, /* max_tlb_entries */ +}; + +static rt_uint16_t m_pow(rt_uint16_t b, rt_uint16_t n) +{ + rt_uint16_t rets = 1; + + while (n--) + rets *= b; + + return rets; +} + +static rt_uint16_t m_log2(rt_uint16_t b) +{ + rt_uint16_t rets = 0; + + while (b != 1) + { + b /= 2; + rets++; + } + + return rets; +} + +/** + * read core attribute + */ +void mips32_cfg_init(void) +{ + rt_uint16_t val; + rt_uint32_t cp0_config1; + + cp0_config1 = read_c0_config(); + if (cp0_config1 & 0x80000000) + { + cp0_config1 = read_c0_config1(); + + val = (cp0_config1 & (7<<22))>>22; + g_mips_core.icache_lines_per_way = 64 * m_pow(2, val); + val = (cp0_config1 & (7<<19))>>19; + g_mips_core.icache_line_size = 2 * m_pow(2, val); + val = (cp0_config1 & (7<<16))>>16; + g_mips_core.icache_ways = val + 1; + + val = (cp0_config1 & (7<<13))>>13; + g_mips_core.dcache_lines_per_way = 64 * m_pow(2, val); + val = (cp0_config1 & (7<<10))>>10; + g_mips_core.dcache_line_size = 2 * m_pow(2, val); + val = (cp0_config1 & (7<<7))>>7; + g_mips_core.dcache_ways = val + 1; + + val = (cp0_config1 & (0x3F<<25))>>25; + g_mips_core.max_tlb_entries = val + 1; + } +} diff --git a/libcpu/mips/loongson/soc3210.h b/libcpu/mips/loongson/soc3210.h new file mode 100644 index 0000000000000000000000000000000000000000..fe394ce0125e4eb1983214c21224894e09e2d3be --- /dev/null +++ b/libcpu/mips/loongson/soc3210.h @@ -0,0 +1,172 @@ +#ifndef __SOC3210_H__ +#define __SOC3210_H__ + +#include "../common/mipsregs.h" + +/* registers */ +#define __REG8(addr) *((volatile unsigned char *)(addr)) +#define __REG16(addr) *((volatile unsigned short *)(addr)) +#define __REG32(addr) *((volatile unsigned int *)(addr)) + +#define EMI_BASE 0xBF000000 +#define NN_BASE 0xBF000040 +#define LCD_BASE 0xBF001000 +#define HSB_MISC_BASE 0xBF003200 +#define SPI_BASE 0xBF004000 +#define PS2_BASE 0xBF004040 +#define UART0_BASE 0xBF004080 +#define UART1_BASE 0xBF004090 +#define I2C_BASE 0xBF0040D0 +#define LPB_MISC_BASE 0xBF004100 +#define AC97_BASE 0xBF004200 +#define AC97_DMA_BASE 0xBF004280 +#define CAN1_BASE 0xBF004300 +#define CAN0_BASE 0xBF004400 +#define MAC0_BASE 0xBF005200 +#define MAC1_BASE 0xBF005300 + +/* LCD registers */ +#define LCD_CTRL __REG32(LCD_BASE + 0x000) +#define LCD_STAT __REG32(LCD_BASE + 0x004) +#define LCD_HTIM __REG32(LCD_BASE + 0x008) +#define LCD_VTIM __REG32(LCD_BASE + 0x00C) +#define LCD_HVLEN __REG32(LCD_BASE + 0x010) +#define LCD_VBARA __REG32(LCD_BASE + 0x014) +#define LCD_VBARB __REG32(LCD_BASE + 0x018) +#define LCD_PCLT __REG32(LCD_BASE + 0x800) + +/* HSB misc registers */ +#define HSB_MISC_REG __REG32(HSB_MISC_BASE + 0x00) +#define INT_EDGE __REG32(HSB_MISC_BASE + 0x04) +#define INT_STEER __REG32(HSB_MISC_BASE + 0x08) +#define INT_POL __REG32(HSB_MISC_BASE + 0x0C) +#define INT_SET __REG32(HSB_MISC_BASE + 0x10) +#define INT_CLR __REG32(HSB_MISC_BASE + 0x14) +#define INT_EN __REG32(HSB_MISC_BASE + 0x18) +#define INT_ISR __REG32(HSB_MISC_BASE + 0x1C) +#define GPIO_OE_60_29 __REG32(HSB_MISC_BASE + 0x20) +#define GPIO_I_60_29 __REG32(HSB_MISC_BASE + 0x24) +#define GPIO_O_60_29 __REG32(HSB_MISC_BASE + 0x28) +#define HSB_ARB_CFG __REG32(HSB_MISC_BASE + 0x2C) +#define WD_TIMER __REG32(HSB_MISC_BASE + 0x30) +#define WD_CTRL __REG32(HSB_MISC_BASE + 0x34) + +/* SPI registers */ +#define SPI_SPCR __REG8(SPI_BASE + 0x00) +#define SPI_SPSR __REG8(SPI_BASE + 0x01) +#define SPI_TX_FIFO __REG8(SPI_BASE + 0x02) +#define SPI_SPER __REG8(SPI_BASE + 0x03) + +/* PS/2 registers */ +#define PS2_RIBUF __REG8(PS2_BASE + 0x00) +#define PS2_WOBUF __REG8(PS2_BASE + 0x00) +#define PS2_RSR __REG8(PS2_BASE + 0x04) +#define PS2_WSC __REG8(PS2_BASE + 0x04) +#define PS2_DLL __REG8(PS2_BASE + 0x08) +#define PS2_DLH __REG8(PS2_BASE + 0x09) +#define PS2_DL_KBD __REG8(PS2_BASE + 0x0A) +#define PS2_DL_AUX __REG8(PS2_BASE + 0x0B) + +/* UART registers */ +#define UART_DAT(base) __REG8(base + 0x00) +#define UART_IER(base) __REG8(base + 0x01) +#define UART_IIR(base) __REG8(base + 0x02) +#define UART_FCR(base) __REG8(base + 0x02) +#define UART_LCR(base) __REG8(base + 0x03) +#define UART_MCR(base) __REG8(base + 0x04) +#define UART_LSR(base) __REG8(base + 0x05) +#define UART_MSR(base) __REG8(base + 0x06) + +#define UART_LSB(base) __REG8(base + 0x00) +#define UART_MSB(base) __REG8(base + 0x01) + +/* UART0 registers */ +#define UART0_DAT __REG8(UART0_BASE + 0x00) +#define UART0_IER __REG8(UART0_BASE + 0x01) +#define UART0_IIR __REG8(UART0_BASE + 0x02) +#define UART0_FCR __REG8(UART0_BASE + 0x02) +#define UART0_LCR __REG8(UART0_BASE + 0x03) +#define UART0_MCR __REG8(UART0_BASE + 0x04) +#define UART0_LSR __REG8(UART0_BASE + 0x05) +#define UART0_MSR __REG8(UART0_BASE + 0x06) + +#define UART0_LSB __REG8(UART0_BASE + 0x00) +#define UART0_MSB __REG8(UART0_BASE + 0x01) + +/* UART1 registers */ +#define UART1_DAT __REG8(UART1_BASE + 0x00) +#define UART1_IER __REG8(UART1_BASE + 0x01) +#define UART1_IIR __REG8(UART1_BASE + 0x02) +#define UART1_FCR __REG8(UART1_BASE + 0x02) +#define UART1_LCR __REG8(UART1_BASE + 0x03) +#define UART1_MCR __REG8(UART1_BASE + 0x04) +#define UART1_LSR __REG8(UART1_BASE + 0x05) +#define UART1_MSR __REG8(UART1_BASE + 0x06) + +#define UART1_LSB __REG8(UART1_BASE + 0x00) +#define UART1_MSB __REG8(UART1_BASE + 0x01) + +/* LPB misc registers */ +#define GPIO_OE_7_0 __REG8(LPB_MISC_BASE + 0x00) +#define GPIO_OE_15_8 __REG8(LPB_MISC_BASE + 0x01) +#define GPIO_OE_23_16 __REG8(LPB_MISC_BASE + 0x02) +#define GPIO_OE_28_24 __REG8(LPB_MISC_BASE + 0x03) +#define GPIO_I_7_0 __REG8(LPB_MISC_BASE + 0x10) +#define GPIO_I_15_8 __REG8(LPB_MISC_BASE + 0x11) +#define GPIO_I_23_16 __REG8(LPB_MISC_BASE + 0x12) +#define GPIO_I_28_24 __REG8(LPB_MISC_BASE + 0x13) +#define GPIO_O_7_0 __REG8(LPB_MISC_BASE + 0x20) +#define GPIO_O_15_8 __REG8(LPB_MISC_BASE + 0x21) +#define GPIO_O_23_16 __REG8(LPB_MISC_BASE + 0x22) +#define GPIO_O_28_24 __REG8(LPB_MISC_BASE + 0x23) +#define LPB_MISC_CFG __REG8(LPB_MISC_BASE + 0x40) + +/* MAC0 registers */ +#define MAC0_BUS_MODE __REG32(MAC0_BASE + 0x00) +#define MAC0_TX_POLL_REQ __REG32(MAC0_BASE + 0x08) +#define MAC0_RX_POLL_REQ __REG32(MAC0_BASE + 0x10) +#define MAC0_RX_LIST_BASE_ADDR __REG32(MAC0_BASE + 0x18) +#define MAC0_TX_LIST_BASE_ADDR __REG32(MAC0_BASE + 0x20) +#define MAC0_STATUS __REG32(MAC0_BASE + 0x28) +#define MAC0_OP_MODE __REG32(MAC0_BASE + 0x30) +#define MAC0_INTERRUPT_EN __REG32(MAC0_BASE + 0x38) +#define MAC0_MISSED_FRAME_STATISTIC __REG32(MAC0_BASE + 0x40) +#define MAC0_SMI_EEPROM_CTL __REG32(MAC0_BASE + 0x48) +#define MAC0_BYTE_ALIGN __REG32(MAC0_BASE + 0x50) +#define MAC0_GPT_IM_CTL __REG32(MAC0_BASE + 0x58) + +/* MAC1 registers */ +#define MAC1_BUS_MODE __REG32(MAC1_BASE + 0x00) +#define MAC1_TX_POLL_REQ __REG32(MAC1_BASE + 0x08) +#define MAC1_RX_POLL_REQ __REG32(MAC1_BASE + 0x10) +#define MAC1_RX_LIST_BASE_ADDR __REG32(MAC1_BASE + 0x18) +#define MAC1_TX_LIST_BASE_ADDR __REG32(MAC1_BASE + 0x20) +#define MAC1_STATUS __REG32(MAC1_BASE + 0x28) +#define MAC1_OP_MODE __REG32(MAC1_BASE + 0x30) +#define MAC1_INTERRUPT_EN __REG32(MAC1_BASE + 0x38) +#define MAC1_MISSED_FRAME_STATISTIC __REG32(MAC1_BASE + 0x40) +#define MAC1_SMI_EEPROM_CTL __REG32(MAC1_BASE + 0x48) +#define MAC1_BYTE_ALIGN __REG32(MAC1_BASE + 0x50) +#define MAC1_GPT_IM_CTL __REG32(MAC1_BASE + 0x58) + +/* Peripheral Interrupt Number */ +#define IRQ_LCD 0 +#define IRQ_MAC1 1 +#define IRQ_MAC2 2 +#define IRQ_AC97 3 +#define IRQ_SPI 8 +#define IRQ_KEY 9 +#define IRQ_MOUSE 10 +#define IRQ_UART0 11 +#define IRQ_UART1 12 +#define IRQ_I2C 13 +#define IRQ_CAN0 14 +#define IRQ_CAN1 15 +#define IRQ_GPIO15 20 +#define IRQ_GPIO14 21 +#define IRQ_GPIO13 22 +#define IRQ_GPIO12 23 + +#define SYSTEM_STACK 0x80003fe8 /* the kernel system stack address */ + +#endif diff --git a/libcpu/mips/loongson/stack.c b/libcpu/mips/loongson/stack.c new file mode 100644 index 0000000000000000000000000000000000000000..187845da586c8c5a135753e97855e909fb74c63c --- /dev/null +++ b/libcpu/mips/loongson/stack.c @@ -0,0 +1,94 @@ +/* + * File : stack.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2010-05-17 swkyer first version + * 2010-07-07 Bernard porting to Jz47xx + */ +#include + +/** + * @addtogroup Loogonson SoC3210 + */ +/*@{*/ + +extern rt_uint32_t cp0_get_cause(void); +extern rt_uint32_t cp0_get_status(void); +extern rt_uint32_t cp0_get_hi(void); +extern rt_uint32_t cp0_get_lo(void); + +/** + * 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; + static rt_uint32_t g_sr = 0; + + if (g_sr == 0) + { + g_sr = cp0_get_status(); + g_sr &= 0xfffffffe; + g_sr |= 0x8401; + } + + /** Start at stack top */ + stk = (rt_uint32_t *)stack_addr; + *(stk) = (rt_uint32_t) tentry; /* pc: Entry Point */ + *(--stk) = (rt_uint32_t) 0xeeee; /* c0_cause */ + *(--stk) = (rt_uint32_t) 0xffff; /* c0_badvaddr */ + *(--stk) = (rt_uint32_t) cp0_get_lo(); /* lo */ + *(--stk) = (rt_uint32_t) cp0_get_hi(); /* hi */ + *(--stk) = (rt_uint32_t) g_sr; /* C0_SR: HW2 = En, IE = En */ + *(--stk) = (rt_uint32_t) texit; /* ra */ + *(--stk) = (rt_uint32_t) 0x0000001e; /* s8 */ + *(--stk) = (rt_uint32_t) stack_addr; /* sp */ + *(--stk) = (rt_uint32_t) 0x0000001c; /* gp */ + *(--stk) = (rt_uint32_t) 0x0000001b; /* k1 */ + *(--stk) = (rt_uint32_t) 0x0000001a; /* k0 */ + *(--stk) = (rt_uint32_t) 0x00000019; /* t9 */ + *(--stk) = (rt_uint32_t) 0x00000018; /* t8 */ + *(--stk) = (rt_uint32_t) 0x00000017; /* s7 */ + *(--stk) = (rt_uint32_t) 0x00000016; /* s6 */ + *(--stk) = (rt_uint32_t) 0x00000015; /* s5 */ + *(--stk) = (rt_uint32_t) 0x00000014; /* s4 */ + *(--stk) = (rt_uint32_t) 0x00000013; /* s3 */ + *(--stk) = (rt_uint32_t) 0x00000012; /* s2 */ + *(--stk) = (rt_uint32_t) 0x00000011; /* s1 */ + *(--stk) = (rt_uint32_t) 0x00000010; /* s0 */ + *(--stk) = (rt_uint32_t) 0x0000000f; /* t7 */ + *(--stk) = (rt_uint32_t) 0x0000000e; /* t6 */ + *(--stk) = (rt_uint32_t) 0x0000000d; /* t5 */ + *(--stk) = (rt_uint32_t) 0x0000000c; /* t4 */ + *(--stk) = (rt_uint32_t) 0x0000000b; /* t3 */ + *(--stk) = (rt_uint32_t) 0x0000000a; /* t2 */ + *(--stk) = (rt_uint32_t) 0x00000009; /* t1 */ + *(--stk) = (rt_uint32_t) 0x00000008; /* t0 */ + *(--stk) = (rt_uint32_t) 0x00000007; /* a3 */ + *(--stk) = (rt_uint32_t) 0x00000006; /* a2 */ + *(--stk) = (rt_uint32_t) 0x00000005; /* a1 */ + *(--stk) = (rt_uint32_t) parameter; /* a0 */ + *(--stk) = (rt_uint32_t) 0x00000003; /* v1 */ + *(--stk) = (rt_uint32_t) 0x00000002; /* v0 */ + *(--stk) = (rt_uint32_t) 0x00000001; /* at */ + *(--stk) = (rt_uint32_t) 0x00000000; /* zero */ + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/libcpu/mips/loongson/start_gcc.S b/libcpu/mips/loongson/start_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..42e19b5d99a276e78a64b15a50383f3d7132263d --- /dev/null +++ b/libcpu/mips/loongson/start_gcc.S @@ -0,0 +1,132 @@ +/* + * File : start_gcc.S + * Change Logs: + * Date Author Notes + * 2010-05-17 swkyer first version + * 2010-09-04 bernard porting to Jz47xx + */ + +#include "../common/mips.inc" +#include "../common/stackframe.h" +#include "soc3210.h" + + .section ".start", "ax" + .set noreorder + + /* the program entry */ + .globl _start +_start: + .set noreorder + la ra, _start + + /* disable interrupt */ + mfc0 t0, CP0_STATUS + and t0, 0xfffffffe # By default it will be disabled. + mtc0 t0, CP0_STATUS # Set CPU to disable interrupt. + nop + + /* disable cache */ + mfc0 t0, CP0_CONFIG + and t0, 0xfffffff8 + or t0, 0x2 # disable,!default value is not it! + mtc0 t0, CP0_CONFIG # Set CPU to disable cache. + nop + + /* setup stack pointer */ + li sp, SYSTEM_STACK + la gp, _gp + + /* copy IRAM section */ + la t0, _iramcopy + la t1, _iramstart + la t2, _iramend +_iram_loop: + lw t3, 0(t0) + sw t3, 0(t1) + addiu t1, 4 + bne t1, t2, _iram_loop + addiu t0, 4 + + /* clear bss */ + la t0, __bss_start + la t1, __bss_end +_clr_bss_loop: + sw zero, 0(t0) + bne t0, t1, _clr_bss_loop + addiu t0, t0, 4 + + /* jump to RT-Thread RTOS */ + jal rtthread_startup + nop + + /* restart, never die */ + j _start + nop + .set reorder + + .globl cp0_get_cause +cp0_get_cause: + mfc0 v0, CP0_CAUSE + jr ra + nop + + .globl cp0_get_status +cp0_get_status: + mfc0 v0, CP0_STATUS + jr ra + nop + + .globl cp0_get_hi +cp0_get_hi: + mfhi v0 + jr ra + nop + + .globl cp0_get_lo +cp0_get_lo: + mflo v0 + jr ra + nop + + .extern tlb_refill_handler + .extern cache_error_handler + + /* Exception Handler */ + /* 0x0 - TLB refill handler */ + .section .vectors.1, "ax", %progbits + j tlb_refill_handler + nop + + /* 0x100 - Cache error handler */ + .section .vectors.2, "ax", %progbits + j cache_error_handler + nop + + /* 0x180 - Exception/Interrupt handler */ + .section .vectors.3, "ax", %progbits + j _general_exception_handler + nop + + /* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */ + .section .vectors.4, "ax", %progbits + j _irq_handler + nop + + .section .vectors, "ax", %progbits + .extern mips_irq_handle + + /* general exception handler */ +_general_exception_handler: + .set noreorder + la k0, mips_irq_handle + jr k0 + nop + .set reorder + + /* interrupt handler */ +_irq_handler: + .set noreorder + la k0, mips_irq_handle + jr k0 + nop + .set reorder