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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [gdbserver/] [linux-or32-low.c] - Diff between revs 446 and 447

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 446 Rev 447
/* GNU/Linux/or32 specific low level interface, for the remote server for GDB.
/* GNU/Linux/or32 specific low level interface, for the remote server for GDB.
   Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
   Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
   Copyright (C) 2010 Embecosm Limited
   Copyright (C) 2010 Embecosm Limited
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* OpenRISC 1000 specific low level Linux interface for GDB server.
/* OpenRISC 1000 specific low level Linux interface for GDB server.
 
 
   This implementation includes full Doxygen compatible documentation         */
   This implementation includes full Doxygen compatible documentation         */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
 
 
#ifdef HAVE_STRINGS_H
#ifdef HAVE_STRINGS_H
#include <strings.h>
#include <strings.h>
#endif
#endif
 
 
#include "server.h"
#include "server.h"
#include "regdef.h"
#include "regdef.h"
#include "linux-low.h"
#include "linux-low.h"
 
 
#include <asm/ptrace.h> /* For openrisc kernel ptrace register offsets */
#include <asm/ptrace.h> /* For openrisc kernel ptrace register offsets */
 
 
#ifdef HAVE_SYS_REG_H
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#include <sys/reg.h>
#endif
#endif
 
 
 
 
 
/* -------------------------------------------------------------------------- */
 
/*!Global register map
 
 
 
   This should be in GDB order (r0-r1, ppc, npc, sr) to ptrace offset.
 
 
 
   ptrace does not support r0 (so we use r31 for now), nor ppc (so we use npc
 
   for now).
 
 
 
   @note This must be a global variable.
 
 
 
   @todo Fix r0 and ppc (needs ptrace changes).                               */
 
/* -------------------------------------------------------------------------- */
struct reg regs_or32[] = {
struct reg regs_or32[] = {
    { "npc", PC * 8, 32 },
  { "r0",  GPR31 * 8, 32 },
    { "sr", SR * 8, 32 },
 
    { "sp", SP * 8, 32 },
    { "sp", SP * 8, 32 },
    { "fp", GPR2 * 8, 32 },
  { "fp",  GPR2  * 8, 32 },
    { "r3", GPR3 * 8, 32 },
  { "r3",  GPR3  * 8, 32 },
    { "r4", GPR4 * 8, 32 },
  { "r4",  GPR4  * 8, 32 },
    { "r5", GPR5 * 8, 32 },
  { "r5",  GPR5  * 8, 32 },
    { "r6", GPR6 * 8, 32 },
  { "r6",  GPR6  * 8, 32 },
    { "r7", GPR7 * 8, 32 },
  { "r7",  GPR7  * 8, 32 },
    { "r8", GPR8 * 8, 32 },
  { "r8",  GPR8  * 8, 32 },
    { "lr", GPR9 * 8, 32 },
  { "lr",  GPR9  * 8, 32 },
    { "r10", GPR10 * 8, 32 },
  { "r10", GPR10 * 8, 32 },
    { "r11", GPR11 * 8, 32 },
  { "r11", GPR11 * 8, 32 },
    { "r12", GPR12 * 8, 32 },
  { "r12", GPR12 * 8, 32 },
    { "r13", GPR13 * 8, 32 },
  { "r13", GPR13 * 8, 32 },
    { "r14", GPR14 * 8, 32 },
  { "r14", GPR14 * 8, 32 },
    { "r15", GPR15 * 8, 32 },
  { "r15", GPR15 * 8, 32 },
    { "r16", GPR16 * 8, 32 },
  { "r16", GPR16 * 8, 32 },
    { "r17", GPR17 * 8, 32 },
  { "r17", GPR17 * 8, 32 },
    { "r18", GPR18 * 8, 32 },
  { "r18", GPR18 * 8, 32 },
    { "r19", GPR19 * 8, 32 },
  { "r19", GPR19 * 8, 32 },
    { "r20", GPR20 * 8, 32 },
  { "r20", GPR20 * 8, 32 },
    { "r21", GPR21 * 8, 32 },
  { "r21", GPR21 * 8, 32 },
    { "r22", GPR22 * 8, 32 },
  { "r22", GPR22 * 8, 32 },
    { "r23", GPR23 * 8, 32 },
  { "r23", GPR23 * 8, 32 },
    { "r24", GPR24 * 8, 32 },
  { "r24", GPR24 * 8, 32 },
    { "r25", GPR25 * 8, 32 },
  { "r25", GPR25 * 8, 32 },
    { "r26", GPR26 * 8, 32 },
  { "r26", GPR26 * 8, 32 },
    { "r27", GPR27 * 8, 32 },
  { "r27", GPR27 * 8, 32 },
    { "r28", GPR28 * 8, 32 },
  { "r28", GPR28 * 8, 32 },
    { "r29", GPR29 * 8, 32 },
  { "r29", GPR29 * 8, 32 },
    { "r30", GPR30 * 8, 32 },
  { "r30", GPR30 * 8, 32 },
    { "r31", GPR31 * 8, 32 },
    { "r31", GPR31 * 8, 32 },
 
