为什么我的SWI指令挂? (BeagleBone黑色,ARM Cortex-A8的CPU) [英] Why does my SWI instruction hang? (BeagleBone Black, ARM Cortex-A8 cpu)

查看:533
本文介绍了为什么我的SWI指令挂? (BeagleBone黑色,ARM Cortex-A8的CPU)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始写的 BeagleBone黑,它采用了ARM玩具OS基于Cortex-A8的- TI的Sitara AM3359的SoC 和U-Boot的引导程序。我有一个简单的独立的Hello World应用程序写入UART0,我可以通过U-Boot的加载,到目前为止,现在我试图转移到中断处理程序,但我不能让SWI做什么,但挂设备。

I'm starting to write a toy OS for the BeagleBone Black, which uses an ARM Cortex-A8-based TI Sitara AM3359 SoC and the U-Boot bootloader. I've got a simple standalone hello world app writing to UART0 that I can load through U-Boot so far, and now I'm trying to move on to interrupt handlers, but I can't get SWI to do anything but hang the device.

据该AM335x TRM(4099开始页面上,如果你有兴趣),中断向量表在ROM于0x20000映射。该ROM SWI处理程序跳转到RAM的0x4030ce08,将跳转到存储在0x4030ce28的地址。 (最初,这是0x20084一个独特的死循环。)

According to the AM335x TRM (starting on page 4099, if you're interested), the interrupt vector table is mapped in ROM at 0x20000. The ROM SWI handler branches to RAM at 0x4030ce08, which branches to the address stored at 0x4030ce28. (Initially, this is a unique dead loop at 0x20084.)

我的code。在内存顶部的所有ARM处理器模式SP建立自己的领域,并允许中断CPSR中,然后执行一个SWI指令,总是挂起。 (也许跳跃到一些死循环指令?)我已经看了一堆样品,并读取任何文件我能找到的,我没有看到,我错过了什么。

My code sets up all the ARM processor modes' SP to their own areas at the top of RAM, and enables interrupts in the CPSR, then executes an SWI instruction, which always hangs. (Perhaps jumping to some dead-loop instruction?) I've looked at a bunch of samples, and read whatever documentation I could find, and I don't see what I'm missing.

目前我与董事会唯一的互动是随着我的Linux机器上UART0串行连接。 U-Boot的初始化UART0,并允许二进制通过串行连接加载。

Currently my only interaction with the board is over serial connection on UART0 with my linux box. U-Boot initializes UART0, and allows loading of the binary over the serial connection.

下面是有关的组件:

.arm
.section ".text.boot"

.equ usr_mode,          0x10
.equ fiq_mode,          0x11
.equ irq_mode,          0x12
.equ svc_mode,          0x13
.equ abt_mode,          0x17
.equ und_mode,          0x1b
.equ sys_mode,          0x1f

.equ swi_vector,        0x4030ce28

.equ rom_swi_b_addr,    0x20008
.equ rom_swi_addr,      0x20028
.equ ram_swi_b_addr,    0x4030CE08
.equ ram_swi_addr,      0x4030CE28

.macro setup_mode mode, stackpointer
    mrs r0, cpsr
    mov r1, r0
    and r1, r1, #0x1f
    bic r0, r0, #0x1f
    orr r0, r0, #\mode
    msr cpsr_csfx, r0
    ldr sp, =\stackpointer
    bic r0, r0, #0x1f
    orr r0, r0, r1
    msr cpsr_csfx, r0
.endm

.macro disable_interrupts
    mrs r0, cpsr
    orr r0, r0, #0x80
    msr cpsr_c, r0
.endm

.macro enable_interrupts
    mrs r0, cpsr
    bic r0, r0, #0x80
    msr cpsr_c, r0
.endm

.global _start
_start:
    // Initial SP
    ldr r3, =_C_STACK_TOP
    mov sp, r3

    // Set up all the modes' stacks
    setup_mode fiq_mode, _FIQ_STACK_TOP
    setup_mode irq_mode, _IRQ_STACK_TOP
    setup_mode svc_mode, _SVC_STACK_TOP
    setup_mode abt_mode, _ABT_STACK_TOP
    setup_mode und_mode, _UND_STACK_TOP
    setup_mode sys_mode, _C_STACK_TOP

    // Clear out BSS
    ldr r0, =_bss_start
    ldr r1, =_bss_end
    mov r5, #0
    mov r6, #0
    mov r7, #0
    mov r8, #0

    b _clear_bss_check$

_clear_bss$:
    stmia r0!, {r5-r8}

_clear_bss_check$:
    cmp r0, r1
    blo _clear_bss$

    // Load our SWI handler's address into
    // the vector table
    ldr r0, =_swi_handler
    ldr r1, =swi_vector
    str r0, [r1]

    // Debug-print out these SWI addresses
    ldr r0, =rom_swi_b_addr
    bl print_mem

    ldr r0, =rom_swi_addr
    bl print_mem

    ldr r0, =ram_swi_b_addr
    bl print_mem

    ldr r0, =ram_swi_addr
    bl print_mem

    enable_interrupts

swi_call$:
    swi #0xCC
    bl kernel_main
    b _reset


.global _swi_handler
_swi_handler:
    // Get the SWI parameter into r0
    ldr r0, [lr, #-4]
    bic r0, r0, #0xff000000

    // Save lr onto the stack
    stmfd sp!, {lr}
    bl print_uint32
    ldmfd sp!, {pc}

这些调试打印产生预期值:

Those debugging prints produce the expected values:

00020008: e59ff018
00020028: 4030ce08
4030ce08: e59ff018
4030ce28: 80200164

(据objdump的,0x80200164的确_swi_handler。0xe59f​​f018是指令LDR PC,[PC,#为0x20]。)

(According to objdump, 0x80200164 is indeed _swi_handler. 0xe59ff018 is the instruction "ldr pc, [pc, #0x20]".)

我在想什么?它的看起来的这样应该工作。

What am I missing? It seems like this should work.

推荐答案

在板子上的固件改变了ARM的执行方式和地点
与各个模式相关联的矢量表。在我自己的情况(裸机
片段code。在权限级别1执行,并在BBB的UBOOT推出)活动量表地址0x9f74b000。

The firmware on the board changes the ARM execution mode and the locations of the vector tables associated with the various modes. In my own case (a bare-metal snippet code executed at Privilege Level 1 and launched by BBB's uBoot) the active vector table is at address 0x9f74b000.

在一般情况下,你可能会使用类似下面的功能定位
积极向量表:

In general, you might use something like the following function to locate the active vector table:

static inline unsigned int *get_vectors_address(void)
{
    unsigned int v;

    /* read SCTLR */
    __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0\n"
            : "=r" (v) : : );
    if (v & (1<<13))
        return (unsigned int *) 0xffff0000;
    /* read VBAR */
    __asm__ __volatile__("mrc p15, 0, %0, c12, c0, 0\n"
            : "=r" (v) : : );
    return (unsigned int *) v;
}

这篇关于为什么我的SWI指令挂? (BeagleBone黑色,ARM Cortex-A8的CPU)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