Jump to content

    

Переключить режим работы ARM

Завтра с работы пришлю процедуру без входа в Abort.

Не надо процедуру. Принцип в двух словах изложите.

Как определить границу памяти без входа в abort, если при обращении мимо этот самый abort однозначно генерируется?

Share this post


Link to post
Share on other sites

В u-boot есть такая функция ram_size:

 

static long ram_size(ulong *base, long maxsize)
{
    volatile long    *test_addr;
    volatile ulong    *base_addr = base;
    ulong        ofs;        /* byte offset from base_addr */
    ulong        save;        /* to make test non-destructive */
    ulong        save2;        /* to make test non-destructive */
    long        ramsize = -1;    /* size not determined yet */

    save = *base_addr;        /* save value at 0 so can restore */
    save2 = *(base_addr+1);    /* save value at 4 so can restore */

    /* is any SRAM present? */
    *base_addr = 0x5555aaaa;

    /* It is important to drive the data bus with different data so
     * it doesn't remember the value and look like RAM that isn't there.
     */
    *(base_addr + 1) = 0xaaaa5555;    /* use write to modify data bus */

    if (*base_addr != 0x5555aaaa)
    ramsize = 0;        /* no RAM present, or defective */
    else {
    *base_addr = 0xaaaa5555;
    *(base_addr + 1) = 0x5555aaaa;    /* use write to modify data bus */
    if (*base_addr != 0xaaaa5555)
        ramsize = 0;    /* no RAM present, or defective */
    }

    /* now size it if any is present */
    for (ofs = 4; ofs < maxsize && ramsize < 0; ofs <<= 1) {
    test_addr = (long*)((long)base_addr + ofs);    /* location to test */

    *base_addr = ~*test_addr;
    if (*base_addr == *test_addr)
        ramsize = ofs;    /* wrapped back to 0, so this is the size */
    }

    *base_addr = save;        /* restore value at 0 */
    *(base_addr+1) = save2;    /* restore value at 4 */
    return (ramsize);
}

 

 

Вызываю ее при запрещенных прерываниях, соответственно нет и Abort

Share this post


Link to post
Share on other sites
Вызываю ее при запрещенных прерываниях, соответственно нет и Abort

Однако, нет слов :(.

Share this post


Link to post
Share on other sites
Вызываю ее при запрещенных прерываниях, соответственно нет и Abort

Разве оно работает? Вместо того чтобы писАть в рам адрес ячейки, чтобы оверлап детектировать, Вы пишете туда ахинею, совсем для этого не предназначенную :(

Share this post


Link to post
Share on other sites

Ну просветите! Надо объем памяти выяснить или в Abort влезть?

 

По поводу "Нет слов". Может это тлетворное влияние понедельника, но не въехал в смысл фразы.

 

Пишу не я, а авторы u-boot.

Share this post


Link to post
Share on other sites
Пишу не я, а авторы u-boot.

Зачем тогда копипастите, то что не понимете, да и еще и добавляете отсебятину :(?

Share this post


Link to post
Share on other sites
Зачем тогда копипастите, то что не понимете, да и еще и добавляете отсебятину :(?

 

Уважаемый гуру!

 

Наверное у меня с утра приступ мозговой слабости. Буду признателен, если вы уделите некоторую толику своего времени для пояснения мне:

1. Чего я не понимаю.

2. В чем состоит отсебятина.

 

P.S. Безо всякого ехидства спрашиваю. Действительно не понял.

Share this post


Link to post
Share on other sites
Действительно не понял.

Запрет прерываний на Abort ну никаким образом не распространяется.

Share this post


Link to post
Share on other sites
Чего я не понимаю.

Про осебятину с запретом прерыаний - ответили.

А не хотите понимать того, что Data Abort будет всегда при обращении к внешней памяти о которой не знает/не запрограммирован EMC. Есть/нет/работоспособна память это второе, а как запрограммирован EMC это первое.

Share this post


Link to post
Share on other sites
В u-boot есть такая функция ram_size:

static long ram_size(ulong *base, long maxsize)
{
....
}

 

Не знаю как насчет интеллигентности, но такой код выглядит куда более яснее и понятнее того, что вы привели:

 

{
    V8 *p = 0x00;
    HANDLE h;

    GetExceptionVector( EXPVECT_DABT,  &h);
    SetExceptionVector( EXPVECT_DABT,  DabtDetHandler);

    while ( !DabtHappened )
    {
         p += 1*M;
         *p;
    }

    SetExceptionVector( EXPVECT_DABT, h);
    return (U32)p - 1;
}

Другое дело, что он работоспособен только после настройки EMC как выяснилось. :(

Share this post


Link to post
Share on other sites

Привет всем.

Есть кусок кода:

    ; 
   ; Disable L2 cache
   ;
   ldr     r1, =CSP_BASE_REG_PA_L2CC
   ldr     r0, =0x0
   str     r0, [r1, #L2CC_CR_OFFSET]

 

Как я разумею:

1. "ldr r1, =CSP_BASE_REG_PA_L2CC" - загружает в r1 то, что содержится (а именно константа CSP_BASE_REG_PA_L2CC) в некоем адресе, заданном как смещение относительно PC. Так ?

2. "ldr r0, =0x0" - по аналогии, запись в r0 числа 0. Хотя, путь странноват. Неправильно понимаю ?

3. "str r0, [r1, #L2CC_CR_OFFSET]" - созранить значение из r0 в адрес, заданный как r1+ L2CC_CR_OFFSET. Верно понимаю ?

 

Спасибо.

Share this post


Link to post
Share on other sites

По пунктам 1 и 2: запись "LDR reg, =число" значит загрузить число в регистр. При этом ассемблер сам выбирает реализацию. К примеру, если число - это 0, то он подставит инструкцию "MOV reg, #0". Может поиграть константой и сдвигами, если есть возможность. Иначе загрузит по смещению от PC.

Пункт 3. Верно.

Share this post


Link to post
Share on other sites

Все верно понимаете. Вместо второго ldr логичнее написать mov r0, #0.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this