summaryrefslogtreecommitdiff
path: root/bsp/ls1cdev/drivers/board.c
blob: a7100a04c4398a24742ba1e21bc10754ebc0331e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * File      : board.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006-2012, 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
 * 2011-08-08     lgnq            modified for Loongson LS1B
 * 2015-07-06     chinesebear  modified for Loongson LS1C
 */

#include <rtthread.h>
#include <rthw.h>

#include "board.h"
#include "drv_uart.h"
#include "ls1c.h"

#define A_K0BASE		0x80000000

extern unsigned char __bss_end;


extern void tlb_refill_exception(void);
extern void general_exception(void);
extern void irq_exception(void);
extern void rt_hw_cache_init(void);
extern void invalidate_writeback_dcache_all(void);
extern void invalidate_icache_all(void);


/**
 * @addtogroup Loongson LS1B
 */
 
/*@{*/

/**
 * This is the timer interrupt service routine.
 */
void rt_hw_timer_handler(void)
{
	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(void)
{
	write_c0_compare(CPU_HZ/2/RT_TICK_PER_SECOND);
	write_c0_count(0);
}


/**
 * init hardware FPU
 */
void rt_hw_fpu_init(void)
{
    rt_uint32_t c0_status = 0;
    rt_uint32_t c1_status = 0;

    // 使能协处理器1--FPU
    c0_status = read_c0_status();
    c0_status |= (ST0_CU1 | ST0_FR);
    write_c0_status(c0_status);

    // 配置FPU
    c1_status = read_c1_status();
    c1_status |= (FPU_CSR_FS | FPU_CSR_FO | FPU_CSR_FN);    // set FS, FO, FN
    c1_status &= ~(FPU_CSR_ALL_E);                          // disable exception
    c1_status = (c1_status & (~FPU_CSR_RM)) | FPU_CSR_RN;   // set RN
    write_c1_status(c1_status);

    return ;
}


/**
 * This function will initial sam7s64 board.
 */
void rt_hw_board_init(void)
{
	/* init cache */
	rt_hw_cache_init();
	
	/* init hardware interrupt */
	rt_hw_interrupt_init();

	/* clear bev */
	write_c0_status(read_c0_status()&(~(1<<22)));

	/* copy vector */
	rt_memcpy((void *)A_K0BASE, tlb_refill_exception, 0x80);
	rt_memcpy((void *)(A_K0BASE + 0x180), general_exception, 0x80);
	rt_memcpy((void *)(A_K0BASE + 0x200), irq_exception, 0x80);

	invalidate_writeback_dcache_all();
	invalidate_icache_all();
	
#ifdef RT_USING_HEAP
	rt_system_heap_init((void*)&__bss_end, (void*)RT_HW_HEAP_END);
#endif

#ifdef RT_USING_SERIAL
	/* init hardware UART device */
	rt_hw_uart_init();
#endif

#ifdef RT_USING_CONSOLE
	/* set console device */
	rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
    /* init operating system timer */
    rt_hw_timer_init();

#ifdef RT_USING_FPU
    /* init hardware fpu */
    rt_hw_fpu_init();
#endif

#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

    rt_kprintf("current sr: 0x%08x\n", read_c0_status());
}

/*@}*/