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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [main_pc.cpp] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
#include <cstdio>
2
#include <cstdlib>
3
 
4
#include <sys/mman.h>
5
#include <sys/types.h>
6
#include <sys/stat.h>
7
#include <fcntl.h>
8
#include <unistd.h>
9
 
10
#include "bochs.h"
11
#include "cpu.h"
12
#include "iodev/iodev.h"
13
 
14
#include "shared_mem.h"
15
 
16
//------------------------------------------------------------------------------
17
//------------------------------------------------------------------------------
18
//------------------------------------------------------------------------------
19
 
20
volatile shared_mem_t *shared_ptr = NULL;
21
 
22
//------------------------------------------------------------------------------
23
//------------------------------------------------------------------------------
24
//------------------------------------------------------------------------------ logfunctions
25
 
26
void logfunctions::panic(const char *fmt, ...) {
27
    printf("#bochs486_pc::logfunctions::panic(): ");
28
 
29
    va_list ap;
30
    va_start(ap, fmt);
31
    vprintf(fmt, ap);
32
    va_end(ap);
33
 
34
    printf("\n");
35
    fflush(stdout);
36
 
37
    if(strstr(fmt, "exception with no resolution") != NULL) {
38
        printf("start_shutdown: 0\n");
39
        printf("\n");
40
        fflush(stdout);
41
        exit(0);
42
    }
43
    else {
44
        exit(-1);
45
    }
46
}
47
void logfunctions::error(const char *fmt, ...) {
48
    printf("#bochs486_pc::logfunctions::error(): ");
49
 
50
    va_list ap;
51
    va_start(ap, fmt);
52
    vprintf(fmt, ap);
53
    va_end(ap);
54
 
55
    printf("\n");
56
    fflush(stdout);
57
}
58
void logfunctions::ldebug(const char *fmt, ...) {
59
    printf("#bochs486_pc::logfunctions::debug(): ");
60
 
61
    va_list ap;
62
    va_start(ap, fmt);
63
    vprintf(fmt, ap);
64
    va_end(ap);
65
 
66
    printf("\n");
67
    fflush(stdout);
68
}
69
void logfunctions::info(const char *fmt, ...) {
70
    printf("#bochs486_pc::logfunctions::info(): ");
71
 
72
    va_list ap;
73
    va_start(ap, fmt);
74
    vprintf(fmt, ap);
75
    va_end(ap);
76
 
77
    printf("\n");
78
    fflush(stdout);
79
}
80
void logfunctions::put(const char *n, const char *p) {
81
}
82
logfunctions::logfunctions() {
83
}
84
logfunctions::~logfunctions() {
85
}
86
 
87
static logfunctions theLog;
88
logfunctions *pluginlog         = &theLog;
89
logfunctions *siminterface_log  = &theLog;
90
 
91
//------------------------------------------------------------------------------
92
//------------------------------------------------------------------------------
93
//------------------------------------------------------------------------------ menu
94
 
95
void bx_param_string_c::text_print(FILE *fp) {
96
printf("#bochs486_pc::bx_param_string_c::text_print()\n");
97
}
98
void bx_param_enum_c::text_print(FILE *fp) {
99
printf("#bochs486_pc::bx_param_enum_c::text_print()\n");
100
}
101
void bx_param_bool_c::text_print(FILE *fp) {
102
printf("#bochs486_pc::bx_param_bool_c::text_print()\n");
103
}
104
void bx_param_num_c::text_print(FILE *fp) {
105
printf("#bochs486_pc::bx_param_num_c::text_print()\n");
106
}
107
void bx_list_c::text_print(FILE *fp) {
108
printf("#bochs486_pc::bx_list_c::text_print()\n");
109
}
110
int bx_param_enum_c::text_ask(FILE *fpin, FILE *fpout) {
111
printf("#bochs486_pc::bx_param_enum_c::text_ask()\n");
112
    return 0;
113
}
114
int bx_param_bool_c::text_ask(FILE *fpin, FILE *fpout) {
115
printf("#bochs486_pc::bx_param_bool_c::text_ask()\n");
116
    return 0;
117
}
118
int bx_param_num_c::text_ask(FILE *fpin, FILE *fpout) {
119
printf("#bochs486_pc::bx_param_num_c::text_ask()\n");
120
    return 0;
121
}
122
int bx_param_string_c::text_ask(FILE *fpin, FILE *fpout) {
123
printf("#bochs486_pc::bx_param_string_c::text_ask()\n");
124
    return 0;
125
}
126
int bx_list_c::text_ask(FILE *fpin, FILE *fpout) {
127
printf("#bochs486_pc::bx_list_c::text_ask()\n");
128
    return 0;
129
}
130
 
131
bx_list_c *root_param = NULL;
132
 
133
bx_gui_c *bx_gui = NULL;
134
 
135
//------------------------------------------------------------------------------
136
//------------------------------------------------------------------------------
137
//------------------------------------------------------------------------------ cpu
138
 
139
void BX_CPU_C::enter_system_management_mode(void) {
140
printf("#bochs486_pc: enter_system_management_mod()\n");
141
}
142
void BX_CPU_C::init_SMRAM(void) {
143
printf("#bochs486_pc: init_SMRAM()\n");
144
}
145
void BX_CPU_C::debug(bx_address offset) {
146
printf("#bochs486_pc: debug(offset=%08x)\n", offset);
147
}
148
void BX_CPU_C::debug_disasm_instruction(bx_address offset) {
149
printf("#bochs486_pc: debug_disasm_instruction(offset=%08x)\n", offset);
150
}
151
 
152
//------------------------------------------------------------------------------
153
//------------------------------------------------------------------------------
154
//------------------------------------------------------------------------------ pc_system
155
 
156
void bx_pc_system_c::countdownEvent(void) {
157
}
158
bx_pc_system_c::bx_pc_system_c() {
159
}
160
int bx_pc_system_c::Reset(unsigned type) {
161
    printf("#bochs486_pc: bx_pc_system_c::Reset(%d) unimplemented.\n", type);
162
    std::exit(-1);
163
}
164
 
165
bx_pc_system_c bx_pc_system;
166
 
167
const char* cpu_mode_string(unsigned cpu_mode) {
168
  static const char *cpu_mode_name[] = {
169
     "real mode",
170
     "v8086 mode",
171
     "protected mode",
172
     "compatibility mode",
173
     "long mode",
174
     "unknown mode"
175
  };
176
 
177
  if(cpu_mode >= 5) cpu_mode = 5;
178
  return cpu_mode_name[cpu_mode];
179
}
180
 
181
const char *choices[] = { "0_choice", NULL };
182
 
183
class bochs486_sim : public bx_simulator_interface_c {
184
 
185
    bx_param_bool_c *get_param_bool(const char *pname, bx_param_c *base) {
186
        if(strcmp(pname, BXPN_CPUID_LIMIT_WINNT) == 0)      return new bx_param_bool_c(  NULL, "b0", "", "", 0);
187
        if(strcmp(pname, BXPN_CPUID_SSE4A) == 0)            return new bx_param_bool_c(  NULL, "b1", "", "", 0);
188
        if(strcmp(pname, BXPN_CPUID_SEP) == 0)              return new bx_param_bool_c(  NULL, "b2", "", "", 0);
189
        if(strcmp(pname, BXPN_CPUID_XSAVE) == 0)            return new bx_param_bool_c(  NULL, "b3", "", "", 0);
190
        if(strcmp(pname, BXPN_CPUID_XSAVEOPT) == 0)         return new bx_param_bool_c(  NULL, "b4", "", "", 0);
191
        if(strcmp(pname, BXPN_CPUID_AES) == 0)              return new bx_param_bool_c(  NULL, "b5", "", "", 0);
192
        if(strcmp(pname, BXPN_CPUID_MOVBE) == 0)            return new bx_param_bool_c(  NULL, "b6", "", "", 0);
193
        if(strcmp(pname, BXPN_CPUID_SMEP) == 0)             return new bx_param_bool_c(  NULL, "b7", "", "", 0);
194
        if(strcmp(pname, BXPN_RESET_ON_TRIPLE_FAULT) == 0)  return new bx_param_bool_c(  NULL, "b8", "", "", 0);
195
        return NULL;
196
    }
197
    bx_param_string_c *get_param_string(const char *pname, bx_param_c *base) {
198
        if(strcmp(pname, BXPN_VENDOR_STRING) == 0) return new bx_param_string_c(NULL, "s0", "", "", "GeniuneAO486");
199
        if(strcmp(pname, BXPN_BRAND_STRING) == 0)  return new bx_param_string_c(NULL, "s1", "", "", "ao486                                           ");
200
        return NULL;
201
    }
202
    bx_param_enum_c *get_param_enum(const char *pname, bx_param_c *base) {
203
        if(strcmp(pname, BXPN_CPU_MODEL) == 0)  return new bx_param_enum_c(  NULL, "e0", "", "", choices, 0);
204
        if(strcmp(pname, BXPN_CPUID_SSE) == 0)  return new bx_param_enum_c(  NULL, "e1", "", "", choices, 0);
205
        return NULL;
206
    }
207
    bx_param_num_c *get_param_num(const char *pname, bx_param_c *base) {
208
        if(strcmp(pname, BXPN_CPUID_STEPPING) == 0)  return new bx_param_num_c(   NULL, "n0", "", "", 0xB,0xB,0xB);
209
        if(strcmp(pname, BXPN_CPUID_MODEL) == 0)     return new bx_param_num_c(   NULL, "n1", "", "", 0x5,0x5,0x5);
210
        if(strcmp(pname, BXPN_CPUID_FAMILY) == 0)    return new bx_param_num_c(   NULL, "n2", "", "", 0x4,0x4,0x4);
211
        if(strcmp(pname, BXPN_CPUID_LEVEL) == 0)     return new bx_param_num_c(   NULL, "n3", "", "", 0x4,0x4,0x4);
212
        return NULL;
213
    }
214
};
215
 
216
bx_simulator_interface_c *SIM;
217
 
218
BOCHSAPI BX_CPU_C bx_cpu;
219
int interrupt_vector;
220
 
221
//------------------------------------------------------------------------------
222
//------------------------------------------------------------------------------
223
//------------------------------------------------------------------------------ devices
224
 
225
class bochs486_pic : public bx_pic_stub_c {
226
    Bit8u IAC(void) { bx_cpu.clear_INTR(); return interrupt_vector & 0xFF; }
227
 
228
};
229
 
230
int is_io_ignored(Bit16u address, Bit32u byteena) {
231
 
232
    bool read_ff =
233
            (address >= 0x0010 && address < 0x0020)     ||
234
            (address == 0x0020 && (byteena & 0x3) == 0) ||
235
            (address >= 0x0024 &&  address < 0x0040)    ||
236
            (address >= 0x0044 &&  address < 0x0060)    ||
237
            (address >= 0x0068 &&  address < 0x0070)    ||
238
            (address == 0x0070 && (byteena & 0x3) == 0) ||
239
            (address >= 0x0074 &&  address < 0x0080)    ||
240
            (address == 0x00A0 && (byteena & 0x3) == 0) ||
241
            (address >= 0x00A4 &&  address < 0x00C0)    ||
242
            (address >= 0x00E0 &&  address < 0x01F0)    ||
243
            (address >= 0x01F8 &&  address < 0x0220)    ||
244
            (address >= 0x0230 &&  address < 0x0388)    ||
245
            (address == 0x0388 && (byteena & 0x3) == 0) ||
246
            (address >= 0x038C &&  address < 0x03B0)    ||
247
            (address >= 0x03E0 &&  address < 0x03F0)    ||
248
            (address >= 0x03F8 &&  address < 0x8888)    ||
249
            (address >= 0x8890);
250
 
251
    bool read_ff_part =
252
            (address == 0x0020) ||
253
            (address == 0x0070) ||
254
            (address == 0x00A0) ||
255
            (address == 0x0388);
256
 
257
    if(read_ff)         return 1;
258
    if(read_ff_part)    return 2;
259
    return 0;
260
}
261
 
262
  Bit32u BX_CPP_AttrRegparmN(2)
263
bx_devices_c::inp(Bit16u addr, unsigned io_len) {
264
//printf("#bochs486_pc:inp(%04x, %d)\n", addr, io_len);
265
    // read aligned to 4 bytes, with byteena
266
 
267
    bool two_reads = (addr & 0x3) + io_len > 4;
268
 
269
    Bit16u   addr1    = addr & 0xFFFC;
270
    unsigned byteena1 = (io_len == 1)? 0x1 : (io_len == 2)? 0x3 : (io_len == 3)? 0x7 : 0xF;
271
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
272
 
273
    Bit16u   addr2    = (addr + 4) & 0xFFFC;
274
    unsigned byteena2 = (byteena1 >> 4) & 0xF;
275
 
276
    //-------------------------------------------------------------------------- first read
277
    int int_ret = is_io_ignored(addr1, byteena1 & 0xF);
278
    unsigned int data1 = 0xFFFFFFFF;
279
 
280
    if(int_ret == 0 || int_ret == 2) {
281
        shared_ptr->bochs486_pc.io_address    = addr1;
282
        shared_ptr->bochs486_pc.io_byteenable = byteena1 & 0xF;
283
        shared_ptr->bochs486_pc.io_is_write   = 0;
284
        shared_ptr->bochs486_pc.io_step       = STEP_REQ;
285
        while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
286
            fflush(stdout);
287
            usleep(10);
288
        }
289
        data1 = ((int_ret == 2)? 0xFFFF0000 : 0x00000000) | shared_ptr->bochs486_pc.io_data;
290
 
291
        FILE *fp = fopen("track.txt", "a");
292
        fprintf(fp, "io rd %04x %x %08x\n", addr1, byteena1 & 0xF, data1);
293
        fclose(fp);
294
 
295
        shared_ptr->bochs486_pc.io_step = STEP_IDLE;
296
    }
297
    //-------------------------------------------------------------------------- second read
298
    unsigned long long data = data1;
299
//printf("#bochs486_pc:inp() read_one %d\n", two_reads);
300
    if(two_reads) {
301
        int_ret = is_io_ignored(addr2, byteena2 & 0xF);
302
        unsigned int data2 = 0xFFFFFFFF;
303
 
304
        if(int_ret == 0 || int_ret == 2) {
305
            shared_ptr->bochs486_pc.io_address    = addr2;
306
            shared_ptr->bochs486_pc.io_byteenable = byteena2 & 0xF;
307
            shared_ptr->bochs486_pc.io_is_write   = 0;
308
            shared_ptr->bochs486_pc.io_step       = STEP_REQ;
309
            while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
310
                fflush(stdout);
311
                usleep(10);
312
            }
313
            data2 = ((int_ret == 2)? 0xFFFF0000 : 0x00000000) | shared_ptr->bochs486_pc.io_data;
314
 
315
            FILE *fp = fopen("track.txt", "a");
316
            fprintf(fp, "io rd %04x %x %08x\n", addr2, byteena2 & 0xF, data2);
317
            fclose(fp);
318
 
319
            shared_ptr->bochs486_pc.io_step = STEP_IDLE;
320
        }
321
 
322
        data = ((unsigned long long)data2 << 32) | data1;
323
    }
324
 
325
    while((byteena1 & 1) == 0) {
326
        byteena1 >>= 1;
327
        data >>= 8;
328
    }
329
    Bit32u ret_val = (io_len == 1)? (data & 0xFFL) : (io_len == 2)? (data & 0xFFFFL) : (io_len == 3)? (data & 0xFFFFFFL) : (data & 0xFFFFFFFFL);
330
printf("#bochs486_pc:inp(%04x, %d, =%08x)\n", addr, io_len, ret_val);
331
    return ret_val;
332
}
333
 
334
  void BX_CPP_AttrRegparmN(3)
335
bx_devices_c::outp(Bit16u addr, Bit32u value, unsigned io_len) {
336
printf("#bochs486_pc:outp(%04x, %d, %08x)\n", addr, io_len, value);
337
    // write aligned to 4 bytes, with byteena
338
 
339
    bool two_writes = (addr & 0x3) + io_len > 4;
340
 
341
    Bit16u   addr1    = addr & 0xFFFC;
342
    unsigned byteena1 = (io_len == 1)? 0x1 : (io_len == 2)? 0x3 : (io_len == 3)? 0x7 : 0xF;
343
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
344
 
345
    Bit16u   addr2    = (addr + 4) & 0xFFFC;
346
    unsigned byteena2 = (byteena1 >> 4) & 0xF;
347
 
348
    if(io_len == 1) value &= 0x000000FF;
349
    if(io_len == 2) value &= 0x0000FFFF;
350
    if(io_len == 3) value &= 0x00FFFFFF;
351
 
352
    Bit64u value_full = ((addr & 0x3) == 0)? (Bit64u)value : ((addr & 0x3) == 1)? ((Bit64u)value << 8) : ((addr & 0x3) == 2)? ((Bit64u)value << 16) : ((Bit64u)value << 24);
353
    Bit32u value1 = value_full;
354
    Bit32u value2   = (value_full >> 32);
355
 
356
    //-------------------------------------------------------------------------- first write
357
    int int_ret = is_io_ignored(addr1, byteena1 & 0xF);
358
 
359
    if(int_ret == 0 || int_ret == 2) {
360
        shared_ptr->bochs486_pc.io_address    = addr1;
361
        shared_ptr->bochs486_pc.io_byteenable = byteena1 & 0xF;
362
        shared_ptr->bochs486_pc.io_is_write   = 1;
363
        shared_ptr->bochs486_pc.io_data       = value1;
364
        shared_ptr->bochs486_pc.io_step       = STEP_REQ;
365
        while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
366
            fflush(stdout);
367
            usleep(10);
368
        }
369
 
370
        FILE *fp = fopen("track.txt", "a");
371
        fprintf(fp, "io wr %04x %x %08x\n", addr1, byteena1 & 0xF, value1);
372
        fclose(fp);
373
 
374
        shared_ptr->bochs486_pc.io_step = STEP_IDLE;
375
    }
376
//printf("#bochs486_pc:outp() write_one %d\n", two_writes);
377
    //-------------------------------------------------------------------------- second write
378
 
379
    if(two_writes) {
380
        int_ret = is_io_ignored(addr2, byteena2 & 0xF);
381
 
382
        if(int_ret == 0 || int_ret == 2) {
383
            shared_ptr->bochs486_pc.io_address    = addr2;
384
            shared_ptr->bochs486_pc.io_byteenable = byteena2 & 0xF;
385
            shared_ptr->bochs486_pc.io_is_write   = 1;
386
            shared_ptr->bochs486_pc.io_data       = value2;
387
            shared_ptr->bochs486_pc.io_step       = STEP_REQ;
388
            while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
389
                fflush(stdout);
390
                usleep(10);
391
            }
392
 
393
            FILE *fp = fopen("track.txt", "a");
394
            fprintf(fp, "io wr %04x %x %08x\n", addr2, byteena2 & 0xF, value2);
395
            fclose(fp);
396
 
397
            shared_ptr->bochs486_pc.io_step = STEP_IDLE;
398
        }
399
    }
400
//printf("#bochs486_pc:outp() write_two\n");
401
}
402
 
403
bx_devices_c::bx_devices_c() {
404
    pluginPicDevice = new bochs486_pic();
405
}
406
 
407
bx_devices_c::~bx_devices_c() {
408
}
409
 
410
bx_devices_c bx_devices;
411
 
412
//------------------------------------------------------------------------------
413
//------------------------------------------------------------------------------
414
//------------------------------------------------------------------------------ memory
415
 
416
void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, void *data) {
417
printf("#bochs486_pc: writePhysicalPage: addr=%08x, len=%d ", addr, len);
418
for(unsigned i=0; i<len; i++) printf("%02x ", ((uint8 *)data)[i]); printf("\n");
419
 
420
    addr &= 0x07FFFFFF;
421
 
422
    if(len > 4) {
423
        printf("#bochs486_pc: writePhysicalPage() with len = %d\n", len);
424
        exit(-1);
425
    }
426
 
427
    bool two_writes = (addr & 0x3) + len > 4;
428
 
429
    Bit32u   addr1    = addr & 0xFFFFFFFC;
430
    unsigned byteena1 = (len == 1)? 0x1 : (len == 2)? 0x3 : (len == 3)? 0x7 : 0xF;
431
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
432
 
433
    Bit32u   addr2    = (addr + 4) & 0xFFFFFFFC;
434
    unsigned byteena2 = (byteena1 >> 4) & 0xF;
435
 
436
    Bit32u value = ((unsigned int *)data)[0];
437
    if(len == 1) value &= 0x000000FF;
438
    if(len == 2) value &= 0x0000FFFF;
439
    if(len == 3) value &= 0x00FFFFFF;
440
 
441
    Bit64u value_full = ((addr & 0x3) == 0)? (Bit64u)value : ((addr & 0x3) == 1)? ((Bit64u)value << 8) : ((addr & 0x3) == 2)? ((Bit64u)value << 16) : ((Bit64u)value << 24);
442
    Bit32u value1 = value_full;
443
    Bit32u value2   = (value_full >> 32);
444
 
445
    //-------------------------------------------------------------------------- first write
446
    shared_ptr->bochs486_pc.mem_address    = addr1;
447
    shared_ptr->bochs486_pc.mem_byteenable = byteena1 & 0xF;
448
    shared_ptr->bochs486_pc.mem_is_write   = 1;
449
    shared_ptr->bochs486_pc.mem_data       = value1;
450
    shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
451
    while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
452
        fflush(stdout);
453
        usleep(10);
454
    }
455
 
456
    FILE *fp = fopen("track.txt", "a");
457
    fprintf(fp, "mem wr %08x %x %08x\n", addr1, byteena1 & 0xF, value1);
458
    fclose(fp);
459
 
460
    shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
461
 
462
//printf("#bochs486_pc: writePhysicalPage: write_one, %d\n", two_writes);
463
    if(two_writes) {
464
        //---------------------------------------------------------------------- second write
465
        shared_ptr->bochs486_pc.mem_address    = addr2;
466
        shared_ptr->bochs486_pc.mem_byteenable = byteena2 & 0xF;
467
        shared_ptr->bochs486_pc.mem_is_write   = 1;
468
        shared_ptr->bochs486_pc.mem_data       = value2;
469
        shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
470
        while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
471
            fflush(stdout);
472
            usleep(10);
473
        }
474
 
475
        FILE *fp = fopen("track.txt", "a");
476
        fprintf(fp, "mem wr %08x %x %08x\n", addr2, byteena2 & 0xF, value2);
477
        fclose(fp);
478
 
479
        shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
480
    }
481
//printf("#bochs486_pc: writePhysicalPage: write_two\n");
482
}
483
 
484
void BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, void *data) {
485
printf("#bochs486_pc: readPhysicalPage: addr=%08x, len=%d\n", addr, len);
486
 
487
        if(addr >= 0xFFFFF000) addr &= 0x000FFFFF;
488
        addr &= 0x07FFFFFF;
489
 
490
    if(len == 4096) {
491
        if((addr & 3) != 0) {
492
            printf("#bochs486_pc: readPhysicalPage() with len = 4096 and addr not aligned to 4.\n");
493
            exit(-1);
494
        }
495
 
496
        if(addr >= 0xA0000 && addr <= 0xBFFFF) {
497
            printf("#bochs486_pc: readPhysicalPage() with len = 4096 and addr in vga buffer.\n");
498
            fflush(stdout); while(1) { ; }
499
            exit(-1);
500
        }
501
 
502
        memcpy((unsigned char *)data, (void *)(shared_ptr->mem.bytes + addr), len);
503
        return;
504
    }
505
 
506
    //check if read crosses line boundry (16 bytes)
507
    if( ((addr) & 0xFFFFFFF0) != ((addr + len - 1) & 0xFFFFFFF0) ) {
508
        unsigned char *ptr = (unsigned char*)data;
509
        readPhysicalPage(cpu, addr,             (addr | 0xF) - addr + 1,       ptr);
510
        readPhysicalPage(cpu, (addr | 0xF) + 1, len - (addr | 0xF) + addr - 1, ptr + ((addr | 0xF) - addr + 1));
511
        return;
512
    }
513
 
514
    if(addr < 0xA0000 || addr > 0xBFFFF) {
515
        memcpy((unsigned char *)data, (void *)(shared_ptr->mem.bytes + addr), len);
516
        return;
517
    }
518
//printf("#bochs486_pc: readPhysicalPage: vga read.\n");    
519
    bool two_reads   = ((addr & 0x3) + len > 4) && ((addr & 0x3) + len <= 8);
520
    bool three_reads = ((addr & 0x3) + len > 8);
521
 
522
    Bit32u   addr1    = addr & 0xFFFFFFFC;
523
    unsigned byteena1 = (len == 1)? 0x1 : (len == 2)? 0x3 : (len == 3)? 0x7 : 0xF;
524
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
525
 
526
    Bit32u   addr2    = (addr + 4) & 0xFFFFFFFC;
527
    Bit32u   addr3    = (addr + 8) & 0xFFFFFFFC;
528
 
529
    if(two_reads || three_reads) byteena1 = 0xF;
530
    byteena1 &= 0xF;
531
 
532
    //-------------------------------------------------------------------------- first read
533
    unsigned int data_read[3] = { 0,0,0 };
534
 
535
    shared_ptr->bochs486_pc.mem_address    = addr1;
536
    shared_ptr->bochs486_pc.mem_byteenable = byteena1 & 0xF;
537
    shared_ptr->bochs486_pc.mem_is_write   = 0;
538
    shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
539
    while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
540
        fflush(stdout);
541
        usleep(10);
542
    }
543
    data_read[0] = shared_ptr->bochs486_pc.mem_data;
544
 
545
    FILE *fp = fopen("track.txt", "a");
546
    fprintf(fp, "mem rd %08x %x %08x\n", addr1, byteena1 & 0xF, data_read[0]);
547
    fclose(fp);
548
 
549
    shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
550
 
551
    if(two_reads || three_reads) {
552
        //---------------------------------------------------------------------- second read
553
        shared_ptr->bochs486_pc.mem_address    = addr2;
554
        shared_ptr->bochs486_pc.mem_byteenable = 0xF;
555
        shared_ptr->bochs486_pc.mem_is_write   = 0;
556
        shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
557
        while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
558
            fflush(stdout);
559
            usleep(10);
560
        }
561
        data_read[1] = shared_ptr->bochs486_pc.mem_data;
562
 
563
        FILE *fp = fopen("track.txt", "a");
564
        fprintf(fp, "mem rd %08x %x %08x\n", addr2, 0xF, data_read[1]);
565
        fclose(fp);
566
 
567
        shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
568
 
569
        if(three_reads) {
570
            //------------------------------------------------------------------ third read
571
            shared_ptr->bochs486_pc.mem_address    = addr3;
572
            shared_ptr->bochs486_pc.mem_byteenable = 0xF;
573
            shared_ptr->bochs486_pc.mem_is_write   = 0;
574
            shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
575
            while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
576
                fflush(stdout);
577
                usleep(10);
578
            }
579
            data_read[2] = shared_ptr->bochs486_pc.mem_data;
580
 
581
            FILE *fp = fopen("track.txt", "a");
582
            fprintf(fp, "mem rd %08x %x %08x\n", addr3, 0xF, data_read[2]);
583
            fclose(fp);
584
 
585
            shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
