msp430-sim.c revision 1.1.1.1
1/* Simulator for TI MSP430 and MSP430X 2 3 Copyright (C) 2013-2014 Free Software Foundation, Inc. 4 Contributed by Red Hat. 5 Based on sim/bfin/bfin-sim.c which was contributed by Analog Devices, Inc. 6 7 This file is part of simulators. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22#include "config.h" 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26#include <inttypes.h> 27#include <assert.h> 28#include "bfd.h" 29#include "opcode/msp430-decode.h" 30#include "sim-main.h" 31#include "dis-asm.h" 32#include "targ-vals.h" 33 34static int 35loader_write_mem (SIM_DESC sd, 36 SIM_ADDR taddr, 37 const unsigned char *buf, 38 int bytes) 39{ 40 SIM_CPU *cpu = MSP430_CPU (sd); 41 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); 42} 43 44static sim_cia 45msp430_pc_fetch (SIM_CPU *cpu) 46{ 47 return cpu->state.regs[0]; 48} 49 50static void 51msp430_pc_store (SIM_CPU *cpu, sim_cia newpc) 52{ 53 cpu->state.regs[0] = newpc; 54} 55 56static long 57lookup_symbol (SIM_DESC sd, const char *name) 58{ 59 struct bfd *abfd = STATE_PROG_BFD (sd); 60 asymbol **symbol_table = STATE_SYMBOL_TABLE (sd); 61 long number_of_symbols = STATE_NUM_SYMBOLS (sd); 62 long i; 63 64 if (symbol_table == NULL) 65 { 66 long storage_needed; 67 68 storage_needed = bfd_get_symtab_upper_bound (abfd); 69 if (storage_needed <= 0) 70 return -1; 71 72 STATE_SYMBOL_TABLE (sd) = symbol_table = xmalloc (storage_needed); 73 STATE_NUM_SYMBOLS (sd) = number_of_symbols = 74 bfd_canonicalize_symtab (abfd, symbol_table); 75 } 76 77 for (i = 0; i < number_of_symbols; i++) 78 if (strcmp (symbol_table[i]->name, name) == 0) 79 { 80 long val = symbol_table[i]->section->vma + symbol_table[i]->value; 81 return val; 82 } 83 return -1; 84} 85 86static int 87msp430_reg_fetch (SIM_CPU *cpu, int regno, unsigned char *buf, int len) 88{ 89 if (0 <= regno && regno < 16) 90 { 91 if (len == 2) 92 { 93 int val = cpu->state.regs[regno]; 94 buf[0] = val & 0xff; 95 buf[1] = (val >> 8) & 0xff; 96 return 0; 97 } 98 else if (len == 4) 99 { 100 int val = cpu->state.regs[regno]; 101 buf[0] = val & 0xff; 102 buf[1] = (val >> 8) & 0xff; 103 buf[2] = (val >> 16) & 0x0f; /* Registers are only 20 bits wide. */ 104 buf[3] = 0; 105 return 0; 106 } 107 else 108 return -1; 109 } 110 else 111 return -1; 112} 113 114static int 115msp430_reg_store (SIM_CPU *cpu, int regno, unsigned char *buf, int len) 116{ 117 if (0 <= regno && regno < 16) 118 { 119 if (len == 2) 120 { 121 cpu->state.regs[regno] = (buf[1] << 8) | buf[0]; 122 return len; 123 } 124 125 if (len == 4) 126 { 127 cpu->state.regs[regno] = ((buf[2] << 16) & 0xf0000) 128 | (buf[1] << 8) | buf[0]; 129 return len; 130 } 131 } 132 133 return -1; 134} 135 136static inline void 137msp430_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu) 138{ 139 memset (&cpu->state, 0, sizeof (cpu->state)); 140} 141 142SIM_DESC 143sim_open (SIM_OPEN_KIND kind, 144 struct host_callback_struct *callback, 145 struct bfd *abfd, 146 char **argv) 147{ 148 SIM_DESC sd = sim_state_alloc (kind, callback); 149 char c; 150 struct bfd *prog_bfd; 151 152 /* Initialise the simulator. */ 153 154 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK) 155 { 156 sim_state_free (sd); 157 return 0; 158 } 159 160 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 161 { 162 sim_state_free (sd); 163 return 0; 164 } 165 166 if (sim_parse_args (sd, argv) != SIM_RC_OK) 167 { 168 sim_state_free (sd); 169 return 0; 170 } 171 172 CPU_PC_FETCH (MSP430_CPU (sd)) = msp430_pc_fetch; 173 CPU_PC_STORE (MSP430_CPU (sd)) = msp430_pc_store; 174 CPU_REG_FETCH (MSP430_CPU (sd)) = msp430_reg_fetch; 175 CPU_REG_STORE (MSP430_CPU (sd)) = msp430_reg_store; 176 177 /* Allocate memory if none specified by user. */ 178 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x200, 1) == 0) 179 sim_do_commandf (sd, "memory-region 0,0x10000"); 180 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0xfffe, 1) == 0) 181 sim_do_commandf (sd, "memory-region 0xfffe,2"); 182 if (sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, &c, 0x10000, 1) == 0) 183 sim_do_commandf (sd, "memory-region 0x10000,0x100000"); 184 185 /* Check for/establish the a reference program image. */ 186 if (sim_analyze_program (sd, 187 (STATE_PROG_ARGV (sd) != NULL 188 ? *STATE_PROG_ARGV (sd) 189 : NULL), abfd) != SIM_RC_OK) 190 { 191 sim_state_free (sd); 192 return 0; 193 } 194 195 prog_bfd = sim_load_file (sd, argv[0], callback, 196 "the program", 197 STATE_PROG_BFD (sd), 198 0 /* verbose */, 199 1 /* use LMA instead of VMA */, 200 loader_write_mem); 201 if (prog_bfd == NULL) 202 { 203 sim_state_free (sd); 204 return 0; 205 } 206 207 /* Establish any remaining configuration options. */ 208 if (sim_config (sd) != SIM_RC_OK) 209 { 210 sim_state_free (sd); 211 return 0; 212 } 213 214 if (sim_post_argv_init (sd) != SIM_RC_OK) 215 { 216 sim_state_free (sd); 217 return 0; 218 } 219 220 /* CPU specific initialization. */ 221 assert (MAX_NR_PROCESSORS == 1); 222 msp430_initialize_cpu (sd, MSP430_CPU (sd)); 223 224 msp430_trace_init (STATE_PROG_BFD (sd)); 225 226 MSP430_CPU (sd)->state.cio_breakpoint = lookup_symbol (sd, "C$$IO$$"); 227 MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "__CIOBUF__"); 228 if (MSP430_CPU (sd)->state.cio_buffer == -1) 229 MSP430_CPU (sd)->state.cio_buffer = lookup_symbol (sd, "_CIOBUF_"); 230 231 return sd; 232} 233 234void 235sim_close (SIM_DESC sd, 236 int quitting) 237{ 238 free (STATE_SYMBOL_TABLE (sd)); 239 sim_state_free (sd); 240} 241 242SIM_RC 243sim_create_inferior (SIM_DESC sd, 244 struct bfd *abfd, 245 char **argv, 246 char **env) 247{ 248 unsigned char resetv[2]; 249 int c; 250 int new_pc; 251 252 c = sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, resetv, 0xfffe, 2); 253 254 new_pc = resetv[0] + 256 * resetv[1]; 255 sim_pc_set (MSP430_CPU (sd), new_pc); 256 msp430_pc_store (MSP430_CPU (sd), new_pc); 257 258 return SIM_RC_OK; 259} 260 261typedef struct 262{ 263 SIM_DESC sd; 264 int gb_addr; 265} Get_Byte_Local_Data; 266 267static int 268msp430_getbyte (void *vld) 269{ 270 Get_Byte_Local_Data *ld = (Get_Byte_Local_Data *)vld; 271 char buf[1]; 272 SIM_DESC sd = ld->sd; 273 274 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, ld->gb_addr, 1); 275 ld->gb_addr ++; 276 return buf[0]; 277} 278 279#define REG(N) MSP430_CPU (sd)->state.regs[(N)] 280#define PC REG(MSR_PC) 281#define SP REG(MSR_SP) 282#define SR REG(MSR_SR) 283 284static const char * 285register_names[] = 286{ 287 "PC", "SP", "SR", "CG", "R4", "R5", "R6", "R7", "R8", 288 "R9", "R10", "R11", "R12", "R13", "R14", "R15" 289}; 290 291static void 292trace_reg_put (SIM_DESC sd, int n, unsigned int v) 293{ 294 if (TRACE_VPU_P (MSP430_CPU (sd))) 295 trace_generic (sd, MSP430_CPU (sd), TRACE_VPU_IDX, 296 "PUT: %#x -> %s", v, register_names [n]); 297 REG (n) = v; 298} 299 300static unsigned int 301trace_reg_get (SIM_DESC sd, int n) 302{ 303 if (TRACE_VPU_P (MSP430_CPU (sd))) 304 trace_generic (sd, MSP430_CPU (sd), TRACE_VPU_IDX, 305 "GET: %s -> %#x", register_names [n], REG (n)); 306 return REG (n); 307} 308 309#define REG_PUT(N,V) trace_reg_put (sd, N, V) 310#define REG_GET(N) trace_reg_get (sd, N) 311 312static int 313get_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n) 314{ 315 MSP430_Opcode_Operand *op = opc->op + n; 316 int rv; 317 int addr; 318 unsigned char buf[4]; 319 int incval = 0; 320 321 switch (op->type) 322 { 323 case MSP430_Operand_Immediate: 324 rv = op->addend; 325 break; 326 case MSP430_Operand_Register: 327 rv = REG_GET (op->reg); 328 break; 329 case MSP430_Operand_Indirect: 330 case MSP430_Operand_Indirect_Postinc: 331 addr = op->addend; 332 if (op->reg != MSR_None) 333 { 334 int reg; 335 /* Index values are signed, but the sum is limited to 16 336 bits if the register < 64k, for MSP430 compatibility in 337 MSP430X chips. */ 338 if (addr & 0x8000) 339 addr |= -1 << 16; 340 reg = REG_GET (op->reg); 341 addr += reg; 342 if (reg < 0x10000 && ! opc->ofs_430x) 343 addr &= 0xffff; 344 } 345 addr &= 0xfffff; 346 switch (opc->size) 347 { 348 case 8: 349 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 1); 350 rv = buf[0]; 351 break; 352 case 16: 353 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 2); 354 rv = buf[0] | (buf[1] << 8); 355 break; 356 case 20: 357 case 32: 358 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, addr, 4); 359 rv = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 360 break; 361 default: 362 assert (! opc->size); 363 break; 364 } 365#if 0 366 /* Hack - MSP430X5438 serial port status register. */ 367 if (addr == 0x5dd) 368 rv = 2; 369#endif 370 if (TRACE_MEMORY_P (MSP430_CPU (sd))) 371 trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX, 372 "GET: [%#x].%d -> %#x", addr, opc->size, rv); 373 break; 374 default: 375 fprintf (stderr, "invalid operand %d type %d\n", n, op->type); 376 abort (); 377 } 378 379 switch (opc->size) 380 { 381 case 8: 382 rv &= 0xff; 383 incval = 1; 384 break; 385 case 16: 386 rv &= 0xffff; 387 incval = 2; 388 break; 389 case 20: 390 rv &= 0xfffff; 391 incval = 4; 392 break; 393 case 32: 394 rv &= 0xffffffff; 395 incval = 4; 396 break; 397 } 398 399 if (op->type == MSP430_Operand_Indirect_Postinc) 400 REG_PUT (op->reg, REG_GET (op->reg) + incval); 401 402 return rv; 403} 404 405static int 406put_op (SIM_DESC sd, MSP430_Opcode_Decoded *opc, int n, int val) 407{ 408 MSP430_Opcode_Operand *op = opc->op + n; 409 int rv; 410 int addr; 411 unsigned char buf[4]; 412 int incval = 0; 413 414 switch (opc->size) 415 { 416 case 8: 417 val &= 0xff; 418 break; 419 case 16: 420 val &= 0xffff; 421 break; 422 case 20: 423 val &= 0xfffff; 424 break; 425 case 32: 426 val &= 0xffffffff; 427 break; 428 } 429 430 switch (op->type) 431 { 432 case MSP430_Operand_Register: 433 REG (op->reg) = val; 434 REG_PUT (op->reg, val); 435 break; 436 case MSP430_Operand_Indirect: 437 case MSP430_Operand_Indirect_Postinc: 438 addr = op->addend; 439 if (op->reg != MSR_None) 440 { 441 int reg; 442 /* Index values are signed, but the sum is limited to 16 443 bits if the register < 64k, for MSP430 compatibility in 444 MSP430X chips. */ 445 if (addr & 0x8000) 446 addr |= -1 << 16; 447 reg = REG_GET (op->reg); 448 addr += reg; 449 if (reg < 0x10000) 450 addr &= 0xffff; 451 } 452 addr &= 0xfffff; 453 454 if (TRACE_MEMORY_P (MSP430_CPU (sd))) 455 trace_generic (sd, MSP430_CPU (sd), TRACE_MEMORY_IDX, 456 "PUT: [%#x].%d <- %#x", addr, opc->size, val); 457#if 0 458 /* Hack - MSP430X5438 serial port transmit register. */ 459 if (addr == 0x5ce) 460 putchar (val); 461#endif 462 switch (opc->size) 463 { 464 case 8: 465 buf[0] = val; 466 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 1); 467 break; 468 case 16: 469 buf[0] = val; 470 buf[1] = val >> 8; 471 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 2); 472 break; 473 case 20: 474 case 32: 475 buf[0] = val; 476 buf[1] = val >> 8; 477 buf[2] = val >> 16; 478 buf[3] = val >> 24; 479 sim_core_write_buffer (sd, MSP430_CPU (sd), write_map, buf, addr, 4); 480 break; 481 default: 482 assert (! opc->size); 483 break; 484 } 485 break; 486 default: 487 fprintf (stderr, "invalid operand %d type %d\n", n, op->type); 488 abort (); 489 } 490 491 switch (opc->size) 492 { 493 case 8: 494 rv &= 0xff; 495 incval = 1; 496 break; 497 case 16: 498 rv &= 0xffff; 499 incval = 2; 500 break; 501 case 20: 502 rv &= 0xfffff; 503 incval = 4; 504 break; 505 case 32: 506 rv &= 0xffffffff; 507 incval = 4; 508 break; 509 } 510 511 if (op->type == MSP430_Operand_Indirect_Postinc) 512 { 513 int new_val = REG_GET (op->reg) + incval; 514 /* SP is always word-aligned. */ 515 if (op->reg == MSR_SP && (new_val & 1)) 516 new_val ++; 517 REG_PUT (op->reg, new_val); 518 } 519 520 return rv; 521} 522 523static void 524mem_put_val (SIM_DESC sd, int addr, int val, int bits) 525{ 526 MSP430_Opcode_Decoded opc; 527 528 opc.size = bits; 529 opc.op[0].type = MSP430_Operand_Indirect; 530 opc.op[0].addend = addr; 531 opc.op[0].reg = MSR_None; 532 put_op (sd, &opc, 0, val); 533} 534 535static int 536mem_get_val (SIM_DESC sd, int addr, int bits) 537{ 538 MSP430_Opcode_Decoded opc; 539 540 opc.size = bits; 541 opc.op[0].type = MSP430_Operand_Indirect; 542 opc.op[0].addend = addr; 543 opc.op[0].reg = MSR_None; 544 return get_op (sd, &opc, 0); 545} 546 547#define CIO_OPEN (0xF0) 548#define CIO_CLOSE (0xF1) 549#define CIO_READ (0xF2) 550#define CIO_WRITE (0xF3) 551#define CIO_LSEEK (0xF4) 552#define CIO_UNLINK (0xF5) 553#define CIO_GETENV (0xF6) 554#define CIO_RENAME (0xF7) 555#define CIO_GETTIME (0xF8) 556#define CIO_GETCLK (0xF9) 557#define CIO_SYNC (0xFF) 558 559#define CIO_I(n) (parms[(n)] + parms[(n)+1] * 256) 560#define CIO_L(n) (parms[(n)] + parms[(n)+1] * 256 \ 561 + parms[(n)+2] * 65536 + parms[(n)+3] * 16777216) 562 563static void 564msp430_cio (SIM_DESC sd) 565{ 566 /* A block of data at __CIOBUF__ describes the I/O operation to 567 perform. */ 568 569 unsigned char raw_parms[13]; 570 unsigned char parms[8]; 571 long length; 572 int command; 573 unsigned char buffer[512]; 574 long ret_buflen = 0; 575 long fd, addr, len, rv; 576 577 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms, 578 MSP430_CPU (sd)->state.cio_buffer, 5); 579 length = CIO_I (0); 580 command = parms[2]; 581 582 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, parms, 583 MSP430_CPU (sd)->state.cio_buffer + 3, 8); 584 585 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, buffer, 586 MSP430_CPU (sd)->state.cio_buffer + 11, length); 587 588 switch (command) 589 { 590 case CIO_WRITE: 591 fd = CIO_I (0); 592 len = CIO_I (2); 593 594 rv = write (fd, buffer, len); 595 parms[0] = rv & 0xff; 596 parms[1] = rv >> 8; 597 598 break; 599 } 600 601 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, parms, 602 MSP430_CPU (sd)->state.cio_buffer + 4, 8); 603 if (ret_buflen) 604 sim_core_write_buffer (sd, MSP430_CPU (sd), 0, buffer, 605 MSP430_CPU (sd)->state.cio_buffer + 12, ret_buflen); 606} 607 608#define SRC get_op (sd, opcode, 1) 609#define DSRC get_op (sd, opcode, 0) 610#define DEST(V) put_op (sd, opcode, 0, (V)) 611 612static int 613msp430_dis_read (bfd_vma memaddr, 614 bfd_byte *myaddr, 615 unsigned int length, 616 struct disassemble_info *dinfo) 617{ 618 SIM_DESC sd = dinfo->private_data; 619 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, myaddr, memaddr, length); 620 return 0; 621} 622 623#define DO_ALU(OP,SOP,MORE) \ 624 { \ 625 int s1 = DSRC; \ 626 int s2 = SRC; \ 627 int result = s1 OP s2 MORE; \ 628 if (TRACE_ALU_P (MSP430_CPU (sd))) \ 629 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, \ 630 "ALU: %#x %s %#x %s = %#x", s1, SOP, s2, #MORE, result); \ 631 DEST (result); \ 632 } 633 634#define SIGN (1 << (opcode->size - 1)) 635#define POS(x) (((x) & SIGN) ? 0 : 1) 636#define NEG(x) (((x) & SIGN) ? 1 : 0) 637 638static int 639zero_ext (int v, int bits) 640{ 641 v &= ((1 << bits) - 1); 642 return v; 643} 644 645static int 646sign_ext (int v, int bits) 647{ 648 int sb = 1 << (bits-1); /* Sign bit. */ 649 int mb = (1 << (bits-1)) - 1; /* Mantissa bits. */ 650 651 if (v & sb) 652 v = v | ~mb; 653 else 654 v = v & mb; 655 return v; 656} 657 658#define SX(v) sign_ext (v, opcode->size) 659#define ZX(v) zero_ext (v, opcode->size) 660 661static char * 662flags2string (int f) 663{ 664 static char buf[2][6]; 665 static int bi = 0; 666 char *bp = buf[bi]; 667 668 bi = (bi + 1) % 2; 669 670 bp[0] = f & MSP430_FLAG_V ? 'V' : '-'; 671 bp[1] = f & MSP430_FLAG_N ? 'N' : '-'; 672 bp[2] = f & MSP430_FLAG_Z ? 'Z' : '-'; 673 bp[3] = f & MSP430_FLAG_C ? 'C' : '-'; 674 bp[4] = 0; 675 return bp; 676} 677 678/* Random number that won't show up in our usual logic. */ 679#define MAGIC_OVERFLOW 0x55000F 680 681static void 682do_flags (SIM_DESC sd, 683 MSP430_Opcode_Decoded *opcode, 684 int vnz_val, /* Signed result. */ 685 int carry, 686 int overflow) 687{ 688 int f = SR; 689 int new_f = 0; 690 int signbit = 1 << (opcode->size - 1); 691 692 f &= ~opcode->flags_0; 693 f &= ~opcode->flags_set; 694 f |= opcode->flags_1; 695 696 if (vnz_val & signbit) 697 new_f |= MSP430_FLAG_N; 698 if (! (vnz_val & ((signbit << 1) - 1))) 699 new_f |= MSP430_FLAG_Z; 700 if (overflow == MAGIC_OVERFLOW) 701 { 702 if (vnz_val != SX (vnz_val)) 703 new_f |= MSP430_FLAG_V; 704 } 705 else 706 if (overflow) 707 new_f |= MSP430_FLAG_V; 708 if (carry) 709 new_f |= MSP430_FLAG_C; 710 711 new_f = f | (new_f & opcode->flags_set); 712 if (TRACE_ALU_P (MSP430_CPU (sd))) 713 { 714 if (SR != new_f) 715 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 716 "FLAGS: %s -> %s", flags2string (SR), 717 flags2string (new_f)); 718 else 719 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 720 "FLAGS: %s", flags2string (new_f)); 721 } 722 SR = new_f; 723} 724 725#define FLAGS(vnz,c) do_flags (sd, opcode, vnz, c, MAGIC_OVERFLOW) 726#define FLAGSV(vnz,c,v) do_flags (sd, opcode, vnz, c, v) 727 728/* These two assume unsigned 16-bit (four digit) words. 729 Mask off unwanted bits for byte operations. */ 730 731static int 732bcd_to_binary (int v) 733{ 734 int r = ( ((v >> 0) & 0xf) * 1 735 + ((v >> 4) & 0xf) * 10 736 + ((v >> 8) & 0xf) * 100 737 + ((v >> 12) & 0xf) * 1000); 738 return r; 739} 740 741static int 742binary_to_bcd (int v) 743{ 744 int r = ( ((v / 1) % 10) << 0 745 | ((v / 10) % 10) << 4 746 | ((v / 100) % 10) << 8 747 | ((v / 1000) % 10) << 12); 748 return r; 749} 750 751static int 752syscall_read_mem (host_callback *cb, struct cb_syscall *sc, 753 unsigned long taddr, char *buf, int bytes) 754{ 755 SIM_DESC sd = (SIM_DESC) sc->p1; 756 SIM_CPU *cpu = (SIM_CPU *) sc->p2; 757 758 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes); 759} 760 761static int 762syscall_write_mem (host_callback *cb, struct cb_syscall *sc, 763 unsigned long taddr, const char *buf, int bytes) 764{ 765 SIM_DESC sd = (SIM_DESC) sc->p1; 766 SIM_CPU *cpu = (SIM_CPU *) sc->p2; 767 768 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes); 769} 770 771static const char * 772cond_string (int cond) 773{ 774 switch (cond) 775 { 776 case MSC_nz: 777 return "NZ"; 778 case MSC_z: 779 return "Z"; 780 case MSC_nc: 781 return "NC"; 782 case MSC_c: 783 return "C"; 784 case MSC_n: 785 return "N"; 786 case MSC_ge: 787 return "GE"; 788 case MSC_l: 789 return "L"; 790 case MSC_true: 791 return "MP"; 792 default: 793 return "??"; 794 } 795} 796 797/* Checks a CALL to address CALL_ADDR. If this is a special 798 syscall address then the call is simulated and non-zero is 799 returned. Otherwise 0 is returned. */ 800 801static int 802maybe_perform_syscall (SIM_DESC sd, int call_addr) 803{ 804 if (call_addr == 0x00160) 805 { 806 int i; 807 808 for (i = 0; i < 16; i++) 809 { 810 if (i % 4 == 0) 811 fprintf (stderr, "\t"); 812 fprintf (stderr, "R%-2d %05x ", i, MSP430_CPU (sd)->state.regs[i]); 813 if (i % 4 == 3) 814 { 815 int sp = SP + (3 - (i / 4)) * 2; 816 unsigned char buf[2]; 817 818 sim_core_read_buffer (sd, MSP430_CPU (sd), read_map, buf, sp, 2); 819 820 fprintf (stderr, "\tSP%+d: %04x", sp - SP, 821 buf[0] + buf[1] * 256); 822 823 if (i / 4 == 0) 824 { 825 int flags = SR; 826 827 fprintf (stderr, flags & 0x100 ? " V" : " -"); 828 fprintf (stderr, flags & 0x004 ? "N" : "-"); 829 fprintf (stderr, flags & 0x002 ? "Z" : "-"); 830 fprintf (stderr, flags & 0x001 ? "C" : "-"); 831 } 832 833 fprintf (stderr, "\n"); 834 } 835 } 836 return 1; 837 } 838 839 if ((call_addr & ~0x3f) == 0x00180) 840 { 841 /* Syscall! */ 842 int syscall_num = call_addr & 0x3f; 843 host_callback *cb = STATE_CALLBACK (sd); 844 CB_SYSCALL sc; 845 846 CB_SYSCALL_INIT (&sc); 847 848 sc.func = syscall_num; 849 sc.arg1 = MSP430_CPU (sd)->state.regs[12]; 850 sc.arg2 = MSP430_CPU (sd)->state.regs[13]; 851 sc.arg3 = MSP430_CPU (sd)->state.regs[14]; 852 sc.arg4 = MSP430_CPU (sd)->state.regs[15]; 853 854 if (TRACE_SYSCALL_P (MSP430_CPU (sd))) 855 { 856 const char *syscall_name = "*unknown*"; 857 858 switch (syscall_num) 859 { 860 case TARGET_SYS_exit: 861 syscall_name = "exit(%d)"; 862 break; 863 case TARGET_SYS_open: 864 syscall_name = "open(%#x,%#x)"; 865 break; 866 case TARGET_SYS_close: 867 syscall_name = "close(%d)"; 868 break; 869 case TARGET_SYS_read: 870 syscall_name = "read(%d,%#x,%d)"; 871 break; 872 case TARGET_SYS_write: 873 syscall_name = "write(%d,%#x,%d)"; 874 break; 875 } 876 trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX, 877 syscall_name, sc.arg1, sc.arg2, sc.arg3, sc.arg4); 878 } 879 880 /* Handle SYS_exit here. */ 881 if (syscall_num == 1) 882 { 883 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 884 MSP430_CPU (sd)->state.regs[0], 885 sim_exited, sc.arg1); 886 return 1; 887 } 888 889 sc.p1 = sd; 890 sc.p2 = MSP430_CPU (sd); 891 sc.read_mem = syscall_read_mem; 892 sc.write_mem = syscall_write_mem; 893 894 cb_syscall (cb, &sc); 895 896 if (TRACE_SYSCALL_P (MSP430_CPU (sd))) 897 trace_generic (sd, MSP430_CPU (sd), TRACE_SYSCALL_IDX, 898 "returns %d", sc.result); 899 900 MSP430_CPU (sd)->state.regs[12] = sc.result; 901 return 1; 902 } 903 904 return 0; 905} 906 907static void 908msp430_step_once (SIM_DESC sd) 909{ 910 Get_Byte_Local_Data ld; 911 unsigned char buf[100]; 912 int i; 913 int opsize; 914 unsigned int opcode_pc; 915 MSP430_Opcode_Decoded opcode_buf; 916 MSP430_Opcode_Decoded *opcode = &opcode_buf; 917 int s1, s2, result; 918 int u1, u2, uresult; 919 int c, reg; 920 int sp; 921 int carry_to_use; 922 int n_repeats; 923 int rept; 924 int op_bytes, op_bits; 925 926 PC &= 0xfffff; 927 opcode_pc = PC; 928 929 if (opcode_pc < 0x10) 930 { 931 fprintf (stderr, "Fault: PC(%#x) is less than 0x10\n", opcode_pc); 932 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 933 MSP430_CPU (sd)->state.regs[0], 934 sim_exited, -1); 935 return; 936 } 937 938 if (PC == MSP430_CPU (sd)->state.cio_breakpoint 939 && STATE_OPEN_KIND (sd) != SIM_OPEN_DEBUG) 940 msp430_cio (sd); 941 942 ld.sd = sd; 943 ld.gb_addr = PC; 944 opsize = msp430_decode_opcode (MSP430_CPU (sd)->state.regs[0], 945 opcode, msp430_getbyte, &ld); 946 PC += opsize; 947 if (opsize <= 0) 948 { 949 fprintf (stderr, "Fault: undecodable opcode at %#x\n", opcode_pc); 950 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 951 MSP430_CPU (sd)->state.regs[0], 952 sim_exited, -1); 953 return; 954 } 955 956 if (opcode->repeat_reg) 957 n_repeats = (MSP430_CPU (sd)->state.regs[opcode->repeats] & 0x000f) + 1; 958 else 959 n_repeats = opcode->repeats + 1; 960 961 op_bits = opcode->size; 962 switch (op_bits) 963 { 964 case 8: 965 op_bytes = 1; 966 break; 967 case 16: 968 op_bytes = 2; 969 break; 970 case 20: 971 case 32: 972 op_bytes = 4; 973 break; 974 } 975 976 if (TRACE_INSN_P (MSP430_CPU (sd))) 977 { 978 disassemble_info info; 979 unsigned char b[10]; 980 981 msp430_trace_one (opcode_pc); 982 983 sim_core_read_buffer (sd, MSP430_CPU (sd), 0, b, opcode_pc, opsize); 984 985 init_disassemble_info (&info, stderr, fprintf); 986 info.private_data = sd; 987 info.read_memory_func = msp430_dis_read; 988 fprintf (stderr, "%#8x ", opcode_pc); 989 for (i = 0; i < opsize; i += 2) 990 fprintf (stderr, " %02x%02x", b[i+1], b[i]); 991 for (; i < 6; i += 2) 992 fprintf (stderr, " "); 993 fprintf (stderr, " "); 994 print_insn_msp430 (opcode_pc, &info); 995 fprintf (stderr, "\n"); 996 fflush (stdout); 997 } 998 999 if (TRACE_ANY_P (MSP430_CPU (sd))) 1000 trace_prefix (sd, MSP430_CPU (sd), NULL_CIA, opcode_pc, 1001 TRACE_LINENUM_P (MSP430_CPU (sd)), NULL, 0, ""); 1002 1003 carry_to_use = 0; 1004 switch (opcode->id) 1005 { 1006 case MSO_unknown: 1007 break; 1008 1009 /* Double-operand instructions. */ 1010 case MSO_mov: 1011 if (opcode->n_bytes == 2 1012 && opcode->op[0].type == MSP430_Operand_Register 1013 && opcode->op[0].reg == MSR_CG 1014 && opcode->op[1].type == MSP430_Operand_Immediate 1015 && opcode->op[1].addend == 0 1016 /* A 16-bit write of #0 is a NOP; an 8-bit write is a BRK. */ 1017 && opcode->size == 8) 1018 { 1019 /* This is the designated software breakpoint instruction. */ 1020 PC -= opsize; 1021 sim_engine_halt (sd, MSP430_CPU (sd), NULL, 1022 MSP430_CPU (sd)->state.regs[0], 1023 sim_stopped, SIM_SIGTRAP); 1024 1025 } 1026 else 1027 { 1028 /* Otherwise, do the move. */ 1029 for (rept = 0; rept < n_repeats; rept ++) 1030 { 1031 DEST (SRC); 1032 } 1033 } 1034 break; 1035 1036 case MSO_addc: 1037 for (rept = 0; rept < n_repeats; rept ++) 1038 { 1039 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0; 1040 u1 = DSRC; 1041 u2 = SRC; 1042 s1 = SX (u1); 1043 s2 = SX (u2); 1044 uresult = u1 + u2 + carry_to_use; 1045 result = s1 + s2 + carry_to_use; 1046 if (TRACE_ALU_P (MSP430_CPU (sd))) 1047 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1048 "ADDC: %#x + %#x + %d = %#x", 1049 u1, u2, carry_to_use, uresult); 1050 DEST (result); 1051 FLAGS (result, uresult != ZX (uresult)); 1052 } 1053 break; 1054 1055 case MSO_add: 1056 for (rept = 0; rept < n_repeats; rept ++) 1057 { 1058 u1 = DSRC; 1059 u2 = SRC; 1060 s1 = SX (u1); 1061 s2 = SX (u2); 1062 uresult = u1 + u2; 1063 result = s1 + s2; 1064 if (TRACE_ALU_P (MSP430_CPU (sd))) 1065 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1066 "ADD: %#x + %#x = %#x", 1067 u1, u2, uresult); 1068 DEST (result); 1069 FLAGS (result, uresult != ZX (uresult)); 1070 } 1071 break; 1072 1073 case MSO_subc: 1074 for (rept = 0; rept < n_repeats; rept ++) 1075 { 1076 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0; 1077 u1 = DSRC; 1078 u2 = SRC; 1079 s1 = SX (u1); 1080 s2 = SX (u2); 1081 uresult = ZX (~u2) + u1 + carry_to_use; 1082 result = s1 - s2 + (carry_to_use - 1); 1083 if (TRACE_ALU_P (MSP430_CPU (sd))) 1084 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1085 "SUBC: %#x - %#x + %d = %#x", 1086 u1, u2, carry_to_use, uresult); 1087 DEST (result); 1088 FLAGS (result, uresult != ZX (uresult)); 1089 } 1090 break; 1091 1092 case MSO_sub: 1093 for (rept = 0; rept < n_repeats; rept ++) 1094 { 1095 u1 = DSRC; 1096 u2 = SRC; 1097 s1 = SX (u1); 1098 s2 = SX (u2); 1099 uresult = ZX (~u2) + u1 + 1; 1100 result = SX (uresult); 1101 if (TRACE_ALU_P (MSP430_CPU (sd))) 1102 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1103 "SUB: %#x - %#x = %#x", 1104 u1, u2, uresult); 1105 DEST (result); 1106 FLAGS (result, uresult != ZX (uresult)); 1107 } 1108 break; 1109 1110 case MSO_cmp: 1111 for (rept = 0; rept < n_repeats; rept ++) 1112 { 1113 u1 = DSRC; 1114 u2 = SRC; 1115 s1 = SX (u1); 1116 s2 = SX (u2); 1117 uresult = ZX (~u2) + u1 + 1; 1118 result = s1 - s2; 1119 if (TRACE_ALU_P (MSP430_CPU (sd))) 1120 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1121 "CMP: %#x - %#x = %x", 1122 u1, u2, uresult); 1123 FLAGS (result, uresult != ZX (uresult)); 1124 } 1125 break; 1126 1127 case MSO_dadd: 1128 for (rept = 0; rept < n_repeats; rept ++) 1129 { 1130 carry_to_use = (SR & MSP430_FLAG_C) ? 1 : 0; 1131 u1 = DSRC; 1132 u2 = SRC; 1133 uresult = bcd_to_binary (u1) + bcd_to_binary (u2) + carry_to_use; 1134 result = binary_to_bcd (uresult); 1135 if (TRACE_ALU_P (MSP430_CPU (sd))) 1136 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1137 "DADD: %#x + %#x + %d = %#x", 1138 u1, u2, carry_to_use, result); 1139 DEST (result); 1140 FLAGS (result, uresult > ((opcode->size == 8) ? 99 : 9999)); 1141 } 1142 break; 1143 1144 case MSO_and: 1145 for (rept = 0; rept < n_repeats; rept ++) 1146 { 1147 u1 = DSRC; 1148 u2 = SRC; 1149 uresult = u1 & u2; 1150 if (TRACE_ALU_P (MSP430_CPU (sd))) 1151 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1152 "AND: %#x & %#x = %#x", 1153 u1, u2, uresult); 1154 DEST (uresult); 1155 FLAGS (uresult, uresult != 0); 1156 } 1157 break; 1158 1159 case MSO_bit: 1160 for (rept = 0; rept < n_repeats; rept ++) 1161 { 1162 u1 = DSRC; 1163 u2 = SRC; 1164 uresult = u1 & u2; 1165 if (TRACE_ALU_P (MSP430_CPU (sd))) 1166 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1167 "BIT: %#x & %#x -> %#x", 1168 u1, u2, uresult); 1169 FLAGS (uresult, uresult != 0); 1170 } 1171 break; 1172 1173 case MSO_bic: 1174 for (rept = 0; rept < n_repeats; rept ++) 1175 { 1176 u1 = DSRC; 1177 u2 = SRC; 1178 uresult = u1 & ~ u2; 1179 if (TRACE_ALU_P (MSP430_CPU (sd))) 1180 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1181 "BIC: %#x & ~ %#x = %#x", 1182 u1, u2, uresult); 1183 DEST (uresult); 1184 } 1185 break; 1186 1187 case MSO_bis: 1188 for (rept = 0; rept < n_repeats; rept ++) 1189 { 1190 u1 = DSRC; 1191 u2 = SRC; 1192 uresult = u1 | u2; 1193 if (TRACE_ALU_P (MSP430_CPU (sd))) 1194 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1195 "BIS: %#x | %#x = %#x", 1196 u1, u2, uresult); 1197 DEST (uresult); 1198 } 1199 break; 1200 1201 case MSO_xor: 1202 for (rept = 0; rept < n_repeats; rept ++) 1203 { 1204 s1 = 1 << (opcode->size - 1); 1205 u1 = DSRC; 1206 u2 = SRC; 1207 uresult = u1 ^ u2; 1208 if (TRACE_ALU_P (MSP430_CPU (sd))) 1209 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1210 "XOR: %#x & %#x = %#x", 1211 u1, u2, uresult); 1212 DEST (uresult); 1213 FLAGSV (uresult, uresult != 0, (u1 & s1) && (u2 & s1)); 1214 } 1215 break; 1216 1217 /* Single-operand instructions. Note: the decoder puts the same 1218 operand in SRC as in DEST, for our convenience. */ 1219 1220 case MSO_rrc: 1221 for (rept = 0; rept < n_repeats; rept ++) 1222 { 1223 u1 = SRC; 1224 carry_to_use = u1 & 1; 1225 uresult = u1 >> 1; 1226 if (SR & MSP430_FLAG_C) 1227 uresult |= (1 << (opcode->size - 1)); 1228 if (TRACE_ALU_P (MSP430_CPU (sd))) 1229 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1230 "RRC: %#x >>= %#x", 1231 u1, uresult); 1232 DEST (uresult); 1233 FLAGS (uresult, carry_to_use); 1234 } 1235 break; 1236 1237 case MSO_swpb: 1238 for (rept = 0; rept < n_repeats; rept ++) 1239 { 1240 u1 = SRC; 1241 uresult = ((u1 >> 8) & 0x00ff) | ((u1 << 8) & 0xff00); 1242 if (TRACE_ALU_P (MSP430_CPU (sd))) 1243 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1244 "SWPB: %#x -> %#x", 1245 u1, uresult); 1246 DEST (uresult); 1247 } 1248 break; 1249 1250 case MSO_rra: 1251 for (rept = 0; rept < n_repeats; rept ++) 1252 { 1253 u1 = SRC; 1254 c = u1 & 1; 1255 s1 = 1 << (opcode->size - 1); 1256 uresult = (u1 >> 1) | (u1 & s1); 1257 if (TRACE_ALU_P (MSP430_CPU (sd))) 1258 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1259 "RRA: %#x >>= %#x", 1260 u1, uresult); 1261 DEST (uresult); 1262 FLAGS (uresult, c); 1263 } 1264 break; 1265 1266 case MSO_rru: 1267 for (rept = 0; rept < n_repeats; rept ++) 1268 { 1269 u1 = SRC; 1270 c = u1 & 1; 1271 uresult = (u1 >> 1); 1272 if (TRACE_ALU_P (MSP430_CPU (sd))) 1273 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1274 "RRU: %#x >>= %#x", 1275 u1, uresult); 1276 DEST (uresult); 1277 FLAGS (uresult, c); 1278 } 1279 break; 1280 1281 case MSO_sxt: 1282 for (rept = 0; rept < n_repeats; rept ++) 1283 { 1284 u1 = SRC; 1285 if (u1 & 0x80) 1286 uresult = u1 | 0xfff00; 1287 else 1288 uresult = u1 & 0x000ff; 1289 if (TRACE_ALU_P (MSP430_CPU (sd))) 1290 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1291 "SXT: %#x -> %#x", 1292 u1, uresult); 1293 DEST (uresult); 1294 FLAGS (uresult, c); 1295 } 1296 break; 1297 1298 case MSO_push: 1299 for (rept = 0; rept < n_repeats; rept ++) 1300 { 1301 int new_sp; 1302 1303 new_sp = REG_GET (MSR_SP) - op_bytes; 1304 /* SP is always word-aligned. */ 1305 if (new_sp & 1) 1306 new_sp --; 1307 REG_PUT (MSR_SP, new_sp); 1308 u1 = SRC; 1309 mem_put_val (sd, SP, u1, op_bits); 1310 if (opcode->op[1].type == MSP430_Operand_Register) 1311 opcode->op[1].reg --; 1312 } 1313 break; 1314 1315 case MSO_pop: 1316 for (rept = 0; rept < n_repeats; rept ++) 1317 { 1318 int new_sp; 1319 1320 u1 = mem_get_val (sd, SP, op_bits); 1321 DEST (u1); 1322 if (opcode->op[0].type == MSP430_Operand_Register) 1323 opcode->op[0].reg ++; 1324 new_sp = REG_GET (MSR_SP) + op_bytes; 1325 /* SP is always word-aligned. */ 1326 if (new_sp & 1) 1327 new_sp ++; 1328 REG_PUT (MSR_SP, new_sp); 1329 } 1330 break; 1331 1332 case MSO_call: 1333 u1 = SRC; 1334 1335 if (maybe_perform_syscall (sd, u1)) 1336 break; 1337 1338 REG_PUT (MSR_SP, REG_GET (MSR_SP) - op_bytes); 1339 mem_put_val (sd, SP, PC, op_bits); 1340 if (TRACE_ALU_P (MSP430_CPU (sd))) 1341 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1342 "CALL: func %#x ret %#x, sp %#x", 1343 u1, PC, SP); 1344 REG_PUT (MSR_PC, u1); 1345 break; 1346 1347 case MSO_reti: 1348 SR = mem_get_val (sd, SP, op_bits); 1349 SP += 2; 1350 PC = mem_get_val (sd, SP, op_bits); 1351 SP += 2; 1352 if (TRACE_ALU_P (MSP430_CPU (sd))) 1353 trace_generic (sd, MSP430_CPU (sd), TRACE_ALU_IDX, 1354 "RETI: pc %#x sr %#x", 1355 PC, SR); 1356 break; 1357 1358 /* Jumps. */ 1359 1360 case MSO_jmp: 1361 i = SRC; 1362 switch (opcode->cond) 1363 { 1364 case MSC_nz: 1365 u1 = (SR & MSP430_FLAG_Z) ? 0 : 1; 1366 break; 1367 case MSC_z: 1368 u1 = (SR & MSP430_FLAG_Z) ? 1 : 0; 1369 break; 1370 case MSC_nc: 1371 u1 = (SR & MSP430_FLAG_C) ? 0 : 1; 1372 break; 1373 case MSC_c: 1374 u1 = (SR & MSP430_FLAG_C) ? 1 : 0; 1375 break; 1376 case MSC_n: 1377 u1 = (SR & MSP430_FLAG_N) ? 1 : 0; 1378 break; 1379 case MSC_ge: 1380 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 1 : 0; 1381 break; 1382 case MSC_l: 1383 u1 = (!!(SR & MSP430_FLAG_N) == !!(SR & MSP430_FLAG_V)) ? 0 : 1; 1384 break; 1385 case MSC_true: 1386 u1 = 1; 1387 break; 1388 } 1389 1390 if (u1) 1391 { 1392 if (TRACE_BRANCH_P (MSP430_CPU (sd))) 1393 trace_generic (sd, MSP430_CPU (sd), TRACE_BRANCH_IDX, 1394 "J%s: pc %#x -> %#x sr %#x, taken", 1395 cond_string (opcode->cond), PC, i, SR); 1396 PC = i; 1397 if (PC == opcode_pc) 1398 exit (0); 1399 } 1400 else 1401 if (TRACE_BRANCH_P (MSP430_CPU (sd))) 1402 trace_generic (sd, MSP430_CPU (sd), TRACE_BRANCH_IDX, 1403 "J%s: pc %#x to %#x sr %#x, not taken", 1404 cond_string (opcode->cond), PC, i, SR); 1405 break; 1406 1407 default: 1408 fprintf (stderr, "error: unexpected opcode id %d\n", opcode->id); 1409 exit (1); 1410 } 1411} 1412 1413void 1414sim_engine_run (SIM_DESC sd, 1415 int next_cpu_nr, 1416 int nr_cpus, 1417 int siggnal) 1418{ 1419 while (1) 1420 { 1421 msp430_step_once (sd); 1422 if (sim_events_tick (sd)) 1423 sim_events_process (sd); 1424 } 1425} 1426