rt-thread/libcpu/mips/loongson_1c/start_gcc.S

531 lines
16 KiB
ArmAsm
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
* 2010-09-04 bernard porting to JZ47xx
* 2019-07-19 Zhou Yanjie clean up code
*/
#ifndef __ASSEMBLY__
#define __ASSEMBLY__
#endif
#include "../common/mips_def.h"
#include "../common/stackframe.h"
#include "sdram_cfg.h"
#include "cache.h"
#include "rtconfig.h"
#define SR_BOOT_EXC_VEC 0x00400000
/* config pll div for cpu and sdram */
#define PLL_MULT (0x54) // 24MhzPLL=504Mhz
#define SDRAM_DIV (0) // SDRAMCPU2
#define CPU_DIV (2) // CPUPLL2
//
#define MEM_SIZE (0x02000000) // 32MByte
/* Delay macro */
#define DELAY(count) \
li v0, count; \
99: \
bnez v0, 99b;\
addiu v0, -1
#define msize s2
#define output_en s3
.section ".start", "ax"
.set noreorder
/* the program entry */
.globl _start
_start:
.set noreorder
la ra, _start
#if !defined(RT_USING_SELF_BOOT)
/* 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
/* 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
#else
mtc0 zero, CP0_STATUS // cp0 status
mtc0 zero, CP0_CAUSE // cp0 cause
/*
ROM(0xbfc00000)
cp0 statusBEV1使CPUROM(kseg1)
*/
li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location */
mtc0 t0, CP0_STATUS
/* setup stack pointer */
li sp, SYSTEM_STACK
la gp, _gp
/* initialize spi */
li t0, 0xbfe80000 //0xbfe80000SPI0
li t1, 0x17 // div 4, fast_read + burst_en + memory_en double I/O SPI flash
sb t1, 0x4(t0) // sfc_param
li t1, 0x05
sb t1, 0x6(t0) // sfc_timing
/* sdram cs1使ejtag_sel gpio_0()sdram
sw2使ejtagpmon */
li a0, 0xbfd011c0
lw a1, 0x40(a0)
ori a1, 0x01
sw a1, 0x40(a0)
bal locate
nop
/* restart, never die */
j _start
nop
#endif
.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
#if defined(RT_USING_SELF_BOOT)
/****************************************LOCATE*********************************/
/*
* We get here from executing a bal to get the PC value of the current execute
* location into ra. Check to see if we run from ROM or if this is ramloaded.
* raraROMRAM
* ROMRAM
* RAMCPU
* ROMra"bal locate"80xBFC00000
* RAMra0x80xxxxxx
*/
locate:
// la s0, uncached
// subu s0, ra, s0
/*
* start.sROM0xBFC00000
* 0x80100000
* s0rastart
* s0 link versus load offset, used to relocate absolute adresses
* s0ROMRAM
*/
la s0, _start // s0 = _start start0x80010000
subu s0, ra, s0 // s0 = ra - s0raROM0xBFC00000
and s0, 0xffff0000 // s0 = s0 & 0xffff0000
/*
* cp0statuscause
* (RAM)cp0statuscause
* ROM
*/
li t0, SR_BOOT_EXC_VEC
mtc0 t0, CP0_CONFIG // cp0status
mtc0 zero, CP0_CAUSE // cp0cause
.set noreorder
li t0, 0xbfe78030 // 0xbfe78030PLL/SDRAM
/* 设置PLL倍频 及SDRAM分频 */
li t2, (0x80000008 | (PLL_MULT << 8) | (0x3 << 2) | SDRAM_DIV)
/* 设置CPU分频 */
li t3, (0x00008003 | (CPU_DIV << 8))
/* 注意:首先需要把分频使能位清零 */
li t1, 0x2
sw t1, 0x4(t0) // CPU_DIV_VALIDdisable
sw t2, 0x0(t0) // START_FREQ
sw t3, 0x4(t0) // CLK_DIV_PARAM
DELAY(2000)
/* 使gpio(使lcd i2c spi ac97
gpio便使gpio
LDE*/
/* disable all gpio */
li a0,0xbfd00000
sw zero,0x10c0(a0) /* disable gpio 0-31 */
sw zero,0x10c4(a0) /* disable gpio 32-63 */
sw zero,0x10c8(a0) /* disable gpio 64-95 */
sw zero,0x10cc(a0)
li t0, 0xffffffff
sw t0, 0x10d0(a0)
sw t0, 0x10d4(a0)
sw t0, 0x10d8(a0)
sw t0, 0x10dc(a0)
sw t0, 0x10f0(a0)
sw t0, 0x10f4(a0)
sw t0, 0x10f8(a0)
sw t0, 0x10fc(a0)
/* lcd soft_reset and panel config & timing */
#ifdef DC_FB0
/* li a0, 0xbc301240
li a1, 0x00100103
sw a1, 0x0(a0)
li a1, 0x00000103
sw a1, 0x0(a0) //soft_reset
li a1, 0x00100103
sw a1, 0x0(a0)
li a1, 0x80001111
sw a1, 0x180(a0) //panel config
li a1, 0x33333333
sw a1, 0x1a0(a0)*/
#endif
li output_en, 0x1
#ifdef FAST_STARTUP
li a1, 0x03000000
sw a1, 0x10c4(a0)
sw a1, 0x10d4(a0)
lw a2, 0x10e4(a0)
and a2, a1
beq a2, a1, get_pin_val_finish
nop
li output_en, 0x1
get_pin_val_finish:
#endif
/* Initializing. Standby... */
/*
* s0ROM
* s00ROM0RAM
* cache
*/
bnez s0, 1f // s00ROM1
nop
li a0, 128
jal rtthread_startup // main
nop
1:
/* use only 8wins */
#define CPU_WIN_BASE 0xbfd00000
#define CPU_WIN_MASK 0xbfd00040
#define CPU_WIN_MMAP 0xbfd00080
#define set_cpu_window(id, base, mask, mmap) \
li t0, CPU_WIN_BASE ; \
sw $0, 0x80+id*8(t0) ; \
li t1, base ; \
sw t1, 0x00+id*8(t0) ; \
sw $0, 0x04+id*8(t0) ; \
li t1, mask ; \
sw t1, 0x40+id*8(t0) ; \
sw $0, 0x44+id*8(t0) ; \
li t1, mmap ; \
sw t1, 0x80+id*8(t0) ; \
sw $0, 0x84+id*8(t0)
/* fixup cpu window */
cpu_win_fixup:
//
// hit = (paddr & mask) == (mmap & mask)
// mapped_addr = paddr &~mask | mmap & mask
//
// mmap[7] -> enable
// mmap[5] -> block trans enable
// mmap[4] -> cachable
// mmap[1:0] -> destination
//
// NOTE: the address windows has priority, win0 > win1 > ... > win7
/* set_cpu_window(0, 0x1c280000, 0xfff80000, 0x1c280083) // camera 512K
set_cpu_window(1, 0x1c300000, 0xfff00000, 0x1c300081) // dc 1M
set_cpu_window(2, 0x1fe10000, 0xffffe000, 0x1fe10082) // gmac0 8K
set_cpu_window(3, 0x1fe10000, 0xffff0000, 0x1fe100d0) // gmac0 64K
set_cpu_window(4, 0x1f000000, 0xff000000, 0x1f000082) // AXIMUX 16M
set_cpu_window(5, 0x00000000, 0x00000000, 0x000000f0) // ddr 0
set_cpu_window(6, 0x00000000, 0x00000000, 0x000000f0) // ddr 0
set_cpu_window(7, 0x00000000, 0x00000000, 0x000000f0) // ddr 0*/
/* set_cpu_window(0, 0x1c280000, 0xfff80000, 0x1c2800d3) // camera
// set_cpu_window(1, 0x1fc00000, 0xfff00000, 0x1fc000f2) //
set_cpu_window(2, 0x1c300000, 0xfff00000, 0x1c3000d1) // dc 1M
// set_cpu_window(3, 0x1f000000, 0xff000000, 0x1f0000d2) //
set_cpu_window(4, 0x00000000, 0x00000000, 0x000000f0)
set_cpu_window(5, 0x00000000, 0x00000000, 0x000000f0)
set_cpu_window(6, 0x00000000, 0x00000000, 0x000000f0) // ddr 0
set_cpu_window(7, 0x00000000, 0x00000000, 0x000000f0) // ddr 0*/
// after this fixup, the kernel code should be compiled with
// uncached instruction fetch patch
/* 配置内存 */
li msize, MEM_SIZE
#if !defined(NAND_BOOT_EN)
/*
SD_CONFIG[31:0]SD_CONFIG[63:32]
3232
使
*/
//
li t1, 0xbfd00410 // SD_CONFIG[31:0]0xbfd00410
li a1, SD_PARA0 // SD_PARA0sdram_cfg.S
sw a1, 0x0(t1) // SD_PARA0SD_CONFIG[31:0]
li a1, SD_PARA1
sw a1, 0x4(t1) // SD_PARA1SD_CONFIG[63:32]
//
li a1, SD_PARA0
sw a1, 0x0(t1)
li a1, SD_PARA1
sw a1, 0x4(t1)
//
li a1, SD_PARA0
sw a1, 0x0(t1)
li a1, SD_PARA1_EN // 使
sw a1, 0x4(t1)
// DELAY(100)
#endif
/**************************************CACHE*****************************/
#define CF_7_SE (1 << 3) /* Secondary cache enable */
#define CF_7_SC (1 << 31) /* Secondary cache not present */
#define CF_7_TE (1 << 12) /* Tertiary cache enable */
#define CF_7_TC (1 << 17) /* Tertiary cache not present */
#define CF_7_TS (3 << 20) /* Tertiary cache size */
#define CF_7_TS_AL 20 /* Shift to align */
#define NOP8 nop;nop;nop;nop;nop;nop;nop;nop
do_caches:
/* Init caches... */
li s7, 0 /* no L2 cache */
li s8, 0 /* no L3 cache */
bal cache_init // cache_init
nop
mfc0 a0, CP0_CONFIG // 0configa0
and a0, a0, ~((1<<12) | 7) // a0 = a0 & ~((1<<12) | 7)
or a0, a0, 2 // a0 |= 2
mtc0 a0, CP0_CONFIG // a00config
/***********************MEMORY DEBUGGING AND COPY SELF TO RAM***********************/
//#include "newtest.32/mydebug.S"
bootnow:
/* copy program to sdram to make copy fast */
/* 先将执行拷贝pmon到内存任务的代码拷贝到内存0xa0000000 */
/* 121122
* 0x80010000
* ROMSPI NOR FLASH0xBFC00000
* s0
*/
la t0, 121f // 121t0
addu t0, s0 // 使s0t0(121)
la t1, 122f // 122t1
addu t1, s0 // 使s0t1(122)
li t2, 0xa0000000 // 0xa0000000t2
1:
lw v0, (t0) // t04v0
sw v0, (t2) // v0t2
addu t0, 4 // t04
addu t2, 4 // t24
ble t0, t1, 1b // t0 <= t114
nop
li t0, 0xa0000000 // 0xa0000000t0
jr t0 // 0xa0000000
nop
121:
/* Copy PMON to execute location... */
/* 0xa0010000
kseg0(0x8000 0000 - 0x9FFF FFFF)kseg1(0xA000 0000 - 0xBFFF FFFF)
0xA000 0000kseg10x8000 0000kseg0
0x8001 00000xA001 0000
*/
la a0, _start // start0x80010000a0
addu a1, a0, s0 // 使s0a0a1=0xBFC00000
la a2, __bss_start // _edataa2
or a0, 0xa0000000 // a0 = a0 | 0xa0000000 = 0xa0010000
or a2, 0xa0000000 // a2 = a2 | 0xa0000000_edata
subu t1, a2, a0 // t1 = a2 - a0start_edata
srl t1, t1, 2 // t1 >>= 2t14(44)
// t1使
move t0, a0 // t0 = a0 = 0xa0010000 ()
move t1, a1 // t1 = a1 = 0xBFC00000 (startROM)
move t2, a2 // t2 = a2 (_edataROM)
/* copy text section */
1: and t3, t0, 0x0000ffff // t3 = t0 & 0x0000ffff16
bnez t3, 2f // t302t3使
nop
2: lw t3, 0(t1) // t14t3
nop
sw t3, 0(t0) // t34t0
addu t0, 4 // t04
addu t1, 4 // t1 4
bne t2, t0, 1b // t2t01
nop
/* copy text section done. */
/* 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
/* 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
/* jump to RT-Thread RTOS */
jal rtthread_startup
nop
/* restart, never die */
j _start
nop
122:
stuck:
b stuck
nop
#endif
.extern tlb_refill_handler
.extern cache_error_handler
/* Exception Handler */
/* 0x0 - TLB refill handler */
.section .vectors.1, "ax", %progbits
.global tlb_refill_exception
.type tlb_refill_exception,@function
tlb_refill_exception:
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
.global general_exception
.type general_exception,@function
general_exception:
j _general_exception_handler
nop
/* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */
.section .vectors.4, "ax", %progbits
.global irq_exception
.type irq_exception,@function
irq_exception:
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