Sunday, August 27, 2006

kernel start up -blackfin arch - resend


mach-bf537/head.S:

.text

ENTRY(__start)
ENTRY(__stext)
/* R0: argument of command line string, passed from uboot, save it */
R7 = R0;
/* Set the SYSCFG register */
R0 = 0x36;
SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd
Bit)*/
/-------------------------------------------------------
SYSCFG: Only three settings

SYSCFG[2]: SNEN - self-nesting interrupt enable
SYSCFG[1]: CCEN - cycle count
SYSCFG[0]: SSSTEP - Supervisor Single Step

--------------------------------------------------------/

R0 = 0;

/*Clear Out All the data and pointer Registers*/
R1 = R0;
R2 = R0;
R3 = R0;
R4 = R0;
R5 = R0;
R6 = R0;

P0 = R0;
P1 = R0;
P2 = R0;
P3 = R0;
P4 = R0;
P5 = R0;

LC0 = r0;
LC1 = r0;
L0 = r0;
L1 = r0;
L2 = r0;
L3 = r0;

/*Clear Out All the DAG Registers*/
B0 = r0;
B1 = r0;
B2 = r0;
B3 = r0;

I0 = r0;
I1 = r0;
I2 = r0;
I3 = r0;

M0 = r0;
M1 = r0;
M2 = r0;
M3 = r0;

/* Turn off the icache */
p0.l = (IMEM_CONTROL & 0xFFFF);
p0.h = (IMEM_CONTROL >> 16);
R1 = [p0];
R0 = ~ENICPLB;
R0 = R0 & R1;
/--------------------------
Disable ICPLB
---------------------------/

/* Anamoly 05000125 */
CLI R2;
SSYNC;
[p0] = R0;
SSYNC;
STI R2;

/* Turn off the dcache */
p0.l = (DMEM_CONTROL & 0xFFFF);
p0.h = (DMEM_CONTROL >> 16);
R1 = [p0];
R0 = ~ENDCPLB;
R0 = R0 & R1;
/----------------------------
Disable DCPLB
------------------------------/

/* Anamoly 05000125 */
CLI R2;
SSYNC;
[p0] = R0;
SSYNC;
STI R2;

/* Initialise General-Purpose I/O Modules on BF537 */
/* Rev 0.0 Anomaly 05000212 - PORTx_FER, PORT_MUX Registers Do Not
accept "writes" correctly: */
p0.h = hi(PORT_MUX);
p0.l = lo(PORT_MUX);
R0.L = W[P0]; //Read
SSYNC;
R0 = (PGDE_UART | PFTE_UART)(Z);
W[P0] = R0.L; //Write
SSYNC;
W[P0] = R0.L; /* Enable both UARTS */
SSYNC;

p0.h = hi(PORTF_FER);
p0.l = lo(PORTF_FER);
R0.L = W[P0]; //Read
SSYNC;
R0 = 0x000F(Z);
W[P0] = R0.L; //Write
SSYNC;
W[P0] = R0.L; /* Enable peripheral function of PORTF for UART0 and
UART1 */
SSYNC;

p0.h = hi(EMAC_SYSTAT);
p0.l = lo(EMAC_SYSTAT);
R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
R0.l = 0xFFFF;
[P0] = R0;
SSYNC;

/*Initialise UART*/
p0.h = hi(UART_LCR);
p0.l = lo(UART_LCR);
r0 = 0x0(Z);
w[p0] = r0.L; /* To enable DLL writes */
ssync;

p0.h = hi(UART_DLL);
p0.l = lo(UART_DLL);
r0 = 0x00(Z);
w[p0] = r0.L;
ssync;

p0.h = hi(UART_DLH);
p0.l = lo(UART_DLH);
r0 = 0x00(Z);
w[p0] = r0.L;
ssync;

p0.h = hi(UART_GCTL);
p0.l = lo(UART_GCTL);
r0 = 0x0(Z);
w[p0] = r0.L; /* To enable UART clock */
ssync;

/* Initialize stack pointer */
sp.l = lo(INITIAL_STACK);
sp.h = hi(INITIAL_STACK);
fp = sp;
usp = sp;

/*Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM*/
call _bf53x_relocate_l1_mem;
#if CONFIG_BFIN_KERNEL_CLOCK
call start_dma_code;
#==endif
/* Code for initializing Async memory banks */

p2.h = hi(EBIU_AMBCTL1);
p2.l = lo(EBIU_AMBCTL1);
r0.h = hi(AMBCTL1VAL);
r0.l = lo(AMBCTL1VAL);
[p2] = r0;
ssync;

p2.h = hi(EBIU_AMBCTL0);
p2.l = lo(EBIU_AMBCTL0);
r0.h = hi(AMBCTL0VAL);
r0.l = lo(AMBCTL0VAL);
[p2] = r0;
ssync;

p2.h = hi(EBIU_AMGCTL);
p2.l = lo(EBIU_AMGCTL);
r0 = AMGCTLVAL;
w[p2] = r0;
ssync;
call _real_start;

/* This section keeps the processor in supervisor mode
* during kernel boot. Switches to user mode at end of boot.
* See page 3-9 of Hardware Reference manual for documentation.
*/

/* EVT15 = _real_start */

p0.l = lo(EVT15);
p0.h = hi(EVT15);
p1.l = _real_start;
p1.h = _real_start;
[p0] = p1;
csync;

p0.l = lo(IMASK);
p0.h = hi(IMASK);
p1.l = IMASK_IVG15;
p1.h = 0x0;
[p0] = p1;
csync;

raise 15;
p0.l = WAIT_HERE;
p0.h = WAIT_HERE;
reti = p0;
rti;

WAIT_HERE:
jump WAIT_HERE;

ENTRY(_real_start)
[ -- sp ] = reti;
p0.l = lo(WDOG_CTL);
p0.h = hi(WDOG_CTL);
r0 = 0xAD6(z);
w[p0] = r0; /* watchdog off for now */
ssync;

/* Code update for BSS size == 0
* Zero out the bss region.
*/

p1.l = ___bss_start;
p1.h = ___bss_start;
p2.l = ___bss_stop;
p2.h = ___bss_stop;
r0 = 0;
p2 -= p1;
lsetup (_clear_bss, _clear_bss ) lc0 = p2;
_clear_bss:
B[p1++] = r0;

/* In case there is a NULL pointer reference
* Zero out region before stext
*/

p1.l = 0x0;
p1.h = 0x0;
r0.l = __stext;
r0.h = __stext;
r0 = r0 >> 1;
p2 = r0;
r0 = 0;
lsetup (_clear_zero, _clear_zero ) lc0 = p2;
_clear_zero:
W[p1++] = r0;

/* pass the uboot arguments to the global value command line */
R0 = R7;
call _cmdline_init;

p1.l = __rambase;
p1.h = __rambase;
r0.l = __sdata;
r0.h = __sdata;
[p1] = r0;

p1.l = __ramstart;
p1.h = __ramstart;
p3.l = ___bss_stop;
p3.h = ___bss_stop;

r1 = p3;
[p1] = r1;

r0.l = lo(RAM_END);
r0.h = hi(RAM_END);
p1.l = __ramend;
p1.h = __ramend;
[p1] = r0;

/*
* load the current thread pointer and stack
*/
r1.l = _init_thread_union;
r1.h = _init_thread_union;

r2.l = 0x2000;
r2.h = 0x0000;
r1 = r1 + r2;
sp = r1;
usp = sp;
fp = sp;
call _start_kernel;
_exit:
jump.s _exit;

No comments:

Blog Archive