Bug fix for ARM driver

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
MisterDave
DCEmu Freak
DCEmu Freak
Posts: 58
Joined: Mon Apr 08, 2013 1:16 pm
Has liked: 0
Been liked: 0

Bug fix for ARM driver

Post by MisterDave » Fri May 20, 2016 2:33 pm

When looking at the ARM driver recently I believe that I have identified a bug in the function snd_sh4_to_aica(...) within the file snd_iface.c which is causing incorrect data to be sent from the ARM back to the SH4 through the response queue.

The problem that I found was due to the bottom of the queue's data buffer being miscalculated to be the start of the q_resp aica_queue_t structure rather than just after it (as is the case with the q_cmd queue). The fixed code is below in which I have kept the naming convention of the introduced 'qa' variable as is the case in snd_sh4_to_aica(...)

Hope this of some use.
Dave

Code: Select all

    uint32  bot, start, stop, top, size, cnt, *pkt32;

    sem_wait(&sem_qram);

    /* Set these up for reference */
    bot = SPU_RAM_BASE + AICA_MEM_RESP_QUEUE;
    assert_msg(g2_read_32(bot + offsetof(aica_queue_t, valid)), "Queue is not yet valid");

    top = SPU_RAM_BASE + AICA_MEM_RESP_QUEUE + g2_read_32(bot + offsetof(aica_queue_t, size));
    start = SPU_RAM_BASE + AICA_MEM_RESP_QUEUE + g2_read_32(bot + offsetof(aica_queue_t, tail));
    stop = SPU_RAM_BASE + AICA_MEM_RESP_QUEUE + g2_read_32(bot + offsetof(aica_queue_t, head));
becomes:

Code: Select all

    uint32  qa, bot, start, stop, top, size, cnt, *pkt32;

    sem_wait(&sem_qram);

    /* Set these up for reference */
    qa = SPU_RAM_BASE + AICA_MEM_RESP_QUEUE;
    assert_msg(g2_read_32(qa + offsetof(aica_queue_t, valid)), "Queue is not yet valid");
    
    bot = SPU_RAM_BASE + g2_read_32(qa + offsetof(aica_queue_t, data));
    top = bot + g2_read_32(qa + offsetof(aica_queue_t, size));
    start = bot + g2_read_32(qa + offsetof(aica_queue_t, tail));
    stop = bot + g2_read_32(qa + offsetof(aica_queue_t, head));  

Code: Select all

    if(stop > top)
        stop -= top - (SPU_RAM_BASE + AICA_MEM_RESP_QUEUE);   
becomes:

Code: Select all

    if(stop > top)
        stop -= top - bot;

Code: Select all

    /* Finally, write a new tail value to signify that we've removed a packet */
    g2_write_32(bot + offsetof(aica_queue_t, tail), start - (SPU_RAM_BASE + AICA_MEM_RESP_QUEUE));    
becomes:

Code: Select all

    /* Finally, write a new tail value to signify that we've removed a packet */    
    g2_write_32(qa + offsetof(aica_queue_t, tail), start - bot);    
Post Reply