1
0
mirror of git://projects.qi-hardware.com/xburst-tools.git synced 2024-12-23 13:30:48 +02:00

blink led all in c code, start add read nand code

This commit is contained in:
xiangfu 2008-06-20 22:24:29 -04:00
parent 474787a501
commit c382c5066c
9 changed files with 501 additions and 297 deletions

View File

@ -7,5 +7,6 @@ AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
export CROSS_COMPILE AD LD CC OBJCOPY
export CROSS_COMPILE AD LD CC OBJCOPY OBJDUMP

View File

@ -1,11 +1,8 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo1973 GTA02 Linux GSM phone
*
* See file CREDITS for list of people who contributed to this
* project.
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -26,14 +23,6 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#define TEXT_BASE 0x00000000 /* xiangfu add*/
#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */
/*
* Size of malloc() pool
*/
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024)
/* >> CFG_VIDEO_LOGO_MAX_SIZE */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
#define TEXT_BASE 0x33F80000 /* xiangfu add*/
#endif /* __CONFIG_H */

View File

@ -19,11 +19,11 @@ INCLUDE =../include
IMAGE =../image
CFLAGS =-Wall -I $(INCLUDE) -g -c -o
all:led.S led.c lowlevel_init.S
$(CC) $(CFLAGS) led_S.o led.S
$(CC) $(CFLAGS) led_C.o led.c
all:start.S blink_led.c lowlevel_init.S
$(CC) $(CFLAGS) start.o start.S
$(CC) $(CFLAGS) blink_led.o blink_led.c
$(CC) $(CFLAGS) lowlevel_init.o lowlevel_init.S
$(LD) -T$(LDS) -g led_S.o led_C.o lowlevel_init.o -o led.o
$(LD) -T$(LDS) -g start.o blink_led.o lowlevel_init.o -o led.o
$(OBJCOPY) -O binary -S led.o $(IMAGE)/led_on
clean:

55
qiboot/src/blink_led.c Normal file
View File

@ -0,0 +1,55 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
* Author: xiangfu liu <xiangfu@openmoko.org>
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#define GPBCON (*(volatile unsigned *)0x56000010)
#define GPBDAT (*(volatile unsigned *)0x56000014)
#define GPBDW (*(volatile unsigned *)0x56000018)
#define LED3_ON() (GPBDAT &= ~(0x1))
#define LED4_ON() (GPBDAT &= ~(0x2))
#define LED3_OFF() (GPBDAT |= (0x1))
#define LED4_OFF() (GPBDAT |= (0x2))
int delay(int time)
{
int i=0;
for(i=0;i<time;i++);
return 0;
}
int blink_led()
{
GPBCON = 0x5;
GPBDW = 0xffff;
while(1)
{
LED3_ON();
delay(0xfffff);
LED3_OFF() ;
delay(0xfffff);
LED4_ON();
delay(0xfffff);
LED4_OFF();
delay(0xfffff);
}
return 0;
}

View File

@ -32,8 +32,9 @@ SECTIONS
. = ALIGN(4);
.text :
{
led_S.o (.text)
led_C.o (.text)
start.o (.text)
lowlevel_init.o(.text)
blink_led.o (.text)
*(.text)
}
@ -48,6 +49,6 @@ SECTIONS
. = ALIGN(4);
__bss_start = .;
.bss (NOLOAD) : { *(.bss) }
.bss : { *(.bss) }
_end = .;
}

View File

