OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [ao486_tool/] [src/] [ao486/] [module/] [memory/] [test/] [TestTLBRead.java] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
package ao486.module.memory.test;
28
 
29
import ao486.module.memory.AvalonListener;
30
import ao486.module.memory.GlobalListener;
31
import ao486.module.memory.Input;
32
import ao486.module.memory.Listener;
33
import ao486.module.memory.Output;
34
import ao486.module.memory.ReadListener;
35
import ao486.module.memory.Test;
36
import ao486.module.memory.WriteListener;
37
import java.util.HashSet;
38
import java.util.LinkedList;
39
import java.util.Random;
40
 
41
class TestTLBReadState {
42
 
43
    TestTLBReadState(Random random) {
44
        this.random = random;
45
 
46
        do {
47
            cr3_base = random.nextLong();
48
            cr3_base &= 0xFFFFF000L;
49
        } while(Test.address_not_in_cache(cr3_base) || Test.address_not_in_cache(cr3_base + 0x1000L));
50
 
51
        cr3_pwt = true;
52
        cr3_pcd = true;
53
 
54
        linear_set = new HashSet<>();
55
    }
56
 
57
    boolean overlap(long a1, long a2, long b1, long b2) {
58
        if(b2 <= a2 && b2 >= a1) return true;
59
        if(b1 <= a2 && b1 >= a1) return true;
60
        return false;
61
    }
62
 
63
    void prepare(AvalonListener avalon) {
64
 
65
        //pde
66
        do {
67
            pde = random.nextLong();
68
            pde &= 0xFFFFF000L;
69
        } while(Test.address_not_in_cache(pde) || Test.address_not_in_cache(pde + 0x1000L) || overlap(cr3_base, cr3_base+ 0x1000L, pde, pde + 0x1000L));
70
 
71
        pde_pwt     = true;
72
        pde_pcd     = true;
73
        pde_present = true;
74
        pde_rw      = false;
75
        pde_su      = false;
76
        pde_accessed= false;
77
 
78
        //pte
79
        do {
80
            pte = random.nextLong();
81
            pte &= 0xFFFFF000L;
82
        } while(Test.address_not_in_cache(pte) || Test.address_not_in_cache(pte + 0x1000L) ||
83
                overlap(cr3_base, cr3_base+ 0x1000L, pte, pte + 0x1000L) || overlap(pde, pde+ 0x1000L, pte, pte + 0x1000L));
84
 
85
        pte_pwt     = true;
86
        pte_pcd     = true;
87
        pte_present = true;
88
        pte_rw      = false;
89
        pte_su      = false;
90
        pte_accessed= false;
91
        pte_dirty   = false;
92
 
93
        //linear
94
        do {
95
            linear = random.nextLong();
96
            linear &= 0xFFFFFFFFL;
97
        } while(linear_set.contains(linear & 0xFFFFF000L));
98
 
99
        linear_set.add(linear & 0xFFFFF000L);
100
 
101
        linear_pde = (linear >> 22) & 0x3FFL;
102
        linear_pte = (linear >> 12) & 0x3FFL;
103
 
104
        length = (int)(16 - (linear & 0xFL));
105
        if(length > 8) length = 8;
106
        length = 1 + random.nextInt(length);
107
 
108
        physical = pte | (linear & 0xFFFL);
109
 
110
        //----------
111
 
112
        long pde_value = pde;
113
        if(pde_present) pde_value |= 0x1L;
114
        if(pde_rw)      pde_value |= 0x2L;
115
        if(pde_su)      pde_value |= 0x4L;
116
        if(pde_pwt)     pde_value |= 0x8L;
117
        if(pde_pcd)     pde_value |= 0x10L;
118
        if(pde_accessed)pde_value |= 0x20L;
119
 
120
        avalon.set_memory(cr3_base | (linear_pde << 2), pde_value, 4);
121
 
122
        long pte_value = pte;
123
        if(pte_present) pte_value |= 0x1L;
124
        if(pte_rw)      pte_value |= 0x2L;
125
        if(pte_su)      pte_value |= 0x4L;
126
        if(pte_pwt)     pte_value |= 0x8L;
127
        if(pte_pcd)     pte_value |= 0x10L;
128
        if(pte_accessed)pte_value |= 0x20L;
129
        if(pte_dirty)   pte_value |= 0x40L;
130
 
131
        avalon.set_memory(pde | (linear_pte << 2), pte_value, 4);
132
    }
133
 
134
    Random random;
135
 
136
    long cr3_base;
137
    boolean cr3_pwt;
138
    boolean cr3_pcd;
139
 
140
    long pde;
141
    boolean pde_pwt;
142
    boolean pde_pcd;
143
    boolean pde_present;
144
    boolean pde_rw;
145
    boolean pde_su;
146
    boolean pde_accessed;
147
 
148
    long pte;
149
    boolean pte_pwt;
150
    boolean pte_pcd;
151
    boolean pte_present;
152
    boolean pte_rw;
153
    boolean pte_su;
154
    boolean pte_accessed;
155
    boolean pte_dirty;
156
 
157
    long linear;
158
    long linear_pde;
159
    long linear_pte;
160
 
161
    long physical;
162
 
163
    int length;
164
 
165
    HashSet<Long> linear_set;
166
}
167
 
