test/sync/machine.ras 3.1 KiB raw
1
//! Exercise code publication and contended metadata updates on each hart.
2
.constant EXPECTED HARTS * 100;
3
.text;
4
@entry
5
    li %t0 0x1888;
6
    csrw mstatus %t0;
7
    csrr %s7 mstatus;
8
    call @kernel::sync::maskInterrupts;
9
    li %t0 8;
10
    bne %a0 %t0 @fail;
11
    csrr %t0 mstatus;
12
    andi %t1 %s7 -9;
13
    bne %t0 %t1 @fail;
14
    call @kernel::sync::restoreInterrupts;
15
    csrr %t0 mstatus;
16
    bne %t0 %s7 @fail;
17
    li %a0 0;
18
    call @kernel::sync::restoreInterrupts;
19
    csrr %t0 mstatus;
20
    andi %t1 %s7 -9;
21
    bne %t0 %t1 @fail;
22
    call @kernel::sync::retired;
23
    mv %s5 %a0;
24
    call @kernel::sync::retired;
25
    bgeu %s5 %a0 @fail;
26
    csrr %s6 mhartid;
27
    li %s0 0x40010000;
28
    slli %s0 %s0 1;
29
    bnez %s6 @waitCode;
30
    li %t0 1;
31
    slli %t0 %t0 32;
32
    addi %t0 %t0 -4;
33
    sw %t0 0(%s0);
34
    sw %t0 4(%s0);
35
    li %t0 0x02a00513;
36
    sw %t0 64(%s0);
37
    li %t0 0x00008067;
38
    sw %t0 68(%s0);
39
    li %t0 37;
40
    sw %t0 44(%s0);
41
    addi %a0 %s0 40;
42
    li %a1 -1;
43
    call @kernel::sync::storeRelease32;
44
    addi %a0 %s0 24;
45
    li %a1 1;
46
    call @kernel::sync::storeRelease;
47
@waitCode
48
    addi %a0 %s0 24;
49
    call @kernel::sync::loadAcquire;
50
    beqz %a0 @waitCode;
51
    addi %a0 %s0 40;
52
    call @kernel::sync::loadAcquire32;
53
    li %t0 1;
54
    slli %t0 %t0 32;
55
    addi %t0 %t0 -1;
56
    bne %a0 %t0 @fail;
57
    lwu %t0 44(%s0);
58
    li %t1 37;
59
    bne %t0 %t1 @fail;
60
    call @kernel::sync::syncInstructions;
61
    addi %t0 %s0 64;
62
    jalr %ra %t0 0;
63
    li %t0 42;
64
    bne %a0 %t0 @fail;
65
    li %s1 100;
66
@ticket
67
    mv %a0 %s0;
68
    call @kernel::sync::nextTicket;
69
    mv %s2 %a0;
70
    li %t0 100;
71
    bne %s1 %t0 @acquire;
72
    // Every hart holds its first ticket before any hart can enter the lock.
73
    addi %a0 %s0 72;
74
    li %a1 1;
75
    call @kernel::sync::fetchAdd;
76
@queued
77
    addi %a0 %s0 72;
78
    call @kernel::sync::loadAcquire;
79
    li %t0 HARTS;
80
    bne %a0 %t0 @queued;
81
@acquire
82
    addi %a0 %s0 4;
83
    call @kernel::sync::loadAcquire32;
84
    bne %a0 %s2 @acquire;
85
    // The protected count must follow ticket order across the u32 wrap.
86
    addi %t1 %s2 4;
87
    slli %t1 %t1 32;
88
    srli %t1 %t1 32;
89
    ld %t0 8(%s0);
90
    bne %t0 %t1 @fail;
91
    addi %t0 %t0 1;
92
    sd %t0 8(%s0);
93
    addi %a0 %s0 4;
94
    addi %a1 %s2 1;
95
    call @kernel::sync::storeRelease32;
96
    addi %s1 %s1 -1;
97
    bnez %s1 @ticket;
98
    addi %a0 %s0 16;
99
    li %a1 1;
100
    call @kernel::sync::fetchAdd;
101
    addi %a0 %a0 1;
102
    li %t0 HARTS;
103
    beq %a0 %t0 @check;
104
@park
105
    wfi;
106
    j @park;
107
@check
108
    ld %t0 8(%s0);
109
    li %t1 EXPECTED;
110
    bne %t0 %t1 @fail;
111
    lwu %t0 0(%s0);
112
    lwu %t2 4(%s0);
113
    bne %t0 %t2 @fail;
114
    addi %t1 %t1 -4;
115
    bne %t0 %t1 @fail;
116
    addi %t2 %s0 32;
117
    lr.w.aq %t0 (%t2);
118
    bnez %t0 @fail;
119
    li %t1 13;
120
    sc.w.rl %t0 %t1 (%t2);
121
    bnez %t0 @fail;
122
    lr.d.aq %t0 (%t2);
123
    bne %t0 %t1 @fail;
124
    sc.d.rl %t0 %zero (%t2);
125
    bnez %t0 @fail;
126
    li %a0 0x02000000;
127
    call @kernel::sync::read32;
128
    bnez %a0 @fail;
129
    j @success;
130
@fail
131
    li %a0 0x10001000;
132
    li %a1 0x13333;
133
    call @kernel::sync::write32;
134
    ebreak;
135
@success
136
    li %a0 0x10001000;
137
    li %a1 0x5555;
138
    call @kernel::sync::write32;
139
    ebreak;