  { "ppc", PC    * 8, 32 },
 
  { "npc", PC    * 8, 32 },
 
  { "sr",  SR    * 8, 32 }
  };
  };
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Initialize the register data.
/*!Initialize the register data.
 
 
  Should be automagically created from a data file in gdb/regformats, but for
  Should be automagically created from a data file in gdb/regformats, but for
  now we do it manually.                                                      */
  now we do it manually.                                                      */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static void
static void
init_registers_or32 ()
init_registers_or32 ()
{
{
 
 
  static const char *expedite_regs_or32[] = { "sp", "lr", "npc", 0 };
  static const char *expedite_regs_or32[] = { "sp", "lr", "npc", 0 };
 
 
  set_register_cache (regs_or32, sizeof (regs_or32) / sizeof (regs_or32[0]));
  set_register_cache (regs_or32, sizeof (regs_or32) / sizeof (regs_or32[0]));
  gdbserver_expedite_regs = expedite_regs_or32;
  gdbserver_expedite_regs = expedite_regs_or32;
  gdbserver_xmltarget     = NULL;
  gdbserver_xmltarget     = NULL;
}
}
 
 
 
 
/*! OpenRISC Linux ptrace provides NPC, SR, then GPRS 1 to 31 */
/*! This is the number of *GDB* registers. I.e. r0-r31, PPC, NPC and SR. */
#define or32_num_regs  (2 + 31)
#define or32_num_regs  35
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Provide the ptrace "address" of a register.
/*!Provide the ptrace "address" of a register.
                                                                              */
 
 
   This must be in GDB order (r0-r1, ppc, npc, sr) to ptrace offset. As with
 
   regs_or32, we substitute r31 for r0 and NPC for PPC.                       */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static int or32_regmap[] = {
static int or32_regmap[] = {
#ifdef PC
  GPR31, SP,    GPR2,  GPR3,  GPR4,  GPR5,  GPR6,  GPR7,
  PC   , SR   , SP   , GPR2 , GPR3 , GPR4 , GPR5 , GPR6 ,
  GPR8,  GPR9,  GPR10, GPR11, GPR12, GPR13, GPR14, GPR15,
  GPR7 , GPR8 , GPR9 , GPR10, GPR11, GPR12, GPR13, GPR14,
  GPR16, GPR17, GPR18, GPR19, GPR20, GPR21, GPR22, GPR23,
  GPR15, GPR16, GPR17, GPR18, GPR19, GPR20, GPR21, GPR22,
  GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30, GPR31,
  GPR23, GPR24, GPR25, GPR26, GPR27, GPR28, GPR29, GPR30,
  PC,    PC,    SR
  GPR31
 
#else
 
  4 *  0, 4 *  1, 4 *  2, 4 *  3, 4 *  4, 4 *  5, 4 *  6, 4 *  7,
 
  4 *  8, 4 *  9, 4 * 10, 4 * 11, 4 * 12, 4 * 13, 4 * 14, 4 * 15,
 
  4 * 16, 4 * 17, 4 * 18, 4 * 19, 4 * 20, 4 * 21, 4 * 22, 4 * 23,
 
  4 * 24, 4 * 25, 4 * 26, 4 * 27, 4 * 28, 4 * 29, 4 * 30, 4 * 31,
 
  4 * 32, 4 * 33, 4 * 34
 
#endif
 
};
};
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Predicate to indicate if a register can be read.
/*!Predicate to indicate if a register can be read.
 
 
   For now, we believe all OR32 registers are readable.
   For now, we believe all OR32 registers are readable.
 
 
   @param[in] regno  Register to read.
   @param[in] regno  Register to read.
 
 
   @return  Non-zero (TRUE) if the register can be read, zero (FALSE)
   @return  Non-zero (TRUE) if the register can be read, zero (FALSE)
            otherwise.                                                        */
            otherwise.                                                        */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static int