168
public class TestTLBRead extends Test implements Listener, ReadListener.ReadInterface, WriteListener.WriteInterface {
169
 
170
    void go(long seed) throws Exception {
171
        random = new Random(seed);
172
 
173
        avalon = new AvalonListener(random, this);
174
        read   = new ReadListener();
175
        global = new GlobalListener();
176
 
177
        finish_cycle = 0;
178
        counter = 1;
179
 
180
        state = new TestTLBReadState(random);
181
 
182
        global.set(true, false, false, true, true, false, state.cr3_base, state.cr3_pcd, state.cr3_pwt, true, false);
183
 
184
//System.out.printf("addr: %x\n", pde | (linear_pde << 2));
185
 
186
        state.prepare(avalon);
187
 
188
        read.read(4, 0, state.linear, state.length, false, false, this);
189
 
190
        //----------
191
 
192
        LinkedList<Listener> listeners = new LinkedList<>();
193
        listeners.add(avalon);
194
        listeners.add(read);
195
        listeners.add(global);
196
        listeners.add(this);
197
 
198
        run_simulation(listeners);
199
    }
200
    @Override
201
    public void read(int cycle, long data) throws Exception {
202
        //System.out.printf("Read value: %x from linear/physical %x/%x size %d\n", data, state.linear, state.physical, state.length);
203
 
204
        //compare read physical address
205
        if((last_read_address & 0xFFFFF000L) != (state.physical & 0xFFFFF000L)) throw new Exception("Invalid physical read address !");
206
 
207
        //compare read value
208
        for(int i=0; i<state.length; i++) {
209
            long value = avalon.get_memory(state.physical+i);
210
 
211
            if((value & 0xFF) != (data & 0xFF)) throw new Exception(String.format("Value mismatch: data: %x, value: %x, i: %d, physical: %x", data, value, i, state.physical));
212
 
213
            value >>= 8;
214
            data >>= 8;
215
        }
216
 
217
        counter++;
218
 
219
        if(counter >= 1000) {
220
            finish_cycle = cycle+1;
221
            return;
222
        }
223
 
224
        state.prepare(avalon);
225
 
226
        read.read(cycle+1, 0, state.linear, state.length, false, false, this);
227
    }
228
 
229
    @Override
230
    public void read_page_fault(int cycle, long cr2, long error_code) throws Exception {
231
        throw new Exception(String.format("read_page_fault: cr2: %x, error_code: %x", cr2, error_code));
232
    }
233
    @Override
234
    public void read_ac_fault(int cycle) throws Exception {
235
        throw new Exception("read_ac_fault.");
236
    }
237
 
238
    @Override
239
    public void written(int cycle) throws Exception {
240
 
241
    }
242
    @Override
243
    public void write_page_fault(int cycle, long cr2, long error_code) throws Exception {
244
        throw new Exception(String.format("write_page_fault: cr2: %x, error_code: %x", cr2, error_code));
245
    }
246
    @Override
247
    public void write_ac_fault(int cycle) throws Exception {
248
        throw new Exception("write_ac_fault.");
249
    }
250
 
251
 
252
    @Override
253
    public void set_input(int cycle, Input input) throws Exception {
254
        if(cycle >= finish_cycle && finish_cycle > 0) {
255
            input.finished = true;
256
        }
257
    }
258
 
259
    @Override
260
    public void get_output(int cycle, Output output) throws Exception {
261
    }
262
 
263
    @Override
264
    public void avalon_read(int cycle, long read_address) throws Exception {
265
        last_read_address = read_address;
266
    }
267
 
268
    int counter;
269
    Random random;
270
 
271
    int finish_cycle;
272
 
273
    long last_read_address;
274
 
275
    TestTLBReadState state;
276
 
277
    AvalonListener avalon;
278
    ReadListener   read;
279
    GlobalListener global;
280
 
281
    //-------------
282
 
283
    public static void main(String args[]) throws Exception {
284
        TestTLBRead test1 = new TestTLBRead();
285
 
286
        for(int i=0; i<100; i++) {
287
            test1.go(i);
288
 
289
            System.out.println("Run " + i + " complete.");
290
        }
291
 
292
        System.out.println("[Main] thread end.");
293
    }
294
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.