From patchwork Mon Nov 16 03:14:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Frysinger X-Patchwork-Id: 9679 X-Patchwork-Delegate: vapier@gentoo.org Received: (qmail 59950 invoked by alias); 16 Nov 2015 03:18:59 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 59881 invoked by uid 89); 16 Nov 2015 03:18:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: smtp.gentoo.org Received: from smtp.gentoo.org (HELO smtp.gentoo.org) (140.211.166.183) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 16 Nov 2015 03:18:48 +0000 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.gentoo.org (Postfix) with ESMTP id 348D134085D for ; Mon, 16 Nov 2015 03:18:46 +0000 (UTC) From: Mike Frysinger To: gdb-patches@sourceware.org Subject: [PATCH 4/6] sim: cr16: convert to common sim memory modules [committed] Date: Sun, 15 Nov 2015 22:14:40 -0500 Message-Id: <1447643682-3812-4-git-send-email-vapier@gentoo.org> In-Reply-To: <1447643682-3812-1-git-send-email-vapier@gentoo.org> References: <1447643682-3812-1-git-send-email-vapier@gentoo.org> X-IsSubscribed: yes The cr16 port has a lot of translation/offset logic baked into it, but it all looks like copy & paste from the d10v port rather than something the cr16 port wants. --- include/gdb/ChangeLog | 6 + include/gdb/sim-cr16.h | 9 - sim/cr16/ChangeLog | 28 +++ sim/cr16/Makefile.in | 5 +- sim/cr16/configure | 6 +- sim/cr16/configure.ac | 4 +- sim/cr16/cr16_sim.h | 68 ++----- sim/cr16/endian.c | 55 ------ sim/cr16/interp.c | 483 ++----------------------------------------------- sim/cr16/simops.c | 2 +- 10 files changed, 68 insertions(+), 598 deletions(-) delete mode 100644 sim/cr16/endian.c diff --git a/include/gdb/ChangeLog b/include/gdb/ChangeLog index eae0cf1..67f430f 100644 --- a/include/gdb/ChangeLog +++ b/include/gdb/ChangeLog @@ -1,3 +1,9 @@ +2015-11-15 Mike Frysinger + + * sim-cr16.h (SIM_CR16_MEMORY_UNIFIED, SIM_CR16_MEMORY_INSN, + SIM_CR16_MEMORY_DATA, SIM_CR16_MEMORY_DMAP, SIM_CR16_MEMORY_IMAP): + Delete. + 2015-11-14 Mike Frysinger * sim-arm.h: Delete __cplusplus checks and extern "C" linkage. diff --git a/include/gdb/sim-cr16.h b/include/gdb/sim-cr16.h index 2f41303..a008977 100644 --- a/include/gdb/sim-cr16.h +++ b/include/gdb/sim-cr16.h @@ -20,15 +20,6 @@ #if !defined (SIM_CR16_H) #define SIM_CR16_H -enum - { - SIM_CR16_MEMORY_UNIFIED = 0x00000000, - SIM_CR16_MEMORY_INSN = 0x10000000, - SIM_CR16_MEMORY_DATA = 0x10000000, - SIM_CR16_MEMORY_DMAP = 0x10000000, - SIM_CR16_MEMORY_IMAP = 0x10000000 - }; - /* The simulator makes use of the following register information. */ enum sim_cr16_regs diff --git a/sim/cr16/ChangeLog b/sim/cr16/ChangeLog index 00169ee..5d03dc3 100644 --- a/sim/cr16/ChangeLog +++ b/sim/cr16/ChangeLog @@ -1,5 +1,33 @@ 2015-11-15 Mike Frysinger + * Makefile.in (SIM_OBJS): Delete endian.o. + (INCLUDE): Delete endian.c. + * configure.ac (SIM_AC_OPTION_ENDIAN): Declare little endian. + (SIM_AC_OPTION_ALIGNMENT): release unaligned loads. + * configure: Regenerate. + * cr16_sim.h (IMAP_BLOCK_SIZE, DMAP_BLOCK_SIZE, SEGMENT_SIZE, + IMEM_SEGMENTS, DMEM_SEGMENTS, UMEM_SEGMENTS, cr16_memory, dmem_addr, + imem_addr, decode_pc, get_longword, get_word, write_word, + write_longword, READ_16): Delete. + (struct _state): Delete mem member. + (endian.c): Delete include. + (SB, RB, SW, RW, SLW): Rewrite to use sim-core functions. + (get_longword): New function. + (RLW): Rewrite to use get_longword. + * endian.c: Delete file. + * interp.c (map_memory, sim_size, last_segname, last_from, last_to, + IMAP0_OFFSET, DMAP0_OFFSET, DMAP2_SHADDOW, DMAP2_OFFSET, + dmap_register, imap_register, sim_cr16_translate_dmap_addr, + sim_cr16_translate_imap_addr, sim_cr16_translate_addr, map_memory, + xfer_mem, sim_write, sim_read, dmem_addr, imem_addr): Delete. + (do_run): Delete iaddr and replace imem_addr/get_longword with RW. + (sim_open): Call sim_do_commandf. Delete sim_size call. + (sim_resume): Delete iaddr and replace imem_addr/get_longword with + RLW. + * simops.c (MEMPTR): Rewrite to use sim_core_trans_addr. + +2015-11-15 Mike Frysinger + * cr16_sim.h (struct simops): Add SIM_DESC and SIM_CPU to func args. (SET_CREG, SET_HW_CREG, SET_PSR_BIT): Pass sd and cpu to move_to_cr. (dmem_addr, imem_addr, move_to_cr): Add SIM_DESC and SIM_CPU args. diff --git a/sim/cr16/Makefile.in b/sim/cr16/Makefile.in index 07fa819..f9b52ad 100644 --- a/sim/cr16/Makefile.in +++ b/sim/cr16/Makefile.in @@ -23,11 +23,10 @@ SIM_OBJS = \ sim-reg.o \ interp.o \ table.o \ - simops.o \ - endian.o + simops.o SIM_EXTRA_CLEAN = clean-extra -INCLUDE = cr16_sim.h $(srcroot)/include/gdb/callback.h targ-vals.h endian.c \ +INCLUDE = cr16_sim.h $(srcroot)/include/gdb/callback.h targ-vals.h \ $(srcroot)/include/gdb/sim-cr16.h # This selects the cr16 newlib/libgloss syscall definitions. diff --git a/sim/cr16/configure b/sim/cr16/configure index 215f0c4..b44e895 100755 --- a/sim/cr16/configure +++ b/sim/cr16/configure @@ -12914,7 +12914,7 @@ sim_link_links="${sim_link_links} targ-vals.def" -wire_endian="" +wire_endian="LITTLE_ENDIAN" default_endian="" # Check whether --enable-sim-endian was given. if test "${enable_sim_endian+set}" = set; then : @@ -12958,8 +12958,8 @@ else fi fi -wire_alignment="STRICT_ALIGNMENT" -default_alignment="STRICT_ALIGNMENT" +wire_alignment="NONSTRICT_ALIGNMENT" +default_alignment="" # Check whether --enable-sim-alignment was given. if test "${enable_sim_alignment+set}" = set; then : diff --git a/sim/cr16/configure.ac b/sim/cr16/configure.ac index 96d0ffd..ebf8bd3 100644 --- a/sim/cr16/configure.ac +++ b/sim/cr16/configure.ac @@ -5,8 +5,8 @@ sinclude(../common/acinclude.m4) SIM_AC_COMMON -SIM_AC_OPTION_ENDIAN -SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT,STRICT_ALIGNMENT) +SIM_AC_OPTION_ENDIAN(LITTLE_ENDIAN) +SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT) SIM_AC_OPTION_HOSTENDIAN SIM_AC_OPTION_ENVIRONMENT SIM_AC_OPTION_INLINE diff --git a/sim/cr16/cr16_sim.h b/sim/cr16/cr16_sim.h index 5167ade..d70ce14 100644 --- a/sim/cr16/cr16_sim.h +++ b/sim/cr16/cr16_sim.h @@ -198,37 +198,6 @@ enum { } \ while (0) -/* cr16 memory: There are three separate cr16 memory regions IMEM, - UMEM and DMEM. The IMEM and DMEM are further broken down into - blocks (very like VM pages). */ - -enum -{ - IMAP_BLOCK_SIZE = 0x2000000, - DMAP_BLOCK_SIZE = 0x4000000 -}; - -/* Implement the three memory regions using sparse arrays. Allocate - memory using ``segments''. A segment must be at least as large as - a BLOCK - ensures that an access that doesn't cross a block - boundary can't cross a segment boundary */ - -enum -{ - SEGMENT_SIZE = 0x2000000, /* 128KB - MAX(IMAP_BLOCK_SIZE,DMAP_BLOCK_SIZE) */ - IMEM_SEGMENTS = 8, /* 1MB */ - DMEM_SEGMENTS = 8, /* 1MB */ - UMEM_SEGMENTS = 128 /* 16MB */ -}; - -struct cr16_memory -{ - uint8 *insn[IMEM_SEGMENTS]; - uint8 *data[DMEM_SEGMENTS]; - uint8 *unif[UMEM_SEGMENTS]; - uint8 fault[16]; -}; - struct _state { creg_t regs[16]; /* general-purpose registers */ @@ -274,8 +243,6 @@ struct _state /* NOTE: everything below this line is not reset by sim_create_inferior() */ - struct cr16_memory mem; - enum _ins_type ins_type; } State; @@ -421,30 +388,19 @@ enum /* sign-extend a 32-bit number */ #define SEXT32(x) ((((x)&0xffffffff)^(~0x7fffffff))+0x80000000) -extern uint8 *dmem_addr (SIM_DESC, SIM_CPU *, uint32 offset); -extern uint8 *imem_addr (SIM_DESC, SIM_CPU *, uint32); -extern bfd_vma decode_pc (void); - -#define RB(x) (*(dmem_addr (sd, cpu, x))) -#define SB(addr,data) ( RB(addr) = (data & 0xff)) +#define SB(addr, data) sim_core_write_1 (cpu, PC, read_map, addr, data) +#define RB(addr) sim_core_read_1 (cpu, PC, read_map, addr) +#define SW(addr, data) sim_core_write_unaligned_2 (cpu, PC, read_map, addr, data) +#define RW(addr) sim_core_read_unaligned_2 (cpu, PC, read_map, addr) +#define SLW(addr, data) sim_core_write_unaligned_4 (cpu, PC, read_map, addr, data) -#if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(NO_ENDIAN_INLINE) -#define ENDIAN_INLINE static __inline__ -#include "endian.c" -#undef ENDIAN_INLINE - -#else -extern uint32 get_longword (uint8 *); -extern uint16 get_word (uint8 *); -extern void write_word (uint8 *addr, uint16 data); -extern void write_longword (uint8 *addr, uint32 data); -#endif - -#define SW(addr,data) write_word (dmem_addr (sd, cpu, addr), data) -#define RW(x) get_word (dmem_addr (sd, cpu, x)) -#define SLW(addr,data) write_longword (dmem_addr (sd, cpu, addr), data) -#define RLW(x) get_longword (dmem_addr (sd, cpu, x)) -#define READ_16(x) get_word(x) +/* Yes, this is as whacked as it looks. The sim currently reads little endian + for 16 bits, but then merge them like big endian to get 32 bits. */ +static inline uint32 get_longword (SIM_CPU *cpu, address_word addr) +{ + return (RW (addr) << 16) | RW (addr + 2); +} +#define RLW(addr) get_longword (cpu, addr) #define JMP(x) do { SET_PC (x); State.pc_changed = 1; } while (0) diff --git a/sim/cr16/endian.c b/sim/cr16/endian.c deleted file mode 100644 index de8c874..0000000 --- a/sim/cr16/endian.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Simulation code for the CR16 processor. - Copyright (C) 2008-2015 Free Software Foundation, Inc. - Contributed by M Ranga Swami Reddy - - This file is part of GDB, the GNU debugger. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - - -/* If we're being compiled as a .c file, rather than being included in - cr16_sim.h, then ENDIAN_INLINE won't be defined yet. */ - -#ifndef ENDIAN_INLINE -#define NO_ENDIAN_INLINE -#include "sim-main.h" -#define ENDIAN_INLINE -#endif - -ENDIAN_INLINE uint16 -get_word (uint8 *x) -{ - return *(uint16 *)x; -} - -ENDIAN_INLINE uint32 -get_longword (uint8 *x) -{ - return (((uint32) *(uint16 *)x) << 16) | ((uint32) *(uint16 *)(x+2)); -} - -ENDIAN_INLINE void -write_word (uint8 *addr, uint16 data) -{ - addr[1] = (data >> 8) & 0xff; - addr[0] = data & 0xff; - -} - -ENDIAN_INLINE void -write_longword (uint8 *addr, uint32 data) -{ - *(uint16 *)(addr + 2) = (uint16)(data >> 16); - *(uint16 *)(addr) = (uint16)data; -} diff --git a/sim/cr16/interp.c b/sim/cr16/interp.c index 7f5e044..478cd9b 100644 --- a/sim/cr16/interp.c +++ b/sim/cr16/interp.c @@ -42,7 +42,6 @@ uint32 sign_flag; static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint64 ins, int size); static void get_operands (operand_desc *s, uint64 mcode, int isize, int nops); -static INLINE uint8 *map_memory (SIM_DESC, SIM_CPU *, unsigned phys_addr); #define MAX_HASH 16 @@ -335,7 +334,6 @@ do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode) struct simops *s= Simops; struct hash_entry *h; char func[12]="\0"; - uint8 *iaddr; #ifdef DEBUG if ((cr16_debug & DEBUG_INSTRUCTION) != 0) (*cr16_callback->printf_filtered) (cr16_callback, "do_long 0x%x\n", mcode); @@ -346,11 +344,8 @@ do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode) if ((h == NULL) || (h->opcode == 0)) return 0; - if (h->size == 3) - { - iaddr = imem_addr (sd, cpu, (uint32)PC + 2); - mcode = (mcode << 16) | get_longword( iaddr ); - } + if (h->size == 3) + mcode = (mcode << 16) | RW (PC + 4); /* Re-set OP list. */ OP[0] = OP[1] = OP[2] = OP[3] = sign_flag = 0; @@ -370,389 +365,6 @@ do_run (SIM_DESC sd, SIM_CPU *cpu, uint64 mcode) return h->size; } -static void -sim_size (int power) -{ - int i; - for (i = 0; i < IMEM_SEGMENTS; i++) - { - if (State.mem.insn[i]) - free (State.mem.insn[i]); - } - for (i = 0; i < DMEM_SEGMENTS; i++) - { - if (State.mem.data[i]) - free (State.mem.data[i]); - } - for (i = 0; i < UMEM_SEGMENTS; i++) - { - if (State.mem.unif[i]) - free (State.mem.unif[i]); - } - /* Always allocate dmem segment 0. This contains the IMAP and DMAP - registers. */ - State.mem.data[0] = calloc (1, SEGMENT_SIZE); -} - -/* For tracing - leave info on last access around. */ -static char *last_segname = "invalid"; -static char *last_from = "invalid"; -static char *last_to = "invalid"; - -enum - { - IMAP0_OFFSET = 0xff00, - DMAP0_OFFSET = 0xff08, - DMAP2_SHADDOW = 0xff04, - DMAP2_OFFSET = 0xff0c - }; - -static unsigned long -dmap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr) -{ - uint8 *raw = map_memory (sd, cpu, SIM_CR16_MEMORY_DATA - + DMAP0_OFFSET + 2 * reg_nr); - return READ_16 (raw); -} - -static unsigned long -imap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr) -{ - uint8 *raw = map_memory (sd, cpu, SIM_CR16_MEMORY_DATA - + IMAP0_OFFSET + 2 * reg_nr); - return READ_16 (raw); -} - -/* Given a virtual address in the DMAP address space, translate it - into a physical address. */ - -static unsigned long -sim_cr16_translate_dmap_addr (SIM_DESC sd, - SIM_CPU *cpu, - unsigned long offset, - int nr_bytes, - unsigned long *phys, - void *regcache, - unsigned long (*dmap_register) (SIM_DESC, - SIM_CPU *, - void *regcache, - int reg_nr)) -{ - short map; - int regno; - last_from = "logical-data"; - if (offset >= DMAP_BLOCK_SIZE * SIM_CR16_NR_DMAP_REGS) - { - /* Logical address out side of data segments, not supported */ - return 0; - } - regno = (offset / DMAP_BLOCK_SIZE); - offset = (offset % DMAP_BLOCK_SIZE); - -#if 1 - if ((offset % DMAP_BLOCK_SIZE) + nr_bytes > DMAP_BLOCK_SIZE) - { - /* Don't cross a BLOCK boundary */ - nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE); - } - map = dmap_register (sd, cpu, regcache, regno); - if (regno == 3) - { - /* Always maps to data memory */ - int iospi = (offset / 0x1000) % 4; - int iosp = (map >> (4 * (3 - iospi))) % 0x10; - last_to = "io-space"; - *phys = (SIM_CR16_MEMORY_DATA + (iosp * 0x10000) + 0xc000 + offset); - } - else - { - int sp = ((map & 0x3000) >> 12); - int segno = (map & 0x3ff); - switch (sp) - { - case 0: /* 00: Unified memory */ - *phys = SIM_CR16_MEMORY_UNIFIED + (segno * DMAP_BLOCK_SIZE) + offset; - last_to = "unified"; - break; - case 1: /* 01: Instruction Memory */ - *phys = SIM_CR16_MEMORY_INSN + (segno * DMAP_BLOCK_SIZE) + offset; - last_to = "chip-insn"; - break; - case 2: /* 10: Internal data memory */ - *phys = SIM_CR16_MEMORY_DATA + (segno << 16) + (regno * DMAP_BLOCK_SIZE) + offset; - last_to = "chip-data"; - break; - case 3: /* 11: Reserved */ - return 0; - } - } -#endif - return nr_bytes; -} - -/* Given a virtual address in the IMAP address space, translate it - into a physical address. */ - -static unsigned long -sim_cr16_translate_imap_addr (SIM_DESC sd, - SIM_CPU *cpu, - unsigned long offset, - int nr_bytes, - unsigned long *phys, - void *regcache, - unsigned long (*imap_register) (SIM_DESC, - SIM_CPU *, - void *regcache, - int reg_nr)) -{ - short map; - int regno; - int sp; - int segno; - last_from = "logical-insn"; - if (offset >= (IMAP_BLOCK_SIZE * SIM_CR16_NR_IMAP_REGS)) - { - /* Logical address outside of IMAP segments, not supported */ - return 0; - } - regno = (offset / IMAP_BLOCK_SIZE); - offset = (offset % IMAP_BLOCK_SIZE); - if (offset + nr_bytes > IMAP_BLOCK_SIZE) - { - /* Don't cross a BLOCK boundary */ - nr_bytes = IMAP_BLOCK_SIZE - offset; - } - map = imap_register (sd, cpu, regcache, regno); - sp = (map & 0x3000) >> 12; - segno = (map & 0x007f); - switch (sp) - { - case 0: /* 00: unified memory */ - *phys = SIM_CR16_MEMORY_UNIFIED + (segno << 17) + offset; - last_to = "unified"; - break; - case 1: /* 01: instruction memory */ - *phys = SIM_CR16_MEMORY_INSN + (IMAP_BLOCK_SIZE * regno) + offset; - last_to = "chip-insn"; - break; - case 2: /*10*/ - /* Reserved. */ - return 0; - case 3: /* 11: for testing - instruction memory */ - offset = (offset % 0x800); - *phys = SIM_CR16_MEMORY_INSN + offset; - if (offset + nr_bytes > 0x800) - /* don't cross VM boundary */ - nr_bytes = 0x800 - offset; - last_to = "test-insn"; - break; - } - return nr_bytes; -} - -static unsigned long -sim_cr16_translate_addr (SIM_DESC sd, - SIM_CPU *cpu, - unsigned long memaddr, - int nr_bytes, - unsigned long *targ_addr, - void *regcache, - unsigned long (*dmap_register) (SIM_DESC, - SIM_CPU *, - void *regcache, - int reg_nr), - unsigned long (*imap_register) (SIM_DESC, - SIM_CPU *, - void *regcache, - int reg_nr)) -{ - unsigned long phys; - unsigned long seg; - unsigned long off; - - last_from = "unknown"; - last_to = "unknown"; - - seg = (memaddr >> 24); - off = (memaddr & 0xffffffL); - - switch (seg) - { - case 0x00: /* Physical unified memory */ - last_from = "phys-unified"; - last_to = "unified"; - phys = SIM_CR16_MEMORY_UNIFIED + off; - if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) - nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); - break; - - case 0x01: /* Physical instruction memory */ - last_from = "phys-insn"; - last_to = "chip-insn"; - phys = SIM_CR16_MEMORY_INSN + off; - if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) - nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); - break; - - case 0x02: /* Physical data memory segment */ - last_from = "phys-data"; - last_to = "chip-data"; - phys = SIM_CR16_MEMORY_DATA + off; - if ((off % SEGMENT_SIZE) + nr_bytes > SEGMENT_SIZE) - nr_bytes = SEGMENT_SIZE - (off % SEGMENT_SIZE); - break; - - case 0x10: /* in logical data address segment */ - nr_bytes = sim_cr16_translate_dmap_addr (sd, cpu, off, nr_bytes, &phys, - regcache, dmap_register); - break; - - case 0x11: /* in logical instruction address segment */ - nr_bytes = sim_cr16_translate_imap_addr (sd, cpu, off, nr_bytes, &phys, - regcache, imap_register); - break; - - default: - return 0; - } - - *targ_addr = phys; - return nr_bytes; -} - -/* Return a pointer into the raw buffer designated by phys_addr. It - is assumed that the client has already ensured that the access - isn't going to cross a segment boundary. */ - -uint8 * -map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr) -{ - uint8 **memory; - uint8 *raw; - unsigned offset; - int segment = ((phys_addr >> 24) & 0xff); - - switch (segment) - { - - case 0x00: /* Unified memory */ - { - memory = &State.mem.unif[(phys_addr / SEGMENT_SIZE) % UMEM_SEGMENTS]; - last_segname = "umem"; - break; - } - - case 0x01: /* On-chip insn memory */ - { - memory = &State.mem.insn[(phys_addr / SEGMENT_SIZE) % IMEM_SEGMENTS]; - last_segname = "imem"; - break; - } - - case 0x02: /* On-chip data memory */ - { - if ((phys_addr & 0xff00) == 0xff00) - { - phys_addr = (phys_addr & 0xffff); - if (phys_addr == DMAP2_SHADDOW) - { - phys_addr = DMAP2_OFFSET; - last_segname = "dmap"; - } - else - last_segname = "reg"; - } - else - last_segname = "dmem"; - memory = &State.mem.data[(phys_addr / SEGMENT_SIZE) % DMEM_SEGMENTS]; - break; - } - - default: - /* OOPS! */ - last_segname = "scrap"; - return State.mem.fault; - } - - if (*memory == NULL) - { - *memory = calloc (1, SEGMENT_SIZE); - if (*memory == NULL) - { - (*cr16_callback->printf_filtered) (cr16_callback, "Malloc failed.\n"); - return State.mem.fault; - } - } - - offset = (phys_addr % SEGMENT_SIZE); - raw = *memory + offset; - return raw; -} - -/* Transfer data to/from simulated memory. Since a bug in either the - simulated program or in gdb or the simulator itself may cause a - bogus address to be passed in, we need to do some sanity checking - on addresses to make sure they are within bounds. When an address - fails the bounds check, treat it as a zero length read/write rather - than aborting the entire run. */ - -static int -xfer_mem (SIM_DESC sd, SIM_ADDR virt, - unsigned char *buffer, - int size, - int write_p) -{ - host_callback *cr16_callback = STATE_CALLBACK (sd); - uint8 *memory; - unsigned long phys; - int phys_size; - phys_size = sim_cr16_translate_addr (sd, NULL, virt, size, &phys, NULL, - dmap_register, imap_register); - if (phys_size == 0) - return 0; - - memory = map_memory (sd, NULL, phys); - -#ifdef DEBUG - if ((cr16_debug & DEBUG_INSTRUCTION) != 0) - { - (*cr16_callback->printf_filtered) - (cr16_callback, - "sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n", - (write_p ? "write" : "read"), - phys_size, virt, last_from, - phys, last_to, - (long) memory, last_segname); - } -#endif - - if (write_p) - { - memcpy (memory, buffer, phys_size); - } - else - { - memcpy (buffer, memory, phys_size); - } - - return phys_size; -} - - -int -sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size) -{ - /* FIXME: this should be performing a virtual transfer */ - return xfer_mem (sd, addr, buffer, size, 1); -} - -int -sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size) -{ - /* FIXME: this should be performing a virtual transfer */ - return xfer_mem (sd, addr, buffer, size, 0); -} - static sim_cia cr16_pc_get (sim_cpu *cpu) { @@ -848,6 +460,14 @@ sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, CPU_PC_STORE (cpu) = cr16_pc_set; } + /* The CR16 has an interrupt controller at 0xFC00, but we don't currently + handle that. Revisit if anyone ever implements operating mode. */ + /* cr16 memory: There are three separate cr16 memory regions IMEM, + UMEM and DMEM. The IMEM and DMEM are further broken down into + blocks (very like VM pages). This might not match the hardware, + but it matches what the toolchain currently expects. Ugh. */ + sim_do_commandf (sd, "memory-size %#x", 20 * 1024 * 1024); + cr16_callback = cb; /* put all the opcodes in the hash table. */ @@ -956,72 +576,9 @@ sim_open (SIM_OPEN_KIND kind, struct host_callback_struct *cb, struct bfd *abfd, } } - /* reset the processor state */ - if (!State.mem.data[0]) - sim_size (1); - return sd; } -uint8 * -dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset) -{ - unsigned long phys; - uint8 *mem; - int phys_size; - - /* Note: DMEM address range is 0..0x10000. Calling code can compute - things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type - is uint16 this is modulo'ed onto 0x0e5d. */ - - phys_size = sim_cr16_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL, - dmap_register); - if (phys_size == 0) - { - mem = State.mem.fault; - } - else - mem = map_memory (sd, cpu, phys); -#ifdef DEBUG - if ((cr16_debug & DEBUG_MEMORY)) - { - (*cr16_callback->printf_filtered) - (cr16_callback, - "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", - offset, last_from, - phys, phys_size, last_to, - (long) mem, last_segname); - } -#endif - return mem; -} - -uint8 * -imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset) -{ - unsigned long phys; - uint8 *mem; - int phys_size = sim_cr16_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL, - imap_register); - if (phys_size == 0) - { - return State.mem.fault; - } - mem = map_memory (sd, cpu, phys); -#ifdef DEBUG - if ((cr16_debug & DEBUG_MEMORY)) - { - (*cr16_callback->printf_filtered) - (cr16_callback, - "mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n", - offset, last_from, - phys, phys_size, last_to, - (long) mem, last_segname); - } -#endif - return mem; -} - static int stop_simulator = 0; int @@ -1038,8 +595,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal) { SIM_CPU *cpu = STATE_CPU (sd, 0); uint32 curr_ins_size = 0; - uint64 mcode = 0; - uint8 *iaddr; + uint64 mcode; #ifdef DEBUG // (*cr16_callback->printf_filtered) (cr16_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); @@ -1076,19 +632,8 @@ sim_resume (SIM_DESC sd, int step, int siggnal) do { - iaddr = imem_addr (sd, cpu, (uint32)PC); - if (iaddr == State.mem.fault) - { -#ifdef SIGBUS - State.exception = SIGBUS; -#else - State.exception = SIGSEGV; -#endif - break; - } - - mcode = get_longword( iaddr ); - + mcode = RLW (PC); + State.pc_changed = 0; curr_ins_size = do_run (sd, cpu, mcode); @@ -1134,7 +679,7 @@ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) bfd_vma start_address; /* reset all state information */ - memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs); + memset (&State, 0, sizeof (State)); /* There was a hack here to copy the values of argc and argv into r0 and r1. The values were also saved into some high memory that diff --git a/sim/cr16/simops.c b/sim/cr16/simops.c index b452ee0..db595f1 100644 --- a/sim/cr16/simops.c +++ b/sim/cr16/simops.c @@ -5143,7 +5143,7 @@ OP_C_C (SIM_DESC sd, SIM_CPU *cpu) /* Turn a pointer in a register into a pointer into real memory. */ -#define MEMPTR(x) ((char *)(dmem_addr (sd, cpu, x))) +#define MEMPTR(x) sim_core_trans_addr (sd, cpu, read_map, x) switch (FUNC) {