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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [bochs486/] [main_plugin.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
 
220
//------------------------------------------------------------------------------
221
//------------------------------------------------------------------------------
222
//------------------------------------------------------------------------------ devices
223
 
224
class bochs486_pic : public bx_pic_stub_c {
225
    Bit8u IAC(void) {
226
 
227
        uint32 vec = shared_ptr->irq_do_vector;
228
 
229
        shared_ptr->irq_done_vector = vec;
230
        shared_ptr->irq_done = STEP_REQ;
231
 
232
        const char *txt = "";
233
 
234
        if(shared_ptr->irq_do == STEP_IDLE)     txt = "-spurIDLE";
235
        else if(shared_ptr->irq_do == STEP_ACK) txt = "-spurACK";
236
 
237
        FILE *fp = fopen("track.txt", "a");
238
        fprintf(fp, "IAC%s 0x%02x at %d; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", txt, vec, shared_ptr->bochs486_pc.instr_counter,
239
                bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
240
                bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
241
        fclose(fp);
242
 
243
        fp = fopen("interrupt.txt", "a");
244
        fprintf(fp, "IAC%s 0x%02x at %d; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", txt, vec, shared_ptr->bochs486_pc.instr_counter,
245
            bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
246
            bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
247
        fclose(fp);
248
 
249
        shared_ptr->irq_do = STEP_ACK;
250
 
251
        bx_cpu.clear_INTR();
252
        return vec & 0xFF;
253
    }
254
 
255
};
256
 
257
int is_io_ignored(Bit16u address, Bit32u byteena) {
258
 
259
    bool read_ff =
260
            (address >= 0x0010 && address < 0x0020)     ||
261
            (address == 0x0020 && (byteena & 0x3) == 0) ||
262
            (address >= 0x0024 &&  address < 0x0040)    ||
263
            (address >= 0x0044 &&  address < 0x0060)    ||
264
            (address >= 0x0068 &&  address < 0x0070)    ||
265
            (address == 0x0070 && (byteena & 0x3) == 0) ||
266
            (address >= 0x0074 &&  address < 0x0080)    ||
267
            (address == 0x00A0 && (byteena & 0x3) == 0) ||
268
            (address >= 0x00A4 &&  address < 0x00C0)    ||
269
            (address >= 0x00E0 &&  address < 0x01F0)    ||
270
            (address >= 0x01F8 &&  address < 0x0220)    ||
271
            (address >= 0x0230 &&  address < 0x0388)    ||
272
            (address == 0x0388 && (byteena & 0x3) == 0) ||
273
            (address >= 0x038C &&  address < 0x03B0)    ||
274
            (address >= 0x03E0 &&  address < 0x03F0)    ||
275
            (address >= 0x03F8 &&  address < 0x8888)    ||
276
            (address >= 0x8890);
277
 
278
    bool read_ff_part =
279
            (address == 0x0020) ||
280
            (address == 0x0070) ||
281
            (address == 0x00A0) ||
282
            (address == 0x0388);
283
 
284
    if(read_ff)         return 1;
285
    if(read_ff_part)    return 2;
286
    return 0;
287
}
288
 
289
  Bit32u BX_CPP_AttrRegparmN(2)
290
bx_devices_c::inp(Bit16u addr, unsigned io_len) {
291
//printf("#bochs486_pc:inp(%04x, %d)\n", addr, io_len);
292
    // read aligned to 4 bytes, with byteena
293
 
294
    bool two_reads = (addr & 0x3) + io_len > 4;
295
 
296
    Bit16u   addr1    = addr & 0xFFFC;
297
    unsigned byteena1 = (io_len == 1)? 0x1 : (io_len == 2)? 0x3 : (io_len == 3)? 0x7 : 0xF;
298
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
299
 
300
    Bit16u   addr2    = (addr + 4) & 0xFFFC;
301
    unsigned byteena2 = (byteena1 >> 4) & 0xF;
302
 
303
    //-------------------------------------------------------------------------- first read
304
    int int_ret = is_io_ignored(addr1, byteena1 & 0xF);
305
    unsigned int data1 = 0xFFFFFFFF;
306
 
307
    if(int_ret == 0 || int_ret == 2) {
308
        shared_ptr->bochs486_pc.io_address    = addr1;
309
        shared_ptr->bochs486_pc.io_byteenable = byteena1 & 0xF;
310
        shared_ptr->bochs486_pc.io_is_write   = 0;
311
        shared_ptr->bochs486_pc.io_step       = STEP_REQ;
312
        while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
313
            fflush(stdout);
314
            usleep(10);
315
        }
316
        data1 = ((int_ret == 2)? 0xFFFF0000 : 0x00000000) | shared_ptr->bochs486_pc.io_data;
317
 
318
        FILE *fp = fopen("track.txt", "a");
319
        fprintf(fp, "io rd %04x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr1, byteena1 & 0xF, data1,
320
            bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
321
            bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
322
        fclose(fp);
323
 
324
        shared_ptr->bochs486_pc.io_step = STEP_IDLE;
325
    }
326
    //-------------------------------------------------------------------------- second read
327
    unsigned long long data = data1;
328
//printf("#bochs486_pc:inp() read_one %d\n", two_reads);
329
    if(two_reads) {
330
        int_ret = is_io_ignored(addr2, byteena2 & 0xF);
331
        unsigned int data2 = 0xFFFFFFFF;
332
 
333
        if(int_ret == 0 || int_ret == 2) {
334
            shared_ptr->bochs486_pc.io_address    = addr2;
335
            shared_ptr->bochs486_pc.io_byteenable = byteena2 & 0xF;
336
            shared_ptr->bochs486_pc.io_is_write   = 0;
337
            shared_ptr->bochs486_pc.io_step       = STEP_REQ;
338
            while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
339
                fflush(stdout);
340
                usleep(10);
341
            }
342
            data2 = ((int_ret == 2)? 0xFFFF0000 : 0x00000000) | shared_ptr->bochs486_pc.io_data;
343
 
344
            FILE *fp = fopen("track.txt", "a");
345
            fprintf(fp, "io rd %04x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr2, byteena2 & 0xF, data2,
346
                    bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
347
                    bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
348
            fclose(fp);
349
 
350
            shared_ptr->bochs486_pc.io_step = STEP_IDLE;
351
        }
352
 
353
        data = ((unsigned long long)data2 << 32) | data1;
354
    }
355
 
356
    while((byteena1 & 1) == 0) {
357
        byteena1 >>= 1;
358
        data >>= 8;
359
    }
360
    Bit32u ret_val = (io_len == 1)? (data & 0xFFL) : (io_len == 2)? (data & 0xFFFFL) : (io_len == 3)? (data & 0xFFFFFFL) : (data & 0xFFFFFFFFL);
361
printf("#bochs486_pc:inp(%04x, %d, =%08x)\n", addr, io_len, ret_val);
362
    return ret_val;
363
}
364
 
365
  void BX_CPP_AttrRegparmN(3)
366
bx_devices_c::outp(Bit16u addr, Bit32u value, unsigned io_len) {
367
printf("#bochs486_pc:outp(%04x, %d, %08x)\n", addr, io_len, value);
368
    // write aligned to 4 bytes, with byteena
369
 
370
    bool two_writes = (addr & 0x3) + io_len > 4;
371
 
372
    Bit16u   addr1    = addr & 0xFFFC;
373
    unsigned byteena1 = (io_len == 1)? 0x1 : (io_len == 2)? 0x3 : (io_len == 3)? 0x7 : 0xF;
374
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
375
 
376
    Bit16u   addr2    = (addr + 4) & 0xFFFC;
377
    unsigned byteena2 = (byteena1 >> 4) & 0xF;
378
 
379
    if(io_len == 1) value &= 0x000000FF;
380
    if(io_len == 2) value &= 0x0000FFFF;
381
    if(io_len == 3) value &= 0x00FFFFFF;
382
 
383
    Bit64u value_full = ((addr & 0x3) == 0)? (Bit64u)value : ((addr & 0x3) == 1)? ((Bit64u)value << 8) : ((addr & 0x3) == 2)? ((Bit64u)value << 16) : ((Bit64u)value << 24);
384
    Bit32u value1 = value_full;
385
    Bit32u value2   = (value_full >> 32);
386
 
387
    //-------------------------------------------------------------------------- first write
388
    int int_ret = is_io_ignored(addr1, byteena1 & 0xF);
389
 
390
    if(int_ret == 0 || int_ret == 2) {
391
        shared_ptr->bochs486_pc.io_address    = addr1;
392
        shared_ptr->bochs486_pc.io_byteenable = byteena1 & 0xF;
393
        shared_ptr->bochs486_pc.io_is_write   = 1;
394
        shared_ptr->bochs486_pc.io_data       = value1;
395
        shared_ptr->bochs486_pc.io_step       = STEP_REQ;
396
        while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
397
            fflush(stdout);
398
            usleep(10);
399
        }
400
 
401
        FILE *fp = fopen("track.txt", "a");
402
        fprintf(fp, "io wr %04x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr1, byteena1 & 0xF, value1,
403
                bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
404
                bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
405
        fclose(fp);
406
 
407
        shared_ptr->bochs486_pc.io_step = STEP_IDLE;
408
    }
409
//printf("#bochs486_pc:outp() write_one %d\n", two_writes);
410
    //-------------------------------------------------------------------------- second write
411
 
412
    if(two_writes) {
413
        int_ret = is_io_ignored(addr2, byteena2 & 0xF);
414
 
415
        if(int_ret == 0 || int_ret == 2) {
416
            shared_ptr->bochs486_pc.io_address    = addr2;
417
            shared_ptr->bochs486_pc.io_byteenable = byteena2 & 0xF;
418
            shared_ptr->bochs486_pc.io_is_write   = 1;
419
            shared_ptr->bochs486_pc.io_data       = value2;
420
            shared_ptr->bochs486_pc.io_step       = STEP_REQ;
421
            while(shared_ptr->bochs486_pc.io_step != STEP_ACK) {
422
                fflush(stdout);
423
                usleep(10);
424
            }
425
 
426
            FILE *fp = fopen("track.txt", "a");
427
            fprintf(fp, "io wr %04x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr2, byteena2 & 0xF, value2,
428
                    bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
429
                    bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
430
            fclose(fp);
431
 
432
            shared_ptr->bochs486_pc.io_step = STEP_IDLE;
433
        }
434
    }
435
//printf("#bochs486_pc:outp() write_two\n");
436
}
437
 
438
bx_devices_c::bx_devices_c() {
439
    pluginPicDevice = new bochs486_pic();
440
}
441
 
442
bx_devices_c::~bx_devices_c() {
443
}
444
 
445
bx_devices_c bx_devices;
446
 
447
//------------------------------------------------------------------------------
448
//------------------------------------------------------------------------------
449
//------------------------------------------------------------------------------ memory
450
 
451
void BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, void *data) {
452
printf("#bochs486_pc: writePhysicalPage: addr=%08x, len=%d ", addr, len);
453
for(unsigned i=0; i<len; i++) printf("%02x ", ((uint8 *)data)[i]); printf("\n");
454
 
455
    addr &= 0x07FFFFFF;
456
 
457
    if(len > 4) {
458
        printf("#bochs486_pc: writePhysicalPage() with len = %d\n", len);
459
        exit(-1);
460
    }
461
 
462
    bool two_writes = (addr & 0x3) + len > 4;
463
 
464
    Bit32u   addr1    = addr & 0xFFFFFFFC;
465
    unsigned byteena1 = (len == 1)? 0x1 : (len == 2)? 0x3 : (len == 3)? 0x7 : 0xF;
466
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
467
 
468
    Bit32u   addr2    = (addr + 4) & 0xFFFFFFFC;
469
    unsigned byteena2 = (byteena1 >> 4) & 0xF;
470
 
471
    Bit32u value = ((unsigned int *)data)[0];
472
    if(len == 1) value &= 0x000000FF;
473
    if(len == 2) value &= 0x0000FFFF;
474
    if(len == 3) value &= 0x00FFFFFF;
475
 
476
    Bit64u value_full = ((addr & 0x3) == 0)? (Bit64u)value : ((addr & 0x3) == 1)? ((Bit64u)value << 8) : ((addr & 0x3) == 2)? ((Bit64u)value << 16) : ((Bit64u)value << 24);
477
    Bit32u value1 = value_full;
478
    Bit32u value2   = (value_full >> 32);
479
 
480
    //-------------------------------------------------------------------------- first write
481
    shared_ptr->bochs486_pc.mem_address    = addr1;
482
    shared_ptr->bochs486_pc.mem_byteenable = byteena1 & 0xF;
483
    shared_ptr->bochs486_pc.mem_is_write   = 1;
484
    shared_ptr->bochs486_pc.mem_data       = value1;
485
    shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
486
    while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
487
        fflush(stdout);
488
        usleep(10);
489
    }
490
 
491
    FILE *fp = fopen("track.txt", "a");
492
    fprintf(fp, "mem wr %08x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr1, byteena1 & 0xF, value1,
493
            bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
494
            bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
495
    fclose(fp);
496
 
497
    shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
498
 
499
//printf("#bochs486_pc: writePhysicalPage: write_one, %d\n", two_writes);
500
    if(two_writes) {
501
        //---------------------------------------------------------------------- second write
502
        shared_ptr->bochs486_pc.mem_address    = addr2;
503
        shared_ptr->bochs486_pc.mem_byteenable = byteena2 & 0xF;
504
        shared_ptr->bochs486_pc.mem_is_write   = 1;
505
        shared_ptr->bochs486_pc.mem_data       = value2;
506
        shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
507
        while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
508
            fflush(stdout);
509
            usleep(10);
510
        }
511
 
512
        FILE *fp = fopen("track.txt", "a");
513
        fprintf(fp, "mem wr %08x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr2, byteena2 & 0xF, value2,
514
                bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
515
                bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
516
        fclose(fp);
517
 
518
        shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
519
    }
520
//printf("#bochs486_pc: writePhysicalPage: write_two\n");
521
}
522
 
523
void BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, bx_phy_address addr, unsigned len, void *data) {
524
printf("#bochs486_pc: readPhysicalPage: addr=%08x, len=%d\n", addr, len);
525
 
526
        if(addr >= 0xFFFFF000) addr &= 0x000FFFFF;
527
        addr &= 0x07FFFFFF;
528
 
529
    if(len == 4096) {
530
        if((addr & 3) != 0) {
531
            printf("#bochs486_pc: readPhysicalPage() with len = 4096 and addr not aligned to 4.\n");
532
            exit(-1);
533
        }
534
 
535
        if(addr >= 0xA0000 && addr <= 0xBFFFF) {
536
            printf("#bochs486_pc: readPhysicalPage() with len = 4096 and addr in vga buffer.\n");
537
            fflush(stdout); while(1) { ; }
538
            exit(-1);
539
        }
540
 
541
        memcpy((unsigned char *)data, (void *)(shared_ptr->mem.bytes + addr), len);
542
        return;
543
    }
544
 
545
    //check if read crosses line boundry (16 bytes)
546
    if( ((addr) & 0xFFFFFFF0) != ((addr + len - 1) & 0xFFFFFFF0) ) {
547
        unsigned char *ptr = (unsigned char*)data;
548
        readPhysicalPage(cpu, addr,             (addr | 0xF) - addr + 1,       ptr);
549
        readPhysicalPage(cpu, (addr | 0xF) + 1, len - (addr | 0xF) + addr - 1, ptr + ((addr | 0xF) - addr + 1));
550
        return;
551
    }
552
 
553
    if(addr < 0xA0000 || addr > 0xBFFFF) {
554
        memcpy((unsigned char *)data, (void *)(shared_ptr->mem.bytes + addr), len);
555
        return;
556
    }
557
//printf("#bochs486_pc: readPhysicalPage: vga read.\n");    
558
    bool two_reads   = ((addr & 0x3) + len > 4) && ((addr & 0x3) + len <= 8);
559
    bool three_reads = ((addr & 0x3) + len > 8);
560
 
561
    Bit32u   addr1    = addr & 0xFFFFFFFC;
562
    unsigned byteena1 = (len == 1)? 0x1 : (len == 2)? 0x3 : (len == 3)? 0x7 : 0xF;
563
    byteena1 = ((addr & 0x3) == 0)? byteena1 : ((addr & 0x3) == 1)? byteena1 << 1 : ((addr & 0x3) == 2)? byteena1 << 2 : byteena1 << 3;
564
 
565
    Bit32u   addr2    = (addr + 4) & 0xFFFFFFFC;
566
    Bit32u   addr3    = (addr + 8) & 0xFFFFFFFC;
567
 
568
    if(two_reads || three_reads) byteena1 = 0xF;
569
    byteena1 &= 0xF;
570
 
571
    //-------------------------------------------------------------------------- first read
572
    unsigned int data_read[3] = { 0,0,0 };
573
 
574
    shared_ptr->bochs486_pc.mem_address    = addr1;
575
    shared_ptr->bochs486_pc.mem_byteenable = byteena1 & 0xF;
576
    shared_ptr->bochs486_pc.mem_is_write   = 0;
577
    shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
578
    while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
579
        fflush(stdout);
580
        usleep(10);
581
    }
582
    data_read[0] = shared_ptr->bochs486_pc.mem_data;
583
 
584
    FILE *fp = fopen("track.txt", "a");
585
    fprintf(fp, "mem rd %08x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr1, byteena1 & 0xF, data_read[0],
586
            bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
587
            bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
588
    fclose(fp);
589
 
590
    shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
591
 
592
    if(two_reads || three_reads) {
593
        //---------------------------------------------------------------------- second read
594
        shared_ptr->bochs486_pc.mem_address    = addr2;
595
        shared_ptr->bochs486_pc.mem_byteenable = 0xF;
596
        shared_ptr->bochs486_pc.mem_is_write   = 0;
597
        shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
598
        while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
599
            fflush(stdout);
600
            usleep(10);
601
        }
602
        data_read[1] = shared_ptr->bochs486_pc.mem_data;
603
 
604
        FILE *fp = fopen("track.txt", "a");
605
        fprintf(fp, "mem rd %08x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr2, 0xF, data_read[1],
606
                bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
607
                bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
608
        fclose(fp);
609
 
610
        shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
611
 
612
        if(three_reads) {
613
            //------------------------------------------------------------------ third read
614
            shared_ptr->bochs486_pc.mem_address    = addr3;
615
            shared_ptr->bochs486_pc.mem_byteenable = 0xF;
616
            shared_ptr->bochs486_pc.mem_is_write   = 0;
617
            shared_ptr->bochs486_pc.mem_step       = STEP_REQ;
618
            while(shared_ptr->bochs486_pc.mem_step != STEP_ACK) {
619
                fflush(stdout);
620
                usleep(10);
621
            }
622
            data_read[2] = shared_ptr->bochs486_pc.mem_data;
623
 
624
            FILE *fp = fopen("track.txt", "a");
625
            fprintf(fp, "mem rd %08x %x %08x; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", addr3, 0xF, data_read[2],
626
                    bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
627
                    bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
628
            fclose(fp);
629
 
630
            shared_ptr->bochs486_pc.mem_step = STEP_IDLE;
631
        }
632
    }
633
 
634
    unsigned char *ptr = (unsigned char *)data_read;
635
 
636
    for(int i=0; i<(addr & 0x3); i++) ptr++;
637
 
638
    memcpy((unsigned char *)data, ptr, len);
639
}
640
 
641
Bit8u *BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, bx_phy_address addr, unsigned rw) {
642
//printf("#bochs486_pc: getHostMemAddr: addr=%08x, rw=%d\n", addr, rw);
643
 
644
    if(addr >= 0xA0000 && addr < 0xC0000) return NULL;
645
    if(rw != BX_EXECUTE) return NULL;
646
 
647
    if(addr >= 0xFFFFF000) addr &= 0x000FFFFF;
648
    addr &= 0x07FFFFFF;
649
 
650
    return (Bit8u *)(shared_ptr->mem.bytes + addr);
651
}
652
BX_MEM_C::BX_MEM_C() {
653
}
654
BX_MEM_C::~BX_MEM_C() {
655
}
656
 
657
BOCHSAPI BX_MEM_C bx_mem;
658
 
659
//------------------------------------------------------------------------------
660
//------------------------------------------------------------------------------
661
//------------------------------------------------------------------------------ interrupt
662
 
663
void print_segment(bx_segment_reg_t *seg, const char *prefix) {
664
 
665
    printf("%s: %04x ",    prefix, seg->selector.value);
666
    printf("val: %01x ",   seg->cache.valid & 1);
667
    printf("rpl: %01hhx ", seg->selector.rpl);
668
    printf("base: %08x ",  seg->cache.u.segment.base);
669
    printf("limit: %08x ", (seg->cache.u.segment.g)? seg->cache.u.segment.limit_scaled >> 12 : seg->cache.u.segment.limit_scaled);
670
    printf("g: %01x ",     seg->cache.u.segment.g);
671
    printf("d_b: %01x ",   seg->cache.u.segment.d_b);
672
    printf("avl: %01x ",   seg->cache.u.segment.avl);
673
    printf("p: %01x ",     seg->cache.p);
674
    printf("dpl: %01x ",   seg->cache.dpl);
675
    printf("s: %01x ",     seg->cache.segment);
676
    printf("type: %01x\n", seg->cache.type);
677
}
678
 
679
void output_cpu_state() {
680
    printf("eax: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EAX));
681
    printf("ebx: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EBX));
682
    printf("ecx: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_ECX));
683
    printf("edx: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EDX));
684
    printf("esi: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_ESI));
685
    printf("edi: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EDI));
686
    printf("ebp: %08x ", bx_cpu.get_reg32(BX_32BIT_REG_EBP));
687
    printf("esp: %08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ESP));
688
 
689
    printf("eip: %08x\n", bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx);
690
 
691
    printf("cflag:  %01x ", bx_cpu.getB_CF());
692
    printf("pflag:  %01x ", bx_cpu.getB_PF());
693
    printf("aflag:  %01x ", bx_cpu.getB_AF());
694
    printf("zflag:  %01x ", bx_cpu.getB_ZF());
695
    printf("sflag:  %01x ", bx_cpu.getB_SF());
696
    printf("tflag:  %01x ", bx_cpu.getB_TF()&1);
697
    printf("iflag:  %01x ", bx_cpu.getB_IF()&1);
698
    printf("dflag:  %01x ", bx_cpu.getB_DF()&1);
699
    printf("oflag:  %01x ", bx_cpu.getB_OF()&1);
700
    printf("iopl:   %01x ", bx_cpu.get_IOPL()&3);
701
    printf("ntflag: %01x ", bx_cpu.getB_NT()&1);
702
    printf("rflag:  %01x ", bx_cpu.getB_RF()&1);
703
    printf("vmflag: %01x ", bx_cpu.getB_VM()&1);
704
    printf("acflag: %01x ", bx_cpu.getB_AC()&1);
705
    printf("idflag: %01x\n", bx_cpu.getB_ID()&1);
706
 
707
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_CS]), "cs");
708
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_DS]), "ds");
709
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_ES]), "es");
710
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_FS]), "fs");
711
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_GS]), "gs");
712
    print_segment(&(bx_cpu.sregs[BX_SEG_REG_SS]), "ss");