static int
or32_cannot_fetch_register (int  regno)
or32_cannot_fetch_register (int  regno)
{
{
  return (regno >= or32_num_regs);
  return (regno >= or32_num_regs);
 
 
}       /* or32_cannot_fetch_register () */
}       /* or32_cannot_fetch_register () */
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Predicate to indicate if a register can be written.
/*!Predicate to indicate if a register can be written.
 
 
   For now, we believe all OR32 registers are writable.
   For now, we believe all OR32 registers are writable.
 
 
   @param[in] regno  Register to write.
   @param[in] regno  Register to write.
 
 
   @return  Non-zero (TRUE) if the register can be written, zero (FALSE)
   @return  Non-zero (TRUE) if the register can be written, zero (FALSE)
            otherwise.                                                        */
            otherwise.                                                        */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static int
static int
or32_cannot_store_register (int  regno)
or32_cannot_store_register (int  regno)
{
{
  return (regno >= or32_num_regs);
  return (regno >= or32_num_regs);
 
 
}       /* or32_cannot_store_register () */
}       /* or32_cannot_store_register () */
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Get the current program counter.
/*!Get the current program counter.
 
 
   On the OR32, this is NPC, the *next* program counter.
   On the OR32, this is NPC, the *next* program counter.
 
 
   @param[in] regcache  Current register cache.
   @param[in] regcache  Current register cache.
 
 
   @return  The value of the NPC.                                             */
   @return  The value of the NPC.                                             */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static CORE_ADDR
static CORE_ADDR
or32_get_pc (struct regcache *regcache)
or32_get_pc (struct regcache *regcache)
{
{
  unsigned long int  npc;
  unsigned long int  npc;
  collect_register_by_name (regcache, "npc", &npc);
  collect_register_by_name (regcache, "npc", &npc);
 
 
    if (debug_threads)
    if (debug_threads)
    {
    {
      fprintf (stderr, "stop pc is %08lx\n", npc);
      fprintf (stderr, "stop pc is %08lx\n", npc);
    }
    }
 
 
  return  npc;
  return  npc;
 
 
}       /* or32_get_pc () */
}       /* or32_get_pc () */
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Set the current program counter.
/*!Set the current program counter.
 
 
   On the OR32, this is NPC, the *next* program counter.
   On the OR32, this is NPC, the *next* program counter.
 
 
   @param[in] regcache  Current register cache.
   @param[in] regcache  Current register cache.
   @param[in] pc        The value of the program counter to set.              */
   @param[in] pc        The value of the program counter to set.              */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static void
static void
or32_set_pc (struct regcache *regcache,
or32_set_pc (struct regcache *regcache,
             CORE_ADDR        pc)
             CORE_ADDR        pc)
{
{
  unsigned long int  npc = pc;
  unsigned long int  npc = pc;
  supply_register_by_name (regcache, "npc", &npc);
  supply_register_by_name (regcache, "npc", &npc);
 
 
}       /* or32_set_pc () */
}       /* or32_set_pc () */
 
 
 
 
/*! The value of a breakpoint instruction (l.trap  1). */
/*! The value of a breakpoint instruction (l.trap  1). */
static const unsigned char or32_breakpoint [] = {0x21, 0x00, 0x00, 0x01};
static const unsigned char or32_breakpoint [] = {0x21, 0x00, 0x00, 0x01};
 
 
 
 
/*! The length of a breakpoint instruction. */
/*! The length of a breakpoint instruction. */
#define OR32_BREAKPOINT_LEN  4
#define OR32_BREAKPOINT_LEN  4
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Predicate to indicate if there is a breakpoint at the current address.
/*!Predicate to indicate if there is a breakpoint at the current address.
 
 
   For the OR32 we, just look for the l.trap 1 instruction.
   For the OR32 we, just look for the l.trap 1 instruction.
 
 
   @param[in] where  The address to look for a breakpoint at.
   @param[in] where  The address to look for a breakpoint at.
 
 
   @return  Non-zero (TRUE) if there is a breakpoint, zero (FALSE) otherwise. */
   @return  Non-zero (TRUE) if there is a breakpoint, zero (FALSE) otherwise. */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static int
static int
or32_breakpoint_at (CORE_ADDR where)
or32_breakpoint_at (CORE_ADDR where)
{
{
  unsigned char  insn[OR32_BREAKPOINT_LEN];
  unsigned char  insn[OR32_BREAKPOINT_LEN];
 
 
  (*the_target->read_memory) (where, insn, OR32_BREAKPOINT_LEN);
  (*the_target->read_memory) (where, insn, OR32_BREAKPOINT_LEN);
 
 
  return  (0 ==  bcmp (insn, or32_breakpoint, OR32_BREAKPOINT_LEN));
  return  (0 ==  bcmp (insn, or32_breakpoint, OR32_BREAKPOINT_LEN));
 
 
}       /* or32_breakpoint_at () */
}       /* or32_breakpoint_at () */
 
 
 
 
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*!Data structure giving all the target specific functions.
/*!Data structure giving all the target specific functions.
 
 
   Details are in struct linux_target_ops in linux-low.h.                     */
   Details are in struct linux_target_ops in linux-low.h.                     */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
struct linux_target_ops the_low_target = {
struct linux_target_ops the_low_target = {
  init_registers_or32,                  /* Arch initialization */
  init_registers_or32,                  /* Arch initialization */
  or32_num_regs,                        /* Num regs in arch */
  or32_num_regs,                        /* Num regs in arch */
  or32_regmap,                          /* Reg offsets for ptrace */
  or32_regmap,                          /* Reg offsets for ptrace */
  or32_cannot_fetch_register,           /* Predicate for reg reading */
  or32_cannot_fetch_register,           /* Predicate for reg reading */
  or32_cannot_store_register,           /* Predicate for reg writing */
  or32_cannot_store_register,           /* Predicate for reg writing */
  or32_get_pc,                          /* Read the PC */
  or32_get_pc,                          /* Read the PC */
  or32_set_pc,                          /* Write the PC */
  or32_set_pc,                          /* Write the PC */
  or32_breakpoint,                      /* Breakpoint instruction bytes */
  or32_breakpoint,                      /* Breakpoint instruction bytes */
  OR32_BREAKPOINT_LEN,                  /* Breakpoint length */
  OR32_BREAKPOINT_LEN,                  /* Breakpoint length */
  NULL,                                 /* Breakpoint reinsertion (unused) */
  NULL,                                 /* Breakpoint reinsertion (unused) */
  0,                                     /* Decrement PC after break (FALSE) */
  0,                                     /* Decrement PC after break (FALSE) */
  or32_breakpoint_at,                   /* Predicate to check for breakpoint */
  or32_breakpoint_at,                   /* Predicate to check for breakpoint */
  NULL,                                 /* Insert matchpoint (unused) */
  NULL,                                 /* Insert matchpoint (unused) */
  NULL,                                 /* Remove matchpoint (unused) */
  NULL,                                 /* Remove matchpoint (unused) */
  NULL,                                 /* Predicate if stopped by watchpoint */
  NULL,                                 /* Predicate if stopped by watchpoint */
  NULL,                                 /* Data address for watchpoint stop */
  NULL,                                 /* Data address for watchpoint stop */
  NULL,                                 /* ptrace PEEKUSR hook */
  NULL,                                 /* ptrace PEEKUSR hook */
  NULL,                                 /* ptrace POKEUSR hook */
  NULL,                                 /* ptrace POKEUSR hook */
  NULL,                                 /* ptrace conversion predicate */
  NULL,                                 /* ptrace conversion predicate */
  NULL,                                 /* New process hook */
  NULL,                                 /* New process hook */
  NULL,                                 /* New thread hook */
  NULL,                                 /* New thread hook */
  NULL,                                 /* Prepare to resume thread */
  NULL,                                 /* Prepare to resume thread */
  NULL,                                 /* Target specific qSupported */
  NULL,                                 /* Target specific qSupported */
  NULL,                                 /* Tracepoint supported predicate */
  NULL,                                 /* Tracepoint supported predicate */
  NULL,                                 /* Get thread area address */
  NULL,                                 /* Get thread area address */
  NULL,                                 /* Fast tracepoint jump pad */
  NULL,                                 /* Fast tracepoint jump pad */
  NULL,                                 /* Get bytecode operations vector */
  NULL,                                 /* Get bytecode operations vector */
};
};
 
 

powered by: WebSVN 2.1.0

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