Skip to content

Fix amo offset forgetfulness with write-through caches

Eclipse Webmaster requested to merge github/fork/chaseblock/amo_sc_fix into master

Created by: chaseblock

This fixes an issue relating to non-8-byte-aligned SC operations.

I noticed this issue on an older version of cva6 in use by the openesp project, and from reading the code here, I believe it probably applies to the current version as well. However, I have not managed to get any testbench set up with the master branch here, so I'm not 100% certain. The fix appears to be working fine with the openesp setup that I have, and I would be interested to know whether it helps here also.

The problem is demonstrated with the following example code:

inline int load_reserve(volatile int * ptr) {
        volatile int rc;
        __asm__ volatile (
                "lr.w %0, (%1)\n\t"
                : "=r" (rc)
                : "r" (ptr)
        );

        return rc;
}

inline int store_conditional(volatile int * ptr, int val) {
        volatile int rc;
        __asm__ volatile (
                "sc.w %0, %1, (%2)\n\t"
                : "=r" (rc)
                : "r" (val), "r" (ptr)
        );
        return rc;
}

int main() {
    int data[2];
    int rc;
    rc = store_conditional(&data[0], -1); // Fails (rc = 1), as it should
    rc = store_conditional(&data[1], -1); // rc = 0, which is wrong, as it indicates success
    // However, if you look at data[1], it was never really updated, so this was really a failure
}

Essentially, it appears that the write-through cache just forgets the offset of the return code between sending the message to the backing cache and getting the response. This means that the SC operation always returns a success code when accessing word-sized data that is not 8-byte aligned. The fix is just one line.

Merge request reports

Loading