713
    print_segment(&(bx_cpu.ldtr), "ldtr");
714
    print_segment(&(bx_cpu.tr),   "tr");
715
 
716
    printf("gdtr_base:  %08x ", bx_cpu.gdtr.base);
717
    printf("gdtr_limit: %02x\n", bx_cpu.gdtr.limit & 0xFFFF);
718
 
719
    printf("idtr_base:  %08x ", bx_cpu.idtr.base);
720
    printf("idtr_limit: %02x\n", bx_cpu.idtr.limit & 0xFFFF);
721
 
722
    printf("cr0_pe: %01x ", bx_cpu.cr0.get_PE() & 1);
723
    printf("cr0_mp: %01x ", bx_cpu.cr0.get_MP() & 1);
724
    printf("cr0_em: %01x ", bx_cpu.cr0.get_EM() & 1);
725
    printf("cr0_ts: %01x ", bx_cpu.cr0.get_TS() & 1);
726
    printf("cr0_ne: %01x ", bx_cpu.cr0.get_NE() & 1);
727
    printf("cr0_wp: %01x ", bx_cpu.cr0.get_WP() & 1);
728
    printf("cr0_am: %01x ", bx_cpu.cr0.get_AM() & 1);
729
    printf("cr0_nw: %01x ", bx_cpu.cr0.get_NW() & 1);