@ -1,194 +0,0 @@
#include <neo_gta02.h>
.globl _start
_start: b start_code
/* ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
/* turn off the watchdog */
# define pWTCON 0x53000000
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define INTSUBMSK_val 0xffff
# define CAMDIVN 0x4C000018
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =INTSUBMSK_val
ldr r0, =INTSUBMSK
str r1, [r0]
/* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */
ldr r0, =CAMDIVN
mov r1, #0
str r1, [r0]
/* Clock asynchronous mode */
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
/* enable uart */
ldr r0, =0x4c00000c /* clkcon */
ldr r1, =0x7fff0 /* all clocks on */
str r1, [r0]
/* gpio UART0 init */
ldr r0, =0x56000070
mov r1, #0xaa
str r1, [r0]
/* init uart */
ldr r0, =0x50000000
mov r1, #0x03
str r1, [r0]
ldr r1, =0x245
str r1, [r0, #0x04]
mov r1, #0x01
str r1, [r0, #0x08]
mov r1, #0x00
str r1, [r0, #0x0c]
mov r1, #0x1a
str r1, [r0, #0x28]
bl cpu_init_crit
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
/* blink led */
.extern blink_led
bl blink_led
.global delay
delay:
subs r0,r0,#0x1
bne delay
mov pc,lr
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
bl lowlevel_init
mov lr, ip
mov pc, lr

View File

@ -1,29 +0,0 @@
#define GPBCON (*(volatile unsigned *)0x56000010)
#define GPBDAT (*(volatile unsigned *)0x56000014)
#define GPBDW (*(volatile unsigned *)0x56000018)
#define LED3_ON() (GPBDAT &= ~(0x1))
#define LED4_ON() (GPBDAT &= ~(0x2))
#define LED3_OFF() (GPBDAT |= (0x1))
#define LED4_OFF() (GPBDAT |= (0x2))
extern void delay(int time);
int blink_led()
{
GPBCON = 0x5;
GPBDW = 0xffff;
while(1)
{
LED3_ON();
delay(0xffff);
LED3_OFF() ;
delay(0xffff);
LED4_ON();
delay(0xffff);
LED4_OFF();
delay(0xffff);
}
return 1;
}

View File

@ -1,14 +1,8 @@
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
* Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
*
* Modified for the FIC Neo1973 GTA01 by Harald Welte <laforge@openmoko.org>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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
@ -26,11 +20,10 @@
*/
/*
* #include <config.h>
* #include <version.h>
*/
* #include <config.h>
* #include <version.h>
*/
#include <neo_gta02.h>
/* some parameters for the board */
/*
*
@ -62,7 +55,7 @@
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x7 /* 14clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
@ -71,7 +64,7 @@
#define B1_Tcos 0x3 /* 4clk */
#define B1_Tacc 0x3 /* 4clk */
#define B1_Tcoh 0x3 /* 4clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0
@ -79,7 +72,7 @@
#define B2_Tcos 0x0
#define B2_Tacc 0x7
#define B2_Tcoh 0x0
#define B2_Tah 0x0
#define B2_Tah 0x0
#define B2_Tacp 0x0
#define B2_PMC 0x0
@ -87,15 +80,15 @@
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x1 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_PMC 0x0 /* normal */
#define B4_Tacs 0x0 /* 0clk */
#define B4_Tcos 0x0 /* 0clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x0 /* 0clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
@ -103,26 +96,26 @@
#define B5_Tcos 0x0 /* 0clk */
#define B5_Tacc 0x7 /* 14clk */
#define B5_Tcoh 0x0 /* 0clk */
#define B5_Tah 0x0 /* 0clk */
#define B5_Tah 0x0 /* 0clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
#define B6_MT 0x3 /* SDRAM */
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 /* 3clk */
#define B6_SCAN 0x1 /* 9bit */
#define B7_SCAN 0x1 /* 9bit */
#define B7_MT 0x3 /* SDRAM */
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 3clk */
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */
#define REFEN 0x1 /* Refresh enable */
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp 0x1 /* 3clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
#define Trp 0x1 /* 3clk */
#define Trc 0x3 /* 7clk */
#define Tchr 0x2 /* 3clk */
//#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
#define REFCNT 997 /* period=17.5us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/
@ -149,30 +142,6 @@ lowlevel_init:
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3)
/* switch on power for NAND */
ldr r0, =0x56000010 /* GPBCON */
ldr r1, [r0]
orr r1, r1, #0x10
str r1, [r0]
ldr r0, =0x56000014 /* GPBDAT */
ldr r1, [r0]
orr r1, r1, #(1 <<2)
str r1, [r0]
#endif
#if defined(CONFIG_ARCH_GTA02_v1)
/* enable KEEPACT(GPJ3) to make sure PMU keeps us alive */
ldr r0, =0x56000000 /* GPJ base */
ldr r1, [r0, #0xd0] /* GPJCON */
orr r1, r1, #(1 << 6)
str r1, [r0, #0xd0]
ldr r1, [r0, #0xd4] /* GPJDAT */
orr r1, r1, #(1 << 3)
str r1, [r0, #0xd4]
#elif CONFIG_GTA02_REVISION >= 2
/* enable KEEPACT(GPJ8) to make sure PMU keeps us alive */
ldr r0, =0x56000000 /* GPJ base */
ldr r1, [r0, #0xd0] /* GPJCON */
@ -182,7 +151,6 @@ lowlevel_init:
ldr r1, [r0, #0xd4] /* GPJDAT */
orr r1, r1, #(1 << 8)
str r1, [r0, #0xd4]
#endif
/* everything is fine now */
mov pc, lr
@ -200,10 +168,6 @@ SMRDATA:
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
#if CONFIG_GTA02_REVISION >= 2
.word 0xb1
#else
.word 0xb2
#endif
.word 0x30
.word 0x30

417
qiboot/src/start.S Normal file
View File

@ -0,0 +1,417 @@
/*
* (C) Copyright 2007 OpenMoko, Inc.
*
* Configuation settings for the FIC Neo GTA02 Linux GSM phone
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <neo_gta02.h>
.globl _start
_start: b start_code
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (called from the ARM reset exception vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
*
*************************************************************************
*/
.globl preboot_override
preboot_override:
.word 0
/* Must follow preboot_override , so we get a well-known address ! */
.globl env_override
env_override:
.word 0
/* we want to be able to start kboot directly from within NAND flash */
.globl booted_from_nand
booted_from_nand:
.word 0
_booted_from_nand:
.word booted_from_nand
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
/* turn off the watchdog */
# define pWTCON 0x53000000
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define INTSUBMSK_val 0xffff
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =INTSUBMSK_val
ldr r0, =INTSUBMSK
str r1, [r0]
/* Make sure we get FCLK:HCLK:PCLK = 1:3:6 */
# define CAMDIVN 0x4C000018
ldr r0, =CAMDIVN
mov r1, #0
str r1, [r0]
/* Clock asynchronous mode */
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
# define LOCKTIME 0x4c000000
# define UPLLCON 0x4c000008
# define UPLLCON_val (( 88 << 12) + (8 << 4) + 2)
# define MPLLCON 0x4c000004
# define MPLLCON_val ((142 << 12) + (7 << 4) + 1)
ldr r0, =LOCKTIME
mov r1, #0xffffff
str r1, [r0]
ldr r0, =UPLLCON
ldr r1, =UPLLCON_val
str r1, [r0]
/* Page 7-23 in s3c2442B manual, seven nops between UPLL and MPLL */
nop
nop
nop
nop
nop
nop
nop
ldr r0, =MPLLCON
ldr r1, =MPLLCON_val
str r1, [r0] /* MPLLCON */
# define CLKDIVN 0x4C000014 /* clock divisor register */
# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */
ldr r0, =CLKDIVN
mov r1, #CLKDIVN_val
str r1, [r0]
/* enable uart */
ldr r0, =0x4c00000c /* clkcon */
ldr r1, =0x7fff0 /* all clocks on */
str r1, [r0]
/* gpio UART0 init */
ldr r0, =0x56000070
mov r1, #0xaa
str r1, [r0]
/* init uart */
ldr r0, =0x50000000
mov r1, #0x03
str r1, [r0]
ldr r1, =0x245
str r1, [r0, #0x04]
mov r1, #0x01
str r1, [r0, #0x08]
mov r1, #0x00
str r1, [r0, #0x0c]
mov r1, #0x1a
str r1, [r0, #0x28]
bl cpu_init_crit
/*
* Size of malloc() pool
*/
#define CFG_ENV_SIZE 0x40000 /* 128k Total Size of Environment Sector */
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024)
/* >> CFG_VIDEO_LOGO_MAX_SIZE */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
#define CONFIG_STACKSIZE (128*1024) /* regular stack */
#define CONFIG_STACKSIZE_IRQ (8*1024) /* IRQ stack */
#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:
str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
/* blink led */
ldr pc, _start_armboot
_start_armboot:
.word blink_led
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
bl lowlevel_init
mov lr, ip
mov pc, lr
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
ldr r2, _armboot_start
sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
ldmia r2, {r2 - r3} @ get pc, cpsr
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r7, sp, #S_PC
stmdb r7, {sp, lr}^ @ Calling SP, LR
str lr, [r7, #0] @ Save calling PC
mrs r6, spsr
str r6, [r7, #4] @ Save CPSR
str r0, [r7, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack
sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
str lr, [r13] @ save caller lr / spsr
mrs lr, spsr
str lr, [r13, #4]
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13
mov lr, pc
movs pc, lr
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
//bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
//bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
//bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
//bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
//bl do_not_used
/* CONFIG_USE_IRQ*/
.align 5
irq:
get_irq_stack
irq_save_user_regs
//bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
//bl do_fiq
irq_restore_user_regs