Как инициализировать основной таймер в ARM Cortex-A7 - PullRequest
0 голосов
/ 14 февраля 2020

В настоящее время я работаю над разработкой операционной системы для Raspberry 2, это мой последний проект для получения университетской степени, и сейчас у меня серьезные проблемы с созданием простого таймера, который выдает прерывание каждую секунду, потому что документация , предоставляемая ARM, не разъясняет, как инициализировать этот модуль.
Я прочитал справочное руководство по архитектуре, оно находится в Архитектура ARM / Справочные руководства / ARMv7-AR

Может кто-нибудь объяснить мне, как происходит инициализация основного таймера?

Я добавлю то, что я пробовал до сих пор:

В моем файле C

    _local_timer_init();
    // ROUTING IRQ
    *(volatile uint32_t*)CORE0_L_TIMER_INT_CTL = 0x8;

В моем файле ассемблера

.globl _local_timer_init
/*
        THIS STEPS APPLIES IN A SYSTEM WHERE THERE IS NOT VIRTUALIZATION SUPPORT
        (I think so)
    1. Look into CNTKCTL register if you need
    2. Look into CNTP_CTL or CNTH_CTL or CNTV_CTL to enable or disable
       the corresponding timer (bit 0)
    3. You have to set the compare value for the corresponding timer
       CNTP_CVAL, CNTH_CVAL, CNTV_CVAL if needed
    4. It should be in boot.S but you have to initialize the counter 
       frequency register, CNTFRQ
    5. Putting the corresponding TVAL register to a right value
    6. Routing the IRQ and enabling IRQ of the corresponding core
*/
_local_timer_init:
    // ENABLING TIMER
    mov r0, #1
    mcr p15, #0, r0, c14, c3, #1 //Write to CNTV_CTL
    // SETTING FREQUENCY TIMER
    //we don't need this right now
    // SETTING TVAL REGISTER (virtual)
    mrc p15, #0, r0, c14, c0, #0 //we obtain CNTFRQ
    mcr p15, #0, r0, c14, c3, #0 //Write to CNTV_TVAL

Я также создал свой пользовательский обработчик ассемблера для исключений IRQ, как это: возможно, проблема здесь, я действительно не знаю Является ли это правильным способ обработки исключения IRQ?

irq_s_handler:
    /*Mode: PL1 irq */
    srsda sp!, #0x12 //we stores the spsr and lr at the address contained in sp of the mode irq
    /*
    It is necessary to switch to supervisor mode and store some registers
    into it's stack for having support for nested exceptions
     */
    push {r0-r12}
    bl irq_c_handler
    pop {r0-r12}
    rfeib sp! //we do the inverse operation of srsdb
    subs pc, lr, #4 //we adjust the appropiate value considered
...