730
    printf("cr0_cd: %01x ", bx_cpu.cr0.get_CD() & 1);
731
    printf("cr0_pg: %01x\n", bx_cpu.cr0.get_PG() & 1);
732
 
733
    printf("cr2: %08x ", bx_cpu.cr2);
734
    printf("cr3: %08x\n", bx_cpu.cr3);
735
 
736
    printf("dr0: %08x ", bx_cpu.dr[0]);
737
    printf("dr1: %08x ", bx_cpu.dr[1]);
738
    printf("dr2: %08x ", bx_cpu.dr[2]);
739
    printf("dr3: %08x ", bx_cpu.dr[3]);
740
 
741
    printf("dr6: %08x ", bx_cpu.dr6.val32);
742
    printf("dr7: %08x\n", bx_cpu.dr7.val32);
743
 
744
    fflush(stdout);
745
}
746
 
747
uint32 seg_word_1(bx_segment_reg_t *seg) {
748
    return  (seg->cache.u.segment.base & 0xFF000000) |
749
            (seg->cache.u.segment.g?   0x00800000 : 0x00) |
750
            (seg->cache.u.segment.d_b? 0x00400000 : 0x00) |
751
            (seg->cache.u.segment.avl? 0x00100000 : 0x00) |
752
            (((seg->cache.u.segment.limit_scaled >> (seg->cache.u.segment.g? 12 : 0)) << 16) & 0xF) |
753
            (seg->cache.p?   0x00008000 : 0x0) |
754
            ((seg->cache.dpl & 0x3) << 13) |
755
            ((seg->cache.segment & 0x1) << 12) |
756
            ((seg->cache.type & 0xF) << 8) |
757
            ((seg->cache.u.segment.base >> 16) & 0xFF);
758
}
759
 
