OK6410 bare metal exception handling

Publisher:WanderlustGlowLatest update time:2018-10-11 Source: eefocusKeywords:OK6410 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

start.S source code:

.globl _start

_start:

    // 0 address 

    b reset // When resetting, the CPU jumps to address 0. In fact, after resetting, the CPU is in management mode (svc)

    ldr pc, =undefined_instruction //When the CPU encounters an unrecognizable instruction, address 4, the instruction goes to the memory to read the link address of un..

    ldr pc, _vector_swi // When executing the swi instruction, enter the swi mode, address 8, this instruction directly reads the current address of _vector_swi

    b halt @ldr pc, _prefetch_abort // Prefetch abort exception 

    b halt @ldr pc, _data_abort // Data access exception 

    b halt @ldr pc, _not_used // not used 

    ldr pc, _irq // 0x18 interrupt exception 

    b halt @ldr pc, _fiq // Fast interrupt exception 

_irq :

    .word vector_irq

_vector_swi:

    .word vector_swi

        

vector_swi:

    // 1. Save the scene 

    ldr sp, =0x56000000 //sp is r13 of svc mode, need to be reset

    stmdb sp!, {r0-r12, lr} // lr is the next instruction address of swi 

    // 2. Handle exceptions 

    mrs r0, cpsr

    ldr r1, =swi_str

    bl print_cpsr

    // 3. Restore the scene 

    ldmia sp!, {r0-r12, pc}^ // ^ means restore spsr to cpsr 

    

sw_str:

    .word 0x00697773           // swi 

    

undefined_instruction:

    // 1. Save the scene 

    ldr sp, =0x55000000

    stmdb sp!, {r0-r12, lr}

    // 2. Handle exceptions 

    mrs r0, cpsr

    ldr r1, =and_str

    bl print_cpsr

    // 3. Restore the scene 

    ldmia sp!, {r0-r12, pc}^ // ^ means restore spsr to cpsr 

and_str:

    .word 0x00646e75 // and 

usr_str:

    .word 0x00727375             // usr 

vector_irq:

    // 1. Save the scene 

    ldr sp, =0x54000000

    sub lr, lr, #4

    stmdb sp!, {r0-r12, lr} // lr is the next instruction address of swi 

    // 2. Handle exceptions 

    // 2.1 Identify which interrupt it is 

    // 2.2 Call its processing function 

    // 3. Restore the scene 

    ldmia sp!, {r0-r12, pc}^ // ^ means restore spsr to cpsr 

reset:

// Hardware related settings 

    // Peri port setup 

    ldr r0, =0x70000000

    orr r0, r0, #0x13

    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)

    

// Turn off the watchdog 

    // Write 0 to WTCON (0x7E004000) 

    ldr r0, =0x7E004000

    mov r1, #0

    str r1, [r0]

    

    // Set up the stack 

    ldr sp, =8*1024

    // Set the clock 

    bl clock_init

    bl ddr_init

    bl init_uart

//Copy the program's code segment and data segment to its link address     

    adr r0, _start // Get the current address of the _start instruction: 0

    ldr r1, =_start // _start link address 0x51000000 

    

    ldr r2, =bss_start // Starting link address of bss segment 

    

    sub r2, r2, r1

    

    cmp r0,r1

    beq clean_bss

    

    bl copy2ddr

    cmp r0, #0

    bne halt

        

// Clear BSS 

    // Clear the memory corresponding to the BSS segment 

clean_bss:

    ldr r0, =bss_start

    ldr r1, =bss_end

    move r3, #0

    cmp r0, r1

    ldreq pc, =on_ddr

clean_loop:

    str r3, [r0], #4

    cmp r0, r1    

    bne clean_loop        

    ldr pc, =on_ddr //jump to DDR to run

on_ddr:    

    mrs r0, cpsr //Read the value of the status register into r0

    bic r0,r0,#0x1f //clear the last 5 bits

    orr r0,r0,#0x10 //Set the fourth position to 1

    msr cpsr,r0 // Enter user mode and assign the value of r0 to the program status register

    ldr sp, =0x57000000 //sp in user mode

    ldr r1, =usr_str

    bl print_cpsr

    

    it is

    // CPU enters svc mode

    // Save the previous cpsr to spsr_svc 

    // Switch to r13_svc, r14_svc

    // Store the address of the next instruction of swi (bl hello) in r14(lr)_svc

    // Jump to address 8

              

    bl hello

undef: //After executing the hello function, the undefined instruction will be executed, thus entering the undefined instruction interrupt

    .word 0xff000000 

    // cpu enters Undefined mode

    // Save the previous cpsr to spsr_und 

    // Switch to r13_und, r14_und

    // Store the address of the next instruction in r14(lr)_und

    // Jump to address 4

swi_ret:

    bl main

halt:

    b stop

====================================================================