586
        }
587
    }
588
 
589
    unsigned char *ptr = (unsigned char *)data_read;
590
 
591
    for(int i=0; i<(addr & 0x3); i++) ptr++;
592
 
593
    memcpy((unsigned char *)data, ptr, len);
594
}
595
 
596
Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw) {
597
//printf("#bochs486_pc: getHostMemAddr: addr=%08x, rw=%d\n", addr, rw);
598
 
599
    if(addr >= 0xA0000 && addr < 0xC0000) return NULL;
600
    if(rw != BX_EXECUTE) return NULL;
601
 
602
    if(addr >= 0xFFFFF000) addr &= 0x000FFFFF;
603
    addr &= 0x07FFFFFF;
604
 
605
    return (Bit8u *)(shared_ptr->mem.bytes + addr);
606
}
607
BX_MEM_C::BX_MEM_C() {
608
}
609
BX_MEM_C::~BX_MEM_C() {
610
}
611
 
612
BOCHSAPI BX_MEM_C bx_mem;
613
 
614
//------------------------------------------------------------------------------
615
//------------------------------------------------------------------------------
616
//------------------------------------------------------------------------------ interrupt
617
 
618
void print_segment(bx_segment_reg_t *seg, const char *prefix) {
619
 
620
    printf("%s: %04x ",    prefix, seg->selector.value);
621
    printf("val: %01x ",   seg->cache.valid & 1);
622
    printf("rpl: %01hhx ", seg->selector.rpl);
623
    printf("base: %08x ",  seg->cache.u.segment.base);
624
    printf("limit: %08x ", (seg->cache.u.segment.g)? seg->cache.u.segment.limit_scaled >> 12 : seg->cache.u.segment.limit_scaled);
625
    printf("g: %01x ",     seg->cache.u.segment.g);
626
    printf("d_b: %01x ",   seg->cache.u.segment.d_b);
627
    printf("avl: %01x ",   seg->cache.u.segment.avl);
628
    printf("p: %01x ",     seg->cache.p);
629
    printf("dpl: %01x ",   seg->cache.dpl);
630
    printf("s: %01x ",     seg->cache.segment);
631
    printf("type: %01x\n", seg->cache.type);
632
}
633
 
634
void output_cpu_state() {
635
    printf("eax: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EAX));
636
    printf("ebx: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EBX));
637
    printf("ecx: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_ECX));
638
    printf("edx: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EDX));
639
    printf("esi: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_ESI));
640
    printf("edi: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EDI));
641
    printf("ebp: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EBP));
642
    printf("esp: %08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ESP));
643
 
644
    printf("eip: %08x\n", bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx);
645
 
646
    printf("cflag:  %01x ", bx_cpu.getB_CF());
647
    printf("pflag:  %01x ", bx_cpu.getB_PF());
648
    printf("aflag:  %01x ", bx_cpu.getB_AF());
649
    printf("zflag:  %01x ", bx_cpu.getB_ZF());
650
    printf("sflag:  %01x ", bx_cpu.getB_SF());
651
    printf("tflag:  %01x ", bx_cpu.getB_TF()&1);
652
    printf("iflag:  %01x ", bx_cpu.getB_IF()&1);
653
    printf("dflag:  %01x ", bx_cpu.getB_DF()&1);
654
    printf("oflag:  %01x ", bx_cpu.getB_OF()&1);
655
    printf("iopl:   %01x ", bx_cpu.get_IOPL()&3);
656
    printf("ntflag: %01x ", bx_cpu.getB_NT()&1);
657
    printf("rflag:  %01x ", bx_cpu.getB_RF()&1);
658
    printf("vmflag: %01x ", bx_cpu.getB_VM()&1);
659
    printf("acflag: %01x ", bx_cpu.getB_AC()&1);
660
    printf("idflag: %01x\n", bx_cpu.getB_ID()&1);
661
 
662
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_CS]), "cs");
663
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_DS]), "ds");
664
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_ES]), "es");
665
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_FS]), "fs");
666
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_GS]), "gs");
667
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_SS]), "ss");
668
    print_segment(&(bx_cpu.ldtr), "ldtr");
669
    print_segment(&(bx_cpu.tr),   "tr");
670
 
671
    printf("gdtr_base:  %08x ", bx_cpu.gdtr.base);
672
    printf("gdtr_limit: %02x\n", bx_cpu.gdtr.limit & 0xFFFF);
673
 
674
    printf("idtr_base:  %08x ", bx_cpu.idtr.base);
675
    printf("idtr_limit: %02x\n", bx_cpu.idtr.limit & 0xFFFF);
676
 
677
    printf("cr0_pe: %01x ", bx_cpu.cr0.get_PE() & 1);
678
    printf("cr0_mp: %01x ", bx_cpu.cr0.get_MP() & 1);
679
    printf("cr0_em: %01x ", bx_cpu.cr0.get_EM() & 1);
680
    printf("cr0_ts: %01x ", bx_cpu.cr0.get_TS() & 1);
681
    printf("cr0_ne: %01x ", bx_cpu.cr0.get_NE() & 1);
682
    printf("cr0_wp: %01x ", bx_cpu.cr0.get_WP() & 1);
683
    printf("cr0_am: %01x ", bx_cpu.cr0.get_AM() & 1);
684
    printf("cr0_nw: %01x ", bx_cpu.cr0.get_NW() & 1);
685
    printf("cr0_cd: %01x ", bx_cpu.cr0.get_CD() & 1);
686
    printf("cr0_pg: %01x\n", bx_cpu.cr0.get_PG() & 1);
687
 
688
    printf("cr2: %08x ", bx_cpu.cr2);
689
    printf("cr3: %08x\n", bx_cpu.cr3);
690
 
691
    printf("dr0: %08x ", bx_cpu.dr[0]);
692
    printf("dr1: %08x ", bx_cpu.dr[1]);
693
    printf("dr2: %08x ", bx_cpu.dr[2]);
694
    printf("dr3: %08x ", bx_cpu.dr[3]);
695
 
696
    printf("dr6: %08x ", bx_cpu.dr6.val32);
697
    printf("dr7: %08x\n", bx_cpu.dr7.val32);
698
 
699
    fflush(stdout);
700
}
701
 
702
uint32 seg_word_1(bx_segment_reg_t *seg) {
703
    return  (seg->cache.u.segment.base & 0xFF000000) |
704
            (seg->cache.u.segment.g?   0x00800000 : 0x00) |
705
            (seg->cache.u.segment.d_b? 0x00400000 : 0x00) |
706
            (seg->cache.u.segment.avl? 0x00100000 : 0x00) |
707
            (((seg->cache.u.segment.limit_scaled >> (seg->cache.u.segment.g? 12 : 0)) << 16) & 0xF) |
708
            (seg->cache.p?   0x00008000 : 0x0) |
709
            ((seg->cache.dpl & 0x3) << 13) |
710
            ((seg->cache.segment & 0x1) << 12) |
711
            ((seg->cache.type & 0xF) << 8) |
712
            ((seg->cache.u.segment.base >> 16) & 0xFF);
713
}
714
 