760
uint32 seg_word_2(bx_segment_reg_t *seg) {
761
    return ((seg->cache.u.segment.base & 0xFFFF) << 16) |
762
           ((seg->cache.u.segment.limit_scaled >> (seg->cache.u.segment.g? 12 : 0)) & 0xFFFF);
763
}
764
 
765
void output_for_verilator() {
766
 
767
    FILE *fp = fopen("./../rtl/ao486/startup_from_sim.v", "wb");
768
 
769
    fprintf(fp, "`define STARTUP_EAX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EAX));
770
    fprintf(fp, "`define STARTUP_EBX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EBX));
771
    fprintf(fp, "`define STARTUP_ECX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ECX));
772
    fprintf(fp, "`define STARTUP_EDX   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EDX));
773
    fprintf(fp, "`define STARTUP_EBP   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EBP));
774
    fprintf(fp, "`define STARTUP_ESP   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ESP));
775
    fprintf(fp, "`define STARTUP_ESI   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_ESI));
776
    fprintf(fp, "`define STARTUP_EDI   32'h%08x\n", bx_cpu.get_reg32(BX_32BIT_REG_EDI));
777
 
778
    fprintf(fp, "`define STARTUP_CR0_PE 1'b%d\n", bx_cpu.cr0.get_PE() & 1);
779
    fprintf(fp, "`define STARTUP_CR0_MP 1'b%d\n", bx_cpu.cr0.get_MP() & 1);
780
    fprintf(fp, "`define STARTUP_CR0_EM 1'b%d\n", bx_cpu.cr0.get_EM() & 1);
781
    fprintf(fp, "`define STARTUP_CR0_TS 1'b%d\n", bx_cpu.cr0.get_TS() & 1);
782
    fprintf(fp, "`define STARTUP_CR0_NE 1'b%d\n", bx_cpu.cr0.get_NE() & 1);
783
    fprintf(fp, "`define STARTUP_CR0_WP 1'b%d\n", bx_cpu.cr0.get_WP() & 1);
784
    fprintf(fp, "`define STARTUP_CR0_AM 1'b%d\n", bx_cpu.cr0.get_AM() & 1);
785
    fprintf(fp, "`define STARTUP_CR0_NW 1'b%d\n", bx_cpu.cr0.get_NW() & 1);
786
    fprintf(fp, "`define STARTUP_CR0_CD 1'b%d\n", bx_cpu.cr0.get_CD() & 1);
787
    fprintf(fp, "`define STARTUP_CR0_PG 1'b%d\n", bx_cpu.cr0.get_PG() & 1);
788
 
789
    fprintf(fp, "`define STARTUP_CR2 32'h%08x\n", bx_cpu.cr2);
790
    fprintf(fp, "`define STARTUP_CR3 32'h%08x\n", bx_cpu.cr3);
791
 
792
    fprintf(fp, "`define STARTUP_CFLAG  1'b%d\n", bx_cpu.getB_CF());
793
    fprintf(fp, "`define STARTUP_PFLAG  1'b%d\n", bx_cpu.getB_PF());
794
    fprintf(fp, "`define STARTUP_AFLAG  1'b%d\n", bx_cpu.getB_AF());
795
    fprintf(fp, "`define STARTUP_ZFLAG  1'b%d\n", bx_cpu.getB_ZF());
796
    fprintf(fp, "`define STARTUP_SFLAG  1'b%d\n", bx_cpu.getB_SF());
797
    fprintf(fp, "`define STARTUP_OFLAG  1'b%d\n", bx_cpu.getB_OF()&1);
798
    fprintf(fp, "`define STARTUP_TFLAG  1'b%d\n", bx_cpu.getB_TF()&1);
799
    fprintf(fp, "`define STARTUP_IFLAG  1'b%d\n", bx_cpu.getB_IF()&1);
800
    fprintf(fp, "`define STARTUP_DFLAG  1'b%d\n", bx_cpu.getB_DF()&1);
801
    fprintf(fp, "`define STARTUP_IOPL   2'd%d\n", bx_cpu.get_IOPL()&3);
802
    fprintf(fp, "`define STARTUP_NTFLAG 1'b%d\n", bx_cpu.getB_NT()&1);
803
    fprintf(fp, "`define STARTUP_VMFLAG 1'b%d\n", bx_cpu.getB_VM()&1);
804
    fprintf(fp, "`define STARTUP_ACFLAG 1'b%d\n", bx_cpu.getB_AC()&1);
805
    fprintf(fp, "`define STARTUP_IDFLAG 1'b%d\n", bx_cpu.getB_ID()&1);
806
    fprintf(fp, "`define STARTUP_RFLAG  1'b%d\n", bx_cpu.getB_RF()&1);
807
 
808
    fprintf(fp, "`define STARTUP_GDTR_BASE  32'h%08x\n", bx_cpu.gdtr.base);
809
    fprintf(fp, "`define STARTUP_GDTR_LIMIT 16'h%04x\n", bx_cpu.gdtr.limit & 0xFFFF);
810
 
811
    fprintf(fp, "`define STARTUP_IDTR_BASE  32'h%08x\n", bx_cpu.idtr.base);
812
    fprintf(fp, "`define STARTUP_IDTR_LIMIT 16'h%04x\n", bx_cpu.idtr.limit & 0xFFFF);
813
 
814
    fprintf(fp, "`define STARTUP_DR0 32'h%08x\n", bx_cpu.dr[0]);
815
    fprintf(fp, "`define STARTUP_DR1 32'h%08x\n", bx_cpu.dr[1]);
816
    fprintf(fp, "`define STARTUP_DR2 32'h%08x\n", bx_cpu.dr[2]);
817
    fprintf(fp, "`define STARTUP_DR3 32'h%08x\n", bx_cpu.dr[3]);
818
 
819
    fprintf(fp, "`define STARTUP_DR6_BREAKPOINTS 4'h%01x\n", bx_cpu.dr6.val32 & 0xF);
820
    fprintf(fp, "`define STARTUP_DR6_B12         1'b%01x\n", (bx_cpu.dr6.val32 >> 12) & 0x1);
821
    fprintf(fp, "`define STARTUP_DR6_BD          1'b%01x\n", (bx_cpu.dr6.val32 >> 13) & 0x1);
822
    fprintf(fp, "`define STARTUP_DR6_BS          1'b%01x\n", (bx_cpu.dr6.val32 >> 14) & 0x1);
823
    fprintf(fp, "`define STARTUP_DR6_BT          1'b%01x\n", (bx_cpu.dr6.val32 >> 15) & 0x1);
824
    fprintf(fp, "`define STARTUP_DR7            32'h%08x\n", bx_cpu.dr7.val32);
825
 
826
    fprintf(fp, "`define STARTUP_ES   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_ES].selector.value);
827
    fprintf(fp, "`define STARTUP_DS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_DS].selector.value);
828
    fprintf(fp, "`define STARTUP_SS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_SS].selector.value);
829
    fprintf(fp, "`define STARTUP_FS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_FS].selector.value);
830
    fprintf(fp, "`define STARTUP_GS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_GS].selector.value);
831
    fprintf(fp, "`define STARTUP_CS   16'h%04x\n", bx_cpu.sregs[BX_SEG_REG_CS].selector.value);
832
    fprintf(fp, "`define STARTUP_LDTR 16'h%04x\n", bx_cpu.ldtr.selector.value);
833
    fprintf(fp, "`define STARTUP_TR   16'h%04x\n", bx_cpu.tr.selector.value);
834
 
835
    fprintf(fp, "`define STARTUP_ES_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_ES].selector.rpl);
836
    fprintf(fp, "`define STARTUP_DS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_DS].selector.rpl);
837
    fprintf(fp, "`define STARTUP_SS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_SS].selector.rpl);
838
    fprintf(fp, "`define STARTUP_FS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_FS].selector.rpl);
839
    fprintf(fp, "`define STARTUP_GS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_GS].selector.rpl);
840
    fprintf(fp, "`define STARTUP_CS_RPL   2'd%d\n", bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl);
841
    fprintf(fp, "`define STARTUP_LDTR_RPL 2'd%d\n", bx_cpu.ldtr.selector.rpl);
842
    fprintf(fp, "`define STARTUP_TR_RPL   2'd%d\n", bx_cpu.tr.selector.rpl);
843
 
844
    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])));
845
    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])));
846
    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])));
847
    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])));
848
    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])));
