arm swi 軟中斷 一例


原文在CU,挪過來了。

1. 目標

    本文單純驗證swi指令相關功能

2. 環境

    vmware + redhat 9 + arm-elf-gcc 2.95 + skyeye-1.2.6_rc1(模擬s3c44b0x)

3. 功能詳述

     1). 調用swi前,關IRQ,FIQ,INTMSK,改變CPU模式為用戶模式0x10000

     2). 指令的功能號由swi指令碼的低24位傳輸,通過
           ldr r4,[lr,#-4]
           bic r4,r4,#0xff000000
          得到它的功能號,這樣就可以根據功能號來進行相關功能的調用,
          本例只使用了兩個功能號:
         

           swi #1   1 表示兩個數的加法
           swi #2   2 表示兩個數的減法
           加法和減法的函數在.c文件中定義

     3). 在swi的處理程序中,對於c函數int add(int a,int b)的參數傳遞是通過
           r0,r1進行的, add(),sub()的結果通過r0返回給swi的處理程序
                           
     4). swi的處理流程:  swi #x --> 0x00000008 --> HandlerSWI --> C函數, 僅此而已

4. 運行:

            #  skyeye 
    調試

           # skyeye -d

     不用再加文件名,文件寫在skyeye.conf里了, 當然還得用arm-elf-gdb.

 

5. 文件清單(5個文件)

swi.s

.equ INTCON,   0x01e00000
.equ INTMSK,   0x01e0000c
.equ LOCKTIME, 0x01d8000c
.equ PLLCON,   0x01d80000
.equ CLKCON,   0x01d80004
.equ WTCON,    0x01d30000
.equ I_ISPR,   0x01e00020
.equ I_ISPC,   0x01e00024
.equ TCFG0,    0x01d50000
.equ TCFG1,    0x01d50004
.equ TCON,     0x01d50008
.equ TCNTB5,   0X01d50048
.equ UTXH0,    0x01d00020
.equ UFCON0,   0x01d00008
.equ ULCON0,   0x01d00000
.equ UCON0,    0x01d00004
.equ UBRDIV0,  0x01d00028


.globl _start
_start:
    b reset
    b .
    b HandlerSWI
    b .
    b .
    b .
    b .
    b .


reset:
    mov r0,#0x80 | 0x40 | 0x13  @ svc, disable irq,fiq
    msr cpsr_c,r0

    ldr sp, =0x0c700000

    ldr r0,=WTCON        @ disable watch dog
    ldr r1, =0x0
    str r1, [r0]

    ldr r0, =INTCON      @ non-vector mode, disable irq, disable fiq
    ldr r1, =0x7
    str r1, [r0]

    ldr r0, =LOCKTIME
    ldrb r1, =800
    strb r1, [r0]

    ldr r0, =PLLCON
    ldr r1, =0x34031
    str r1,[r0]
    
    ldr r0, =CLKCON
    ldr r1, =0x7ff8
    str r1, [r0]

    @ UART 0
    ldr r0,=UFCON0
    mov r1,#0x0
    str r1,[r0]

    ldr r0,=ULCON0
    mov r1,#0x03
    str r1,[r0]
    
    ldr r0,=UCON0
    mov r1,#0x05
    str r1,[r0]

    ldr r0,=UBRDIV0
    mov r1,#32
    str r1,[r0]

    ldr r0,=UTXH0        @ print 'C'
    mov r1,#'C'
    str r1,[r0]
    
    @ sp_svc
    ldr sp,=0x0c700000
    
    ldr r0, =INTMSK
    ldr r1, =0x03ffffff  @ disable all irq.
    str r1, [r0]
    
    @ move to user mode

    mov r0, #0x80 | 0x40 | 0x10  @ svc, disable irq,fiq
    msr cpsr_c,r0

    mov r0, #'A'
    mov r1, #0x1
    swi #1              @ add('A',1), print 'B'

    ldr r1,=UTXH0       @ print 'A'
    str r0,[r1]

    mov r0, #'H'        @ subtract
    mov r1, #0x1        @
    swi #2              @ sub('H',1), print 'G'

    ldr r1,=UTXH0       @ print 'H'
    str r0,[r1]
    
    ldr r1,=UTXH0       @ print 'S' -- STOP
    mov r0,#'S'
    str r0,[r1]

stop:    b stop              @ while(1);


HandlerSWI:       
    stmfd sp!,{r0-r12,lr}   

    ldr r4,[lr,#-4]         @ lr is "swi #x" address, get swi instruction code
    bic r4,r4,#0xff000000   @ get #x

    cmp r4,#1               @ 1 -- add(a,b)
    bne next

    bl add                  @ c function use r0,r1 as parameter, and return result with r0
    ldr r1,=UTXH0           @ print 'B'
    str r0,[r1]

next:
    cmp r4,#2               @ 2 -- sub(a,b)
    bne swi_return

    bl sub
    ldr r1,=UTXH0           @ print 'G'
    str r0,[r1]

swi_return:
    ldmfd sp!, {r0-r12,pc}^

c_fun.c

int add(int a,int b){
    return a + b;
}

int sub(int a,int b){
    return a - b;
}

 

swi.lds

OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
    . = 0x00000000;

    .text :
    {
            swi.o (.text)
    }
    
    . = ALIGN(4);
    .data :
    {
       *(.data)
    }

}

Makefile

all: swi

swi: swi.o c_fun.o
    arm-elf-ld -T swi.lds -o swi swi.o c_fun.o
    arm-elf-objcopy -O binary -S swi swi.bin

swi.o: swi.s
    arm-elf-as --gstabs -o swi.o swi.s

c_fun.o: c_fun.c
    arm-elf-gcc -gstabs -c c_fun.c

.PHONY: clean
clean:    
    rm -f swi.o c_fun.o swi swi.bin

 

skyeye.conf

#skyeye config file for S3C44B0X
cpu: arm7tdmi
mach: s3c44b0x

# physical memory
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00200000, file=swi.bin
mem_bank: map=M, type=RW, addr=0x0c000000, size=0x00800000

# peripherals I/O mapping area
mem_bank: map=I, type=RW, addr=0x01c00000, size=0x00400000

# uart 0
uart: mod=stdio

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM