* sim-main.h (phys_to_virt): Use memory bank parameters to translate

the physical address in virtual address.
	(struct _sim_cpu): Add memory bank members.
	* m68hc11_sim.c (cpu_initialize): Clear memory bank parameters.
	* interp.c (sim_hw_configure): Create memory bank according to memory
	bank parameters.
	(sim_get_bank_parameters): New function to obtain memory bank config
	from the symbol table.
	(sim_prepare_for_program): Call it to obtain the memory bank parameters.
	(sim_open): Call sim_prepare_for_program.
	* dv-m68hc11.c (m68hc11cpu_io_write_buffer): Use memory bank parameters
	to check if address is within bank window.
	(m68hc11cpu_io_read_buffer): Likewise.
	(attach_m68hc11_regs): Map the memory bank according to memory bank
	parameters.
This commit is contained in:
Stephane Carrez 2003-08-08 20:42:21 +00:00
parent 53b3cd2254
commit 77342e5ecc
5 changed files with 137 additions and 25 deletions

View file

@ -1,3 +1,21 @@
2003-08-08 Stephane Carrez <stcarrez@nerim.fr>
* sim-main.h (phys_to_virt): Use memory bank parameters to translate
the physical address in virtual address.
(struct _sim_cpu): Add memory bank members.
* m68hc11_sim.c (cpu_initialize): Clear memory bank parameters.
* interp.c (sim_hw_configure): Create memory bank according to memory
bank parameters.
(sim_get_bank_parameters): New function to obtain memory bank config
from the symbol table.
(sim_prepare_for_program): Call it to obtain the memory bank parameters.
(sim_open): Call sim_prepare_for_program.
* dv-m68hc11.c (m68hc11cpu_io_write_buffer): Use memory bank parameters
to check if address is within bank window.
(m68hc11cpu_io_read_buffer): Likewise.
(attach_m68hc11_regs): Map the memory bank according to memory bank
parameters.
2003-08-08 Stephane Carrez <stcarrez@nerim.fr>,
* sim-main.h (PAGE_REGNUM, Z_REGNUM): Use same numbering as gdb.

View file

@ -1,5 +1,5 @@
/* dv-m68hc11.c -- CPU 68HC11&68HC12 as a device.
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@nerim.fr)
(From a driver model Contributed by Cygnus Solutions.)
@ -324,8 +324,8 @@ attach_m68hc11_regs (struct hw *me,
if (hw_find_property (me, "use_bank") != NULL)
hw_attach_address (hw_parent (me), 0,
exec_map,
0x08000,
0x04000,
cpu->bank_start,
cpu->bank_end - cpu->bank_start,
me);
cpu_mode = "expanded";
@ -843,7 +843,7 @@ m68hc11cpu_io_read_buffer (struct hw *me,
sd = hw_system (me);
cpu = STATE_CPU (sd, 0);
if (base >= 0x8000 && base < 0xc000)
if (base >= cpu->bank_start && base < cpu->bank_end)
{
address_word virt_addr = phys_to_virt (cpu, base);
if (virt_addr != base)
@ -864,7 +864,7 @@ m68hc11cpu_io_read_buffer (struct hw *me,
break;
memcpy (dest, &cpu->ios[base], 1);
dest++;
dest = (char*) dest + 1;
base++;
byte++;
nr_bytes--;
@ -1091,7 +1091,7 @@ m68hc11cpu_io_write_buffer (struct hw *me,
sd = hw_system (me);
cpu = STATE_CPU (sd, 0);
if (base >= 0x8000 && base < 0xc000)
if (base >= cpu->bank_start && base < cpu->bank_end)
{
address_word virt_addr = phys_to_virt (cpu, base);
if (virt_addr != base)
@ -1113,7 +1113,7 @@ m68hc11cpu_io_write_buffer (struct hw *me,
val = *((uint8*) source);
m68hc11cpu_io_write (me, cpu, base, val);
source++;
source = (char*) source + 1;
base++;
byte++;
nr_bytes--;

View file

@ -1,5 +1,5 @@
/* interp.c -- Simulator for Motorola 68HC11/68HC12
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@nerim.fr)
This file is part of GDB, the GNU debugger.
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "hw-tree.h"
#include "hw-device.h"
#include "hw-ports.h"
#include "elf32-m68hc1x.h"
#ifndef MONITOR_BASE
# define MONITOR_BASE (0x0C000)
@ -194,8 +195,17 @@ sim_hw_configure (SIM_DESC sd)
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
M6811_RAM_LEVEL);
sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
if (cpu->bank_start < cpu->bank_end)
{
sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
cpu->bank_virtual, M6811_RAM_LEVEL);
sim_hw_parse (sd, "/m68hc11/use_bank 1");
}
}
if (cpu->cpu_start_mode)
{
sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
}
if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
{
sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
@ -242,14 +252,16 @@ sim_hw_configure (SIM_DESC sd)
{
/* Allocate core external memory. */
sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
0xC000, M6811_RAM_LEVEL, 0x4000);
0x8000, M6811_RAM_LEVEL, 0x8000);
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
M6811_RAM_LEVEL);
sim_do_commandf (sd, "memory region 0x01000000@%d,0x100000",
M6811_RAM_LEVEL);
if (cpu->bank_start < cpu->bank_end)
{
sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
cpu->bank_virtual, M6811_RAM_LEVEL);
sim_hw_parse (sd, "/m68hc12/use_bank 1");
}
sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
sim_hw_parse (sd, "/m68hc12/use_bank 1");
}
if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
@ -294,19 +306,77 @@ sim_hw_configure (SIM_DESC sd)
return 1;
}
/* Get the memory bank parameters by looking at the global symbols
defined by the linker. */
static int
sim_prepare_for_program (SIM_DESC sd, struct bfd* abfd)
sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
{
sim_cpu *cpu;
long symsize;
long symbol_count, i;
unsigned size;
asymbol** asymbols;
asymbol** current;
cpu = STATE_CPU (sd, 0);
if (!sim_hw_configure (sd))
return SIM_RC_FAIL;
symsize = bfd_get_symtab_upper_bound (abfd);
if (symsize < 0)
{
sim_io_eprintf (sd, "Cannot read symbols of program");
return 0;
}
asymbols = (asymbol **) xmalloc (symsize);
symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
if (symbol_count < 0)
{
sim_io_eprintf (sd, "Cannot read symbols of program");
return 0;
}
size = 0;
for (i = 0, current = asymbols; i < symbol_count; i++, current++)
{
const char* name = bfd_asymbol_name (*current);
if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
{
cpu->bank_start = bfd_asymbol_value (*current);
}
else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
{
size = bfd_asymbol_value (*current);
}
else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
{
cpu->bank_virtual = bfd_asymbol_value (*current);
}
}
free (asymbols);
cpu->bank_end = cpu->bank_start + size;
cpu->bank_shift = 0;
for (; size > 1; size >>= 1)
cpu->bank_shift++;
return 0;
}
static int
sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
{
sim_cpu *cpu;
int elf_flags = 0;
cpu = STATE_CPU (sd, 0);
if (abfd != NULL)
{
asection *s;
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
elf_flags = elf_elfheader (abfd)->e_flags;
cpu->cpu_elf_start = bfd_get_start_address (abfd);
/* See if any section sets the reset address */
cpu->cpu_use_elf_start = 1;
@ -331,8 +401,17 @@ sim_prepare_for_program (SIM_DESC sd, struct bfd* abfd)
}
}
}
if (elf_flags & E_M68HC12_BANKS)
{
if (sim_get_bank_parameters (sd, abfd) != 0)
sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
}
}
if (!sim_hw_configure (sd))
return SIM_RC_FAIL;
/* reset all state information */
sim_board_reset (sd);
@ -341,7 +420,7 @@ sim_prepare_for_program (SIM_DESC sd, struct bfd* abfd)
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
struct bfd *abfd, char **argv)
bfd *abfd, char **argv)
{
SIM_DESC sd;
sim_cpu *cpu;
@ -398,8 +477,11 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
free_state (sd);
return 0;
}
sim_hw_configure (sd);
if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
{
free_state (sd);
return 0;
}
/* Fudge our descriptor. */
return sd;

View file

@ -464,6 +464,9 @@ cpu_initialize (SIM_DESC sd, sim_cpu *cpu)
cpu->cpu_use_elf_start = 0;
cpu->cpu_elf_start = 0;
cpu->cpu_use_local_config = 0;
cpu->bank_start = 0;
cpu->bank_end = 0;
cpu->bank_shift = 0;
cpu->cpu_config = M6811_NOSEC | M6811_NOCOP | M6811_ROMON |
M6811_EEON;
interrupts_initialize (sd, cpu);

View file

@ -210,6 +210,14 @@ struct _sim_cpu {
uint8 ios[MAX_PORTS];
/* Memory bank parameters which describe how the memory bank window
is mapped in memory and how to convert it in virtual address. */
uint16 bank_start;
uint16 bank_end;
address_word bank_virtual;
unsigned bank_shift;
struct hw *hw_cpu;
/* ... base type ... */
@ -237,7 +245,7 @@ struct _sim_cpu {
#define cpu_get_sp(PROC) ((PROC)->cpu_regs.sp)
#define cpu_get_a(PROC) ((PROC->cpu_regs.d >> 8) & 0x0FF)
#define cpu_get_b(PROC) ((PROC->cpu_regs.d) & 0x0FF)
#define cpu_get_page(PROC) (PROC->cpu_regs.page)
#define cpu_get_page(PROC) ((PROC)->cpu_regs.page)
/* 68HC12 specific and Motorola internal registers. */
#define cpu_get_tmp3(PROC) (0)
@ -246,7 +254,7 @@ struct _sim_cpu {
#define cpu_set_d(PROC,VAL) (((PROC)->cpu_regs.d) = (VAL))
#define cpu_set_x(PROC,VAL) (((PROC)->cpu_regs.ix) = (VAL))
#define cpu_set_y(PROC,VAL) (((PROC)->cpu_regs.iy) = (VAL))
#define cpu_set_page(PROC,VAL) ((PROC->cpu_regs.page) = (VAL))
#define cpu_set_page(PROC,VAL) (((PROC)->cpu_regs.page) = (VAL))
/* 68HC12 specific and Motorola internal registers. */
#define cpu_set_tmp3(PROC,VAL) (0)
@ -297,9 +305,10 @@ extern void cpu_memory_exception (struct _sim_cpu *proc,
inline address_word
phys_to_virt (sim_cpu *cpu, address_word addr)
{
if (addr >= 0x8000 && addr < 0xc000)
return ((address_word) (addr) - 0x8000)
+ (((address_word) cpu->cpu_regs.page) << 14) + 0x01000000;
if (addr >= cpu->bank_start && addr < cpu->bank_end)
return ((address_word) (addr - cpu->bank_start)
+ (((address_word) cpu->cpu_regs.page) << cpu->bank_shift)
+ cpu->bank_virtual);
else
return (address_word) (addr);
}