849
    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])));
850
    fprintf(fp, "`define STARTUP_LDTR_CACHE 64'h%08x%08x\n", seg_word_1(&(bx_cpu.ldtr)),                 seg_word_2(&(bx_cpu.ldtr)));
851
    fprintf(fp, "`define STARTUP_TR_CACHE   64'h%08x%08x\n", seg_word_1(&(bx_cpu.tr)),                   seg_word_2(&(bx_cpu.tr)));
852
 
853
    fprintf(fp, "`define STARTUP_ES_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_ES].cache.valid & 1);
854
    fprintf(fp, "`define STARTUP_DS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_DS].cache.valid & 1);
855
    fprintf(fp, "`define STARTUP_SS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_SS].cache.valid & 1);
856
    fprintf(fp, "`define STARTUP_FS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_FS].cache.valid & 1);
857
    fprintf(fp, "`define STARTUP_GS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_GS].cache.valid & 1);
858
    fprintf(fp, "`define STARTUP_CS_VALID   1'b%d\n", bx_cpu.sregs[BX_SEG_REG_CS].cache.valid & 1);
859
    fprintf(fp, "`define STARTUP_LDTR_VALID 1'b%d\n", bx_cpu.ldtr.cache.valid & 1);
860
    fprintf(fp, "`define STARTUP_TR_VALID   1'b%d\n", bx_cpu.tr.cache.valid & 1);
861
 
862
    fprintf(fp, "`define STARTUP_EIP 32'h%08x\n", bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx);
863
 
864
    fprintf(fp, "`define STARTUP_PREFETCH_LIMIT  32'h%08x\n",
865
            (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);
866
    fprintf(fp, "`define STARTUP_PREFETCH_LINEAR 32'h%08x\n",
867
            bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base + bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx);
868
 
869
    fflush(fp);
870
    fclose(fp);
871
}
872
 
873
//------------------------------------------------------------------------------
874
//------------------------------------------------------------------------------
875
//------------------------------------------------------------------------------ instrument
876
 
877
bool bochs486_skip_rep_finish = false;
878
 
879
 
880
void bx_instr_init_env(void) { }
881
void bx_instr_exit_env(void) { }
882
 
883
void bx_instr_debug_promt() { }
884
void bx_instr_debug_cmd(const char *cmd) { }
885
 
886
void bx_instr_cnear_branch_taken(unsigned cpu, bx_address branch_eip, bx_address new_eip) { }
887
void bx_instr_cnear_branch_not_taken(unsigned cpu, bx_address branch_eip) { }
888
void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address branch_eip, bx_address new_eip) { }
889
void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u new_cs, bx_address new_eip) { }
890
 
891
void bx_instr_opcode(unsigned cpu, bxInstruction_c *i, const Bit8u *opcode, unsigned len, bx_bool is32, bx_bool is64) { }
892
 
893
void bx_instr_exception(unsigned cpu, unsigned vector, unsigned error_code) { }
894
void bx_instr_hwinterrupt(unsigned cpu, unsigned vector, Bit16u cs, bx_address eip) { }
895
 
896
void bx_instr_tlb_cntrl(unsigned cpu, unsigned what, bx_phy_address new_cr3) { }
897
void bx_instr_cache_cntrl(unsigned cpu, unsigned what) { }
898
void bx_instr_prefetch_hint(unsigned cpu, unsigned what, unsigned seg, bx_address offset) { }
899
void bx_instr_clflush(unsigned cpu, bx_address laddr, bx_phy_address paddr) { }
900
 
901
void bx_instr_initialize(unsigned cpu) { }
902
void bx_instr_exit(unsigned cpu) { }
903
void bx_instr_reset(unsigned cpu, unsigned type) { }
904
 
905
void bx_instr_inp(Bit16u addr, unsigned len) { }
906
void bx_instr_inp2(Bit16u addr, unsigned len, unsigned val) { }
907
void bx_instr_outp(Bit16u addr, unsigned len, unsigned val) { }
908
 
909
void bx_instr_lin_access(unsigned cpu, bx_address lin, bx_address phy, unsigned len, unsigned rw) { }
910
void bx_instr_phy_access(unsigned cpu, bx_address phy, unsigned len, unsigned rw) { }
911
 
912
void bx_instr_wrmsr(unsigned cpu, unsigned addr, Bit64u value) { }
913
 
914
 
915
bool intr_pending = false;
916
 
917
void bx_instr_interrupt(unsigned cpu, unsigned vector, unsigned type, bx_bool push_error, Bit16u error_code) {
918
 
919
    bochs486_skip_rep_finish = false;
920
    if(type == BX_EXTERNAL_INTERRUPT) intr_pending = false;
921
 
922
    if(type == BX_HARDWARE_EXCEPTION || type == BX_EXTERNAL_INTERRUPT) {
923
        printf("bx_instr_interrupt(%d): %02x at %d\n", type, vector, shared_ptr->bochs486_pc.instr_counter);
924
        shared_ptr->bochs486_pc.instr_counter++;
925
 
926
        if(type != BX_EXTERNAL_INTERRUPT) {
927
            FILE *fp = fopen("track.txt", "a");
928
            fprintf(fp, "Exception 0x%02x at %d; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", vector, shared_ptr->bochs486_pc.instr_counter,
929
                    bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
930
                    bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
931
            fclose(fp);
932
        }
933
 
934
        if(shared_ptr->irq_do == STEP_REQ && intr_pending == false) {
935
printf("raise_INTR(): %02x at %d\n", shared_ptr->irq_do_vector, shared_ptr->bochs486_pc.instr_counter);
936
            bx_cpu.raise_INTR();
937
            intr_pending = true;
938
        }
939
 
940
        if(shared_ptr->irq_do == STEP_IDLE && intr_pending == true) {
941
printf("clear_INTR() at %d\n", shared_ptr->bochs486_pc.instr_counter);
942
            bx_cpu.clear_INTR();
943
            intr_pending = false;
944
        }
945
 
946
/*
947
        if(shared_ptr->bochs486_pc.instr_counter == shared_ptr->interrupt_at_counter) {
948
            interrupt_vector = shared_ptr->interrupt_vector;
949
 
950
            FILE *fp = fopen("track.txt", "a");
951
            fprintf(fp, "IAC 0x%02x at %x\n", vector, shared_ptr->bochs486_pc.instr_counter);
952
            fclose(fp);
953
 
954
printf("raise_INTR(): %02x at %d\n", interrupt_vector, shared_ptr->bochs486_pc.instr_counter);
955
            bx_cpu.raise_INTR();
956
            intr_pending = true;
957
        }
958
        else if(intr_pending && shared_ptr->interrupt_at_counter == 0) {
959
printf("clear_INTR() at %d\n", shared_ptr->bochs486_pc.instr_counter);
960
            bx_cpu.clear_INTR();
961
            intr_pending = false;
962
        }
963
*/
964
    }
965
    else {
966
        FILE *fp = fopen("track.txt", "a");
967
        fprintf(fp, "INT 0x%02x at %d; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", vector, shared_ptr->bochs486_pc.instr_counter,
968
                bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
969
                bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
970
        fclose(fp);
971
    }
972
}
973
 
974
void instr_after_execution() {
975
 
976
    shared_ptr->bochs486_pc.instr_counter++;
977
 
978
bx_cpu.TLB_flush();
979
 
980
    if(shared_ptr->dump_enabled) {
981
        output_cpu_state();
982
    }
983
 
984
    if(shared_ptr->irq_do == STEP_REQ && intr_pending == false) {
985
printf("raise_INTR(): %02x at %d\n", shared_ptr->irq_do_vector, shared_ptr->bochs486_pc.instr_counter);
986
        bx_cpu.raise_INTR();
987
        intr_pending = true;
988
    }
989
 
990
    if(shared_ptr->irq_do == STEP_IDLE && intr_pending == true) {
991
printf("clear_INTR() at %d\n", shared_ptr->bochs486_pc.instr_counter);
992
        bx_cpu.clear_INTR();
993
        intr_pending = false;
994
    }
995
 
996
/*
997
    if(shared_ptr->bochs486_pc.instr_counter == shared_ptr->interrupt_at_counter) {
998
        interrupt_vector = shared_ptr->interrupt_vector;
999
 
1000
        FILE *fp = fopen("track.txt", "a");
1001
        fprintf(fp, "IAC 0x%02x at %x\n", interrupt_vector, shared_ptr->bochs486_pc.instr_counter);
1002
        fclose(fp);
1003
 
1004
printf("raise_INTR(): %02x at %d\n", interrupt_vector, shared_ptr->bochs486_pc.instr_counter);
1005
        bx_cpu.raise_INTR();
1006
        intr_pending = true;
1007
    }
1008
    else if(intr_pending && shared_ptr->interrupt_at_counter == 0) {
1009
printf("clear_INTR() at %d\n", shared_ptr->bochs486_pc.instr_counter);
1010
        bx_cpu.clear_INTR();
1011
        intr_pending = false;
1012
    }
1013
*/
1014
 
1015
    if(shared_ptr->bochs486_pc.stop == STEP_REQ && bochs486_skip_rep_finish == false) {
1016
        printf("stopping...\n");
1017
        output_cpu_state();
1018
        fflush(stdout);
1019
 
1020
        output_for_verilator();
1021
 
1022
        shared_ptr->bochs486_pc.stop = STEP_ACK;
1023
        while(shared_ptr->bochs486_pc.stop != STEP_IDLE) {
1024
            usleep(500);
1025
        }
1026
    }
1027
}
1028
 
1029
void bx_instr_before_execution(unsigned cpu, bxInstruction_c *i) {
1030
 
1031
//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);
1032
 
1033
}
1034
 
1035
void bx_instr_after_execution(unsigned cpu, bxInstruction_c *i) {
1036
//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);    
1037
 
1038
    if(bochs486_skip_rep_finish) {
1039
        printf("#bx_instr_after_execution: bochs486_skip_rep_finished at %d\n", shared_ptr->bochs486_pc.instr_counter);
1040
        bochs486_skip_rep_finish = false;
1041
        return;
1042
    }
1043
 
1044
printf("#instr: %02x %d\n", i->bochs486_opcode, shared_ptr->bochs486_pc.instr_counter);
1045
 
1046
    if(i->bochs486_opcode == 0xCF) {
1047
        FILE *fp = fopen("track.txt", "a");
1048
        fprintf(fp, "IRET at %d; pe: %d, pg: %d, vm: %d, eip: %08x, cs: %04x, rpl: %d, ebx: %08x\n", shared_ptr->bochs486_pc.instr_counter,
1049
                bx_cpu.cr0.get_PE() & 1, bx_cpu.cr0.get_PG() & 1, bx_cpu.getB_VM()&1, bx_cpu.gen_reg[BX_32BIT_REG_EIP].dword.erx, bx_cpu.sregs[BX_SEG_REG_CS].selector.value, bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl,
1050
                bx_cpu.gen_reg[BX_32BIT_REG_EBX].dword.erx);
1051
        fclose(fp);
1052
    }
1053
 
1054
    instr_after_execution();
1055
}
1056
void bx_instr_repeat_iteration(unsigned cpu, bxInstruction_c *i) {
1057
    bochs486_skip_rep_finish = true;
1058
 
1059
printf("#repeat: %d\n", shared_ptr->bochs486_pc.instr_counter);
1060
    instr_after_execution();
1061
}
1062
void bx_instr_hlt(unsigned cpu) {
1063
    instr_after_execution();
1064
}
1065
 
1066
void bx_instr_mwait(unsigned cpu, bx_phy_address addr, unsigned len, Bit32u flags) { }
1067
 
1068
// memory trace callbacks from CPU, len=1,2,4 or 8
1069
void bx_dbg_lin_memory_access(unsigned cpu, bx_address lin, bx_phy_address phy, unsigned len, unsigned pl, unsigned rw, Bit8u *data) {
1070
}
1071
void bx_dbg_phy_memory_access(unsigned cpu, bx_phy_address phy, unsigned len, unsigned rw, unsigned attr, Bit8u *data) {
1072
}
1073
 
1074
//------------------------------------------------------------------------------
1075
//------------------------------------------------------------------------------
1076
//------------------------------------------------------------------------------ main
1077
 
1078
int main(int argc, char **argv) {
1079
 
1080
    //map shared memory
1081
    int fd = open("./../sim/sim_pc/shared_mem.dat", O_RDWR, S_IRUSR | S_IWUSR);
1082
 
1083
    if(fd == -1) {
1084
        perror("open() failed for shared_mem.dat");
1085
        return -1;
1086
    }
1087
 
1088
    shared_ptr = (shared_mem_t *)mmap(NULL, sizeof(shared_mem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1089
 
1090
    if(shared_ptr == MAP_FAILED) {
1091
        perror("mmap() failed");
1092
        close(fd);
1093
        return -2;
1094
    }
1095
 
1096
    //wait for ack
1097
    shared_ptr->bochs486_pc.starting = STEP_REQ;
1098
    printf("Waiting for startup ack...");
1099
    fflush(stdout);
1100
    while(shared_ptr->bochs486_pc.starting != STEP_ACK) {
1101
        usleep(100000);
1102
    }
1103
    printf("done.\n");
1104
 
1105
 
1106
 
1107
    bx_pc_system.a20_mask = 0xFFFFFFFF;
1108
 
1109
    SIM = new bochs486_sim();
1110
 
1111
    bx_cpu.initialize();
1112
    bx_cpu.reset(BX_RESET_HARDWARE);
1113
 
1114
    printf("START\n");
1115
    bx_cpu.gen_reg[BX_32BIT_REG_EDX].dword.erx = 0x0000045b; //after reset EDX value
1116
    shared_ptr->bochs486_pc.instr_counter++; //ao486 has extra instruction at 0xFFFFFFF0
1117
 
1118
    bx_cpu.async_event = 0;
1119
    bx_cpu.handleCpuModeChange();
1120
 
1121
    bx_cpu.cpu_loop();
1122
 
1123
    printf("#bochs486_pc: finishing.\n");
1124
 
1125
    munmap((void *)shared_ptr, sizeof(shared_mem_t));
1126
    close(fd);
1127
 
1128
    return 0;
1129
}

powered by: WebSVN 2.1.0

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