illustrate:

    ①After the above code is powered on and reset, the CPU is in management mode (svc). Execute b reset at address 0 to jump to reset: and continue running. After initializing the relevant hardware, the last 5 bits of cpsr will be cleared and the fourth bit will be set to 1. After entering user mode to set the stack, it will run in user mode (usr). That is, when the processor starts, it first enters supervisor mode (svc), and then enters other modes except user mode, mainly completing the stack settings of each mode, and finally enters user mode to run user programs; when a swi soft interrupt occurs, the CPU enters svc mode.


    ②Swi soft interrupt is mainly used to switch from usr mode (applications usually run in usr mode) to svc mode. Among the 7 modes of arm (there are more than 7), usr mode is the only non-privileged mode, and the others are privileged modes, such as fiq, und, etc. The switch between them can directly change the lower 5 bits of the cpsr register mode or when an exception such as fiq, und occurs, the purpose of switching can be achieved; while usr mode is not a privileged mode and there is no way to change the lower 5 bits of the cpsr register to switch. If you want to switch to a privileged mode, you can only call the swi instruction, which will help it enter the svc mode.

    ③If it was originally in svc mode, it would enter und (Undefined) mode after an undefined instruction exception occurs, and you need to reset the sp stack pointer at this time; if it was already in svc mode when the swi instruction was executed, then it would still be in svc mode after the swi soft interrupt occurs, and you do not need to set the sp stack pointer at this time (in the tiny4412 exception experiment, because the running uboot is already in svc mode, you need to pay attention to the sp pointer).

    ④ Only when handling swi and und exceptions does lr point to the next instruction. When other exceptions occur, lr points to the next two instructions. Each instruction on ARM is 32 bits long, i.e. 4 bytes. The swi instruction is also 32 bits and the value following it occupies the lower 24 bits of the instruction. Therefore, the value of the swi instruction can be obtained in the program, as follows:

unsigned long *pdo_swi = 0x75000000;

*pdo_swi = do_swi; //First put the interrupt processing function do_swi address at 0x75000000

When a swi exception occurs, the program will automatically jump to the exception vector entry: "b swi\n"

Then jump to swi to execute:

"swi:\n"

   "stmfd sp!, {r0-r12, lr}\n"

//Protect the scene and push the relevant registers in the usr mode into the stack.

//The storage order is to store lr, r12....r0 first, and finally sp points to the address of r0

"mov r0, sp\n" //Transfer the sp pointing to the r0 address in the previous step in the usr mode to the r0 register

"mov r3, #0x75000000\n" 

"ldr r3, [r3]\n"

"blx r3\n" //Call interrupt processing function do_swi, the parameters are placed in r0

//regs[0] == r0

//regs[1] == r1

//.....

//regs[12] == r12

//regs[13] == lr

void do_swi(unsigned long regs[]) //regs points to address r0 in usr mode

{

    //According to the stacking order, regs[13] is the lr value in usr mode, that is, the address of the next instruction when a swi exception occurs

    //regs[13] - 4 = lr - 4; the address of the previous instruction is also the address of the swi exception

    unsigned long *instr = regs[13] - 4;

    

    //According to the ARM instruction is 32 bits, the swi instruction is also 32 bits and the value following it occupies the lower 24 bits of the instruction to get the value value

    printf("swi:  0x%x\n", *instr & 0xffffff);

}

====================================================================

Note the usage of exceptions in the operating system:

    ①The purpose of SWI exception interrupt is: when the application is running in user mode (usr), when the application calls the open/read/write function, it needs to call the kernel function. How to enter the kernel? In fact, the open/read/write function is a SWI #VAL instruction with different parameters. Once this instruction is executed, the CPU will have an exception. The cpu will enter the svc mode and jump to a fixed address. The kernel code is placed in the address. The kernel code determines the #VAL parameter value brought by the SWI instruction. If it is an open function, it calls the sys_open function, etc.

    ②Use of undefined instruction exception: for debugging, how to set a breakpoint when the program is executed? When the program is running, take out the instruction where you want to set the breakpoint, save it, and replace it with an undefined instruction. When the program runs to the instruction, an undefined instruction exception will occur, and enter the undefined instruction exception handling function. Some code can be placed in the handling function, such as waiting for the user to enter other instructions. If the user wants to check certain registers and certain memory, you can check the register memory and return the result. When you want to continue running, restore the replaced instruction and let the program run again from here.

OK6410 bare metal exception handling

                                                                     Stack order


Keywords:OK6410 Reference address:OK6410 bare metal exception handling

Previous article:ARM working mode and big-endian and small-endian storage modes
Next article:OK6410 bare metal NAND Flash operation to update firmware

Recommended ReadingLatest update time:2024-11-23 15:08

OK6410 rmmod failed to uninstall the module: No such file or directory
illustrate: 1. This document is based on Linux 2.6.32 and has been tested on TQ2440. 2. arm-linux-gcc version Thread model: posix gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) 1. Problem description and tracking analysis The following error was found when using rmmod rmmod chdir n
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号