715
uint32 seg_word_2(bx_segment_reg_t *seg) {
716
    return ((seg->cache.u.segment.base & 0xFFFF) << 16) |
717
           ((seg->cache.u.segment.limit_scaled >> (seg->cache.u.segment.g? 12 : 0)) & 0xFFFF);
718
}
719
 
720
void output_for_verilator() {
721
 
722
    FILE *fp = fopen("./../rtl/ao486/startup_from_sim.v", "wb");
723
 
724
    fprintf(fp, "`define STARTUP_EAX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EAX));
725
    fprintf(fp, "`define STARTUP_EBX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EBX));
726
    fprintf(fp, "`define STARTUP_ECX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ECX));
727
    fprintf(fp, "`define STARTUP_EDX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EDX));
728
    fprintf(fp, "`define STARTUP_EBP   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EBP));
729
    fprintf(fp, "`define STARTUP_ESP   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ESP));
730
    fprintf(fp, "`define STARTUP_ESI   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ESI));
731
    fprintf(fp, "`define STARTUP_EDI   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EDI));
732
 
733
    fprintf(fp, "`define STARTUP_CR0_PE 1'b%d\n", bx_cpu.cr0.get_PE() & 1);
734
    fprintf(fp, "`define STARTUP_CR0_MP 1'b%d\n", bx_cpu.cr0.get_MP() & 1);
735
    fprintf(fp, "`define STARTUP_CR0_EM 1'b%d\n", bx_cpu.cr0.get_EM() & 1);
736
    fprintf(fp, "`define STARTUP_CR0_TS 1'b%d\n", bx_cpu.cr0.get_TS() & 1);
737
    fprintf(fp, "`define STARTUP_CR0_NE 1'b%d\n", bx_cpu.cr0.get_NE() & 1);
738
    fprintf(fp, "`define STARTUP_CR0_WP 1'b%d\n", bx_cpu.cr0.get_WP() & 1);
739
    fprintf(fp, "`define STARTUP_CR0_AM 1'b%d\n", bx_cpu.cr0.get_AM() & 1);
740
    fprintf(fp, "`define STARTUP_CR0_NW 1'b%d\n", bx_cpu.cr0.get_NW() & 1);
741
    fprintf(fp, "`define STARTUP_CR0_CD 1'b%d\n", bx_cpu.cr0.get_CD() & 1);
742
    fprintf(fp, "`define STARTUP_CR0_PG 1'b%d\n", bx_cpu.cr0.get_PG() & 1);
743
 
744
    fprintf(fp, "`define STARTUP_CR2 32'h%08x\n", bx_cpu.cr2);
745
    fprintf(fp, "`define STARTUP_CR3 32'h%08x\n", bx_cpu.cr3);
746
 
747
    fprintf(fp, "`define STARTUP_CFLAG  1'b%d\n", bx_cpu.getB_CF());
748
    fprintf(fp, "`define STARTUP_PFLAG  1'b%d\n", bx_cpu.getB_PF());
749
    fprintf(fp, "`define STARTUP_AFLAG  1'b%d\n", bx_cpu.getB_AF());
750
    fprintf(fp, "`define STARTUP_ZFLAG  1'b%d\n", bx_cpu.getB_ZF());
751
    fprintf(fp, "`define STARTUP_SFLAG  1'b%d\n", bx_cpu.getB_SF());
752
    fprintf(fp, "`define STARTUP_OFLAG  1'b%d\n", bx_cpu.getB_OF()&1);
753
    fprintf(fp, "`define STARTUP_TFLAG  1'b%d\n", bx_cpu.getB_TF()&1);
754
    fprintf(fp, "`define STARTUP_IFLAG  1'b%d\n", bx_cpu.getB_IF()&1);
755
    fprintf(fp, "`define STARTUP_DFLAG  1'b%d\n", bx_cpu.getB_DF()&1);
756
    fprintf(fp, "`define STARTUP_IOPL   2'd%d\n", bx_cpu.get_IOPL()&3);
757
    fprintf(fp, "`define STARTUP_NTFLAG 1'b%d\n", bx_cpu.getB_NT()&1);
758
    fprintf(fp, "`define STARTUP_VMFLAG 1'b%d\n", bx_cpu.getB_VM()&1);
759
    fprintf(fp, "`define STARTUP_ACFLAG 1'b%d\n", bx_cpu.getB_AC()&1);
760
    fprintf(fp, "`define STARTUP_IDFLAG 1'b%d\n", bx_cpu.getB_ID()&1);
761
    fprintf(fp, "`define STARTUP_RFLAG  1'b%d\n", bx_cpu.getB_RF()&1);
762
 
763
    fprintf(fp, "`define STARTUP_GDTR_BASE  32'h%08x\n", bx_cpu.gdtr.base);
764
    fprintf(fp, "`define STARTUP_GDTR_LIMIT 16'h%04x\n", bx_cpu.gdtr.limit & 0xFFFF);
765
 
766
    fprintf(fp, "`define STARTUP_IDTR_BASE  32'h%08x\n", bx_cpu.idtr.base);
767
    fprintf(fp, "`define STARTUP_IDTR_LIMIT 16'h%04x\n", bx_cpu.idtr.limit & 0xFFFF);
768
 
769
    fprintf(fp, "`define STARTUP_DR0 32'h%08x\n", bx_cpu.dr[0]);
770
    fprintf(fp, "`define STARTUP_DR1 32'h%08x\n", bx_cpu.dr[1]);
771
    fprintf(fp, "`define STARTUP_DR2 32'h%08x\n", bx_cpu.dr[2]);
772
    fprintf(fp, "`define STARTUP_DR3 32'h%08x\n", bx_cpu.dr[3]);
773
 
774
    fprintf(fp, "`define STARTUP_DR6_BREAKPOINTS 4'h%01x\n", bx_cpu.dr6.val32 & 0xF);
775
    fprintf(fp, "`define STARTUP_DR6_B12         1'b%01x\n", (bx_cpu.dr6.val32 >> 12) & 0x1);
776
    fprintf(fp, "`define STARTUP_DR6_BD          1'b%01x\n", (bx_cpu.dr6.val32 >> 13) & 0x1);
777
    fprintf(fp, "`define STARTUP_DR6_BS          1'b%01x\n", (bx_cpu.dr6.val32 >> 14) & 0x1);
778
    fprintf(fp, "`define STARTUP_DR6_BT          1'b%01x\n", (bx_cpu.dr6.val32 >> 15) & 0x1);
779
    fprintf(fp, "`define STARTUP_DR7            32'h%08x\n", bx_cpu.dr7.val32);
780
 
781
    fprintf(fp, "`define STARTUP_ES   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_ES].selector.value);
782
    fprintf(fp, "`define STARTUP_DS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_DS].selector.value);
783
    fprintf(fp, "`define STARTUP_SS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_SS].selector.value);
784
    fprintf(fp, "`define STARTUP_FS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_FS].selector.value);
785
    fprintf(fp, "`define STARTUP_GS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_GS].selector.value);
786
    fprintf(fp, "`define STARTUP_CS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_CS].selector.value);
787
    fprintf(fp, "`define STARTUP_LDTR 16'h%04x\n", bx_cpu.ldtr.selector.value);
788
    fprintf(fp, "`define STARTUP_TR   16'h%04x\n", bx_cpu.tr.selector.value);
789
 
790
    fprintf(fp, "`define STARTUP_ES_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_ES].selector.rpl);
791
    fprintf(fp, "`define STARTUP_DS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_DS].selector.rpl);
792
    fprintf(fp, "`define STARTUP_SS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_SS].selector.rpl);
793
    fprintf(fp, "`define STARTUP_FS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_FS].selector.rpl);
794
    fprintf(fp, "`define STARTUP_GS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_GS].selector.rpl);
795
    fprintf(fp, "`define STARTUP_CS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl);
796
    fprintf(fp, "`define STARTUP_LDTR_RPL 2'd%d\n", bx_cpu.ldtr.selector.rpl);
797
    fprintf(fp, "`define STARTUP_TR_RPL   2'd%d\n", bx_cpu.tr.selector.rpl);
798
 
799
    fprintf(fp, "`define STARTUP_ES_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.sregs[BX_SEG_REG_ES])), seg_word_2(&(bx_cpu.sregs[BX_SEG_REG_ES])));
800
    fprintf(fp, "`define STARTUP_DS_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.sregs[BX_SEG_REG_DS])), seg_word_2(&(bx_cpu.sregs[BX_SEG_REG_DS])));
801
    fprintf(fp, "`define STARTUP_SS_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.sregs[BX_SEG_REG_SS])), seg_word_2(&(bx_cpu.sregs[BX_SEG_REG_SS])));
802
    fprintf(fp, "`define STARTUP_FS_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.sregs[BX_SEG_REG_FS])), seg_word_2(&(bx_cpu.sregs[BX_SEG_REG_FS])));
803
    fprintf(fp, "`define STARTUP_GS_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.sregs[BX_SEG_REG_GS])), seg_word_2(&(bx_cpu.sregs[BX_SEG_REG_GS])));
804
    fprintf(fp, "`define STARTUP_CS_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.sregs[BX_SEG_REG_CS])), seg_word_2(&(bx_cpu.sregs[BX_SEG_REG_CS])));
805
    fprintf(fp, "`define STARTUP_LDTR_CACHE 64'h%08x%08x\n", seg_word_1(&(bx_cpu.ldtr)),                 seg_word_2(&(bx_cpu.ldtr)));
806
    fprintf(fp, "`define STARTUP_TR_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.tr)),                   seg_word_2(&(bx_cpu.tr)));
807
 
808
    fprintf(fp, "`define STARTUP_ES_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_ES].cache.valid & 1);
809
    fprintf(fp, "`define STARTUP_DS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_DS].cache.valid & 1);
810
    fprintf(fp, "`define STARTUP_SS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_SS].cache.valid & 1);
811
    fprintf(fp, "`define STARTUP_FS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_FS].cache.valid & 1);
812
    fprintf(fp, "`define STARTUP_GS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_GS].cache.valid & 1);
813
    fprintf(fp, "`define STARTUP_CS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_CS].cache.valid & 1);
814
    fprintf(fp, "`define STARTUP_LDTR_VALID 1'b%d\n", bx_cpu.ldtr.cache.valid & 1);
815
    fprintf(fp, "`define STARTUP_TR_VALID   1'b%d\n", bx_cpu.tr.cache.valid & 1);
816
 
817
    fprintf(fp, "`define STARTUP_EIP 32'h%08x\n", bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx);
818
 
819
    fprintf(fp, "`define STARTUP_PREFETCH_LIMIT  32'h%08x\n",
820
            (bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled >> (bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.g? 12 : 0)) - bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx + 1);
821
    fprintf(fp, "`define STARTUP_PREFETCH_LINEAR 32'h%08x\n",
822
            bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base + bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx);
823
 
824
    fflush(fp);
825
    fclose(fp);
826
}
827
 
828
//------------------------------------------------------------------------------
829
//------------------------------------------------------------------------------
830
//------------------------------------------------------------------------------ instrument
831
 
832
bool bochs486_skip_rep_finish = false;
833
 
834
 
835
void bx_instr_init_env(void) { }
836
void bx_instr_exit_env(void) { }
837
 
838
void bx_instr_debug_promt() { }
839
void bx_instr_debug_cmd(const char *cmd) { }
840
 
841
void bx_instr_cnear_branch_taken(unsigned cpu, bx_address branch_eip, bx_address new_eip) { }
842
void bx_instr_cnear_branch_not_taken(unsigned cpu, bx_address branch_eip) { }
843
void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address branch_eip, bx_address new_eip) { }
844
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u new_cs, bx_address new_eip) { }
845
 
846
void bx_instr_opcode(unsigned cpu, bxInstruction_c *i, const Bit8u *opcode, unsigned len, bx_bool is32, bx_bool is64) { }
847
 
848
void bx_instr_exception(unsigned cpu, unsigned vector, unsigned error_code) { }
849
void bx_instr_hwinterrupt(unsigned cpu, unsigned vector, Bit16u cs, bx_address eip) { }
850
 
851
void bx_instr_tlb_cntrl(unsigned cpu, unsigned what, bx_phy_address new_cr3) { }
852
void bx_instr_cache_cntrl(unsigned cpu, unsigned what) { }
853
void bx_instr_prefetch_hint(unsigned cpu, unsigned what, unsigned seg, bx_address offset) { }
854
void bx_instr_clflush(unsigned cpu, bx_address laddr, bx_phy_address paddr) { }
855
 
856
void bx_instr_initialize(unsigned cpu) { }
857
void bx_instr_exit(unsigned cpu) { }
858
void bx_instr_reset(unsigned cpu, unsigned type) { }
859
 
860
void bx_instr_inp(Bit16u addr, unsigned len) { }
861
void bx_instr_inp2(Bit16u addr, unsigned len, unsigned val) { }
862
void bx_instr_outp(Bit16u addr, unsigned len, unsigned val) { }
863
 
864
void bx_instr_lin_access(unsigned cpu, bx_address lin, bx_address phy, unsigned len, unsigned rw) { }
865
void bx_instr_phy_access(unsigned cpu, bx_address phy, unsigned len, unsigned rw) { }
866
 
867
void bx_instr_wrmsr(unsigned cpu, unsigned addr, Bit64u value) { }
868
 
869
 
870
bool intr_pending = false;
871
 
872
void bx_instr_interrupt(unsigned cpu, unsigned vector, unsigned type, bx_bool push_error, Bit16u error_code) {
873
 
874
    bochs486_skip_rep_finish = false;
875
    if(type == BX_EXTERNAL_INTERRUPT) intr_pending = false;
876
 
877
    if(type == BX_HARDWARE_EXCEPTION || type == BX_EXTERNAL_INTERRUPT) {
878
        printf("bx_instr_interrupt(%d): %02x at %d\n", type, vector, shared_ptr->bochs486_pc.instr_counter);
879
        shared_ptr->bochs486_pc.instr_counter++;
880
 
881
        if(type != BX_EXTERNAL_INTERRUPT) {
882
            FILE *fp = fopen("track.txt", "a");
883
            fprintf(fp, "Exception 0x%02x at %x\n", vector, shared_ptr->bochs486_pc.instr_counter);
884
            fclose(fp);
885
        }
886
 
887
        if(shared_ptr->bochs486_pc.instr_counter == shared_ptr->interrupt_at_counter) {
888
            interrupt_vector = shared_ptr->interrupt_vector;
889
 
890
            FILE *fp = fopen("track.txt", "a");
891
            fprintf(fp, "IAC 0x%02x at %x\n", vector, shared_ptr->bochs486_pc.instr_counter);
892
            fclose(fp);
893
 
894
printf("raise_INTR(): %02x at %d\n", interrupt_vector, shared_ptr->bochs486_pc.instr_counter);
895
            bx_cpu.raise_INTR();
896
            intr_pending = true;
897
        }
898
        else if(intr_pending && shared_ptr->interrupt_at_counter == 0) {
899
printf("clear_INTR() at %d\n", shared_ptr->bochs486_pc.instr_counter);
900
            bx_cpu.clear_INTR();
901
            intr_pending = false;
902
        }
903
    }
904
}
905
 
906
void instr_after_execution() {
907
 
908
    shared_ptr->bochs486_pc.instr_counter++;
909
 
910
bx_cpu.TLB_flush();
911
 
912
    if(shared_ptr->dump_enabled) {
913
        output_cpu_state();
914
    }
915
 
916
    if(shared_ptr->bochs486_pc.instr_counter == shared_ptr->interrupt_at_counter) {
917
        interrupt_vector = shared_ptr->interrupt_vector;
918
 
919
        FILE *fp = fopen("track.txt", "a");
920
        fprintf(fp, "IAC 0x%02x at %x\n", interrupt_vector, shared_ptr->bochs486_pc.instr_counter);
921
        fclose(fp);
922
 
923
printf("raise_INTR(): %02x at %d\n", interrupt_vector, shared_ptr->bochs486_pc.instr_counter);
924
        bx_cpu.raise_INTR();
925
        intr_pending = true;
926
    }
927
    else if(intr_pending && shared_ptr->interrupt_at_counter == 0) {
928
printf("clear_INTR() at %d\n", shared_ptr->bochs486_pc.instr_counter);
929
        bx_cpu.clear_INTR();
930
        intr_pending = false;
931
    }
932
 
933
    if(shared_ptr->bochs486_pc.stop == STEP_REQ && bochs486_skip_rep_finish == false) {
934
        printf("stopping...\n");
935
        output_cpu_state();
936
        fflush(stdout);
937
 
938
        output_for_verilator();
939
 
940
        shared_ptr->bochs486_pc.stop = STEP_ACK;
941
        while(shared_ptr->bochs486_pc.stop != STEP_IDLE) {
942
            usleep(500);
943
        }
944
    }
945
}
946
 
947
void bx_instr_before_execution(unsigned cpu, bxInstruction_c *i) {
948
 
949
//printf("cs: %04x eip: %08x len: %d op: %02x\n", bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, i->ilen(), i->bochs486_opcode);
950
 
951
}
952
 
953
void bx_instr_after_execution(unsigned cpu, bxInstruction_c *i) {
954
//printf("AFT cs: %04x eip: %08x len: %d op: %02x\n", bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, i->ilen(), i->bochs486_opcode);    
955
 
956
    if(bochs486_skip_rep_finish) {
957
        printf("#bx_instr_after_execution: bochs486_skip_rep_finished at %d\n", shared_ptr->bochs486_pc.instr_counter);
958
        bochs486_skip_rep_finish = false;
959
        return;
960
    }
961
 
962
printf("#instr: %02x %d\n", i->bochs486_opcode, shared_ptr->bochs486_pc.instr_counter);
963
 
964
    instr_after_execution();
965
}
966
void bx_instr_repeat_iteration(unsigned cpu, bxInstruction_c *i) {
967
    bochs486_skip_rep_finish = true;
968
 
969
printf("#repeat: %d\n", shared_ptr->bochs486_pc.instr_counter);
970
    instr_after_execution();
971
}
972
void bx_instr_hlt(unsigned cpu) {
973
    instr_after_execution();
974
}
975
 
976
void bx_instr_mwait(unsigned cpu, bx_phy_address addr, unsigned len, Bit32u flags) { }
977
 
978
// memory trace callbacks from CPU, len=1,2,4 or 8
979
void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned pl, unsigned rw, Bit8u *data) {
980
}
981
void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw, unsigned attr, Bit8u *data) {
982
}
983
 
984
//------------------------------------------------------------------------------
985
//------------------------------------------------------------------------------
986
//------------------------------------------------------------------------------ main
987
 
988
int main(int argc, char **argv) {
989
 
990
    //map shared memory
991
    int fd = open("./../sim/sim_pc/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
992
 
993
    if(fd == -1) {
994
        perror("open() failed for shared_mem.dat");
995
        return -1;
996
    }
997
 
998
    shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
999
 
1000
    if(shared_ptr == MAP_FAILED) {
1001
        perror("mmap() failed");
1002
        close(fd);
1003
        return -2;
1004
    }
1005
 
1006
    //wait for ack
1007
    shared_ptr->bochs486_pc.starting = STEP_REQ;
1008
    printf("Waiting for startup ack...");
1009
    fflush(stdout);
1010
    while(shared_ptr->bochs486_pc.starting != STEP_ACK) {
1011
        usleep(100000);
1012
    }
1013
    printf("done.\n");
1014
 
1015
 
1016
 
1017
    bx_pc_system.a20_mask = 0xFFFFFFFF;
1018
 
1019
    SIM = new bochs486_sim();
1020
 
1021
    bx_cpu.initialize();
1022
    bx_cpu.reset(BX_RESET_HARDWARE);
1023
 
1024
    printf("START\n");
1025
    bx_cpu.gen_reg[BX_32BIT_REG_EDX].dword.erx = 0x0000045b; //after reset EDX value
1026
    shared_ptr->bochs486_pc.instr_counter++; //ao486 has extra instruction at 0xFFFFFFF0
1027
 
1028
    bx_cpu.async_event = 0;
1029
    bx_cpu.handleCpuModeChange();
1030
 
1031
    bx_cpu.cpu_loop();
1032
 
1033
    printf("#bochs486_pc: finishing.\n");
1034
 
1035
    munmap((void *)shared_ptr, sizeof(shared_mem_t));
1036
    close(fd);
1037
 
1038
    return 0;
1039
}

powered by: WebSVN 2.1.0

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