/* Target-dependent code for Atmel AVR, for GDB.
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
   Free Software Foundation, Inc.

   This file is part of GDB.

   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 2 of the License, 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* Contributed by Theodore A. Roth, troth@verinet.com */

/* Portions of this file were taken from the original gdb-4.18 patch developed
   by Denis Chertykov, denisc@overta.ru */

#include "defs.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "inferior.h"
#include "symfile.h"
#include "arch-utils.h"
#include "regcache.h"

/* AVR Background:

   (AVR micros are pure Harvard Architecture processors.)

   The AVR family of microcontrollers have three distinctly different memory
   spaces: flash, sram and eeprom. The flash is 16 bits wide and is used for
   the most part to store program instructions. The sram is 8 bits wide and is
   used for the stack and the heap. Some devices lack sram and some can have
   an additional external sram added on as a peripheral.

   The eeprom is 8 bits wide and is used to store data when the device is
   powered down. Eeprom is not directly accessible, it can only be accessed
   via io-registers using a special algorithm. Accessing eeprom via gdb's
   remote serial protocol ('m' or 'M' packets) looks difficult to do and is
   not included at this time.

   [The eeprom could be read manually via ``x/b <eaddr + AVR_EMEM_START>'' or
   written using ``set {unsigned char}<eaddr + AVR_EMEM_START>''.  For this to
   work, the remote target must be able to handle eeprom accesses and perform
   the address translation.]

   All three memory spaces have physical addresses beginning at 0x0. In
   addition, the flash is addressed by gcc/binutils/gdb with respect to 8 bit
   bytes instead of the 16 bit wide words used by the real device for the
   Program Counter.

   In order for remote targets to work correctly, extra bits must be added to
   addresses before they are send to the target or received from the target
   via the remote serial protocol. The extra bits are the MSBs and are used to
   decode which memory space the address is referring to. */

#undef XMALLOC
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))

#undef EXTRACT_INSN
#define EXTRACT_INSN(addr) extract_unsigned_integer(addr,2)

/* Constants: prefixed with AVR_ to avoid name space clashes */

enum
{
  AVR_REG_W = 24,
  AVR_REG_X = 26,
  AVR_REG_Y = 28,
  AVR_FP_REGNUM = 28,
  AVR_REG_Z = 30,

  AVR_SREG_REGNUM = 32,
  AVR_SP_REGNUM = 33,
  AVR_PC_REGNUM = 34,

  AVR_NUM_REGS = 32 + 1 /*SREG*/ + 1 /*SP*/ + 1 /*PC*/,
  AVR_NUM_REG_BYTES = 32 + 1 /*SREG*/ + 2 /*SP*/ + 4 /*PC*/,

  AVR_PC_REG_INDEX = 35,	/* index into array of registers */

  AVR_MAX_PROLOGUE_SIZE = 56,	/* bytes */

  /* Count of pushed registers. From r2 to r17 (inclusively), r28, r29 */
  AVR_MAX_PUSHES = 18,

  /* Number of the last pushed register. r17 for current avr-gcc */
  AVR_LAST_PUSHED_REGNUM = 17,

  /* FIXME: TRoth/2002-01-??: Can we shift all these memory masks left 8
     bits? Do these have to match the bfd vma values?. It sure would make
     things easier in the future if they didn't need to match.

     Note: I chose these values so as to be consistent with bfd vma
     addresses.

     TRoth/2002-04-08: There is already a conflict with very large programs
     in the mega128. The mega128 has 128K instruction bytes (64K words),
     thus the Most Significant Bit is 0x10000 which gets masked off my
     AVR_MEM_MASK.

     The problem manifests itself when trying to set a breakpoint in a
     function which resides in the upper half of the instruction space and
     thus requires a 17-bit address.

     For now, I've just removed the EEPROM mask and changed AVR_MEM_MASK
     from 0x00ff0000 to 0x00f00000. Eeprom is not accessible from gdb yet,
     but could be for some remote targets by just adding the correct offset
     to the address and letting the remote target handle the low-level
     details of actually accessing the eeprom. */

  AVR_IMEM_START = 0x00000000,	/* INSN memory */
  AVR_SMEM_START = 0x00800000,	/* SRAM memory */
#if 1
  /* No eeprom mask defined */
  AVR_MEM_MASK = 0x00f00000,	/* mask to determine memory space */
#else
  AVR_EMEM_START = 0x00810000,	/* EEPROM memory */
  AVR_MEM_MASK = 0x00ff0000,	/* mask to determine memory space */
#endif
};

/* Any function with a frame looks like this
   .......    <-SP POINTS HERE
   LOCALS1    <-FP POINTS HERE
   LOCALS0
   SAVED FP
   SAVED R3
   SAVED R2
   RET PC
   FIRST ARG
   SECOND ARG */

struct frame_extra_info
{
  CORE_ADDR return_pc;
  CORE_ADDR args_pointer;
  int locals_size;
  int framereg;
  int framesize;
  int is_main;
};

struct gdbarch_tdep
{
  /* FIXME: TRoth: is there anything to put here? */
  int foo;
};

/* Lookup the name of a register given it's number. */

static char *
avr_register_name (int regnum)
{
  static char *register_names[] = {
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
    "SREG", "SP", "PC"
  };
  if (regnum < 0)
    return NULL;
  if (regnum >= (sizeof (register_names) / sizeof (*register_names)))
    return NULL;
  return register_names[regnum];
}

/* Index within `registers' of the first byte of the space for
   register REGNUM.  */

static int
avr_register_byte (int regnum)
{
  if (regnum < AVR_PC_REGNUM)
    return regnum;
  else
    return AVR_PC_REG_INDEX;
}

/* Number of bytes of storage in the actual machine representation for
   register REGNUM.  */

static int
avr_register_raw_size (int regnum)
{
  switch (regnum)
    {
    case AVR_PC_REGNUM:
      return 4;
    case AVR_SP_REGNUM:
    case AVR_FP_REGNUM:
      return 2;
    default:
      return 1;
    }
}

/* Number of bytes of storage in the program's representation
   for register N.  */

static int
avr_register_virtual_size (int regnum)
{
  return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
}

/* Return the GDB type object for the "standard" data type
   of data in register N.  */

static struct type *
avr_register_virtual_type (int regnum)
{
  switch (regnum)
    {
    case AVR_PC_REGNUM:
      return builtin_type_unsigned_long;
    case AVR_SP_REGNUM:
      return builtin_type_unsigned_short;
    default:
      return builtin_type_unsigned_char;
    }
}

/* Instruction address checks and convertions. */

static CORE_ADDR
avr_make_iaddr (CORE_ADDR x)
{
  return ((x) | AVR_IMEM_START);
}

static int
avr_iaddr_p (CORE_ADDR x)
{
  return (((x) & AVR_MEM_MASK) == AVR_IMEM_START);
}

/* FIXME: TRoth: Really need to use a larger mask for instructions. Some
   devices are already up to 128KBytes of flash space.

   TRoth/2002-04-8: See comment above where AVR_IMEM_START is defined. */

static CORE_ADDR
avr_convert_iaddr_to_raw (CORE_ADDR x)
{
  return ((x) & 0xffffffff);
}

/* SRAM address checks and convertions. */

static CORE_ADDR
avr_make_saddr (CORE_ADDR x)
{
  return ((x) | AVR_SMEM_START);
}

static int
avr_saddr_p (CORE_ADDR x)
{
  return (((x) & AVR_MEM_MASK) == AVR_SMEM_START);
}

static CORE_ADDR
avr_convert_saddr_to_raw (CORE_ADDR x)
{
  return ((x) & 0xffffffff);
}

/* EEPROM address checks and convertions. I don't know if these will ever
   actually be used, but I've added them just the same. TRoth */

/* TRoth/2002-04-08: Commented out for now to allow fix for problem with large
   programs in the mega128. */

/*  static CORE_ADDR */
/*  avr_make_eaddr (CORE_ADDR x) */
/*  { */
/*    return ((x) | AVR_EMEM_START); */
/*  } */

/*  static int */
/*  avr_eaddr_p (CORE_ADDR x) */
/*  { */
/*    return (((x) & AVR_MEM_MASK) == AVR_EMEM_START); */
/*  } */

/*  static CORE_ADDR */
/*  avr_convert_eaddr_to_raw (CORE_ADDR x) */
/*  { */
/*    return ((x) & 0xffffffff); */
/*  } */

/* Convert from address to pointer and vice-versa. */

static void
avr_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr)
{
  /* Is it a code address?  */
  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
      || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
    {
      store_unsigned_integer (buf, TYPE_LENGTH (type),
			      avr_convert_iaddr_to_raw (addr));
    }
  else
    {
      /* Strip off any upper segment bits.  */
      store_unsigned_integer (buf, TYPE_LENGTH (type),
			      avr_convert_saddr_to_raw (addr));
    }
}

static CORE_ADDR
avr_pointer_to_address (struct type *type, void *buf)
{
  CORE_ADDR addr = extract_address (buf, TYPE_LENGTH (type));

  if (TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
    {
      fprintf_unfiltered (gdb_stderr, "CODE_SPACE ---->> ptr->addr: 0x%lx\n",
			  addr);
      fprintf_unfiltered (gdb_stderr,
			  "+++ If you see this, please send me an email <troth@verinet.com>\n");
    }

  /* Is it a code address?  */
  if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
      || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
      || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
    return avr_make_iaddr (addr);
  else
    return avr_make_saddr (addr);
}

static CORE_ADDR
avr_read_pc (ptid_t ptid)
{
  ptid_t save_ptid;
  CORE_ADDR pc;
  CORE_ADDR retval;

  save_ptid = inferior_ptid;
  inferior_ptid = ptid;
  pc = (int) read_register (AVR_PC_REGNUM);
  inferior_ptid = save_ptid;
  retval = avr_make_iaddr (pc);
  return retval;
}

static void
avr_write_pc (CORE_ADDR val, ptid_t ptid)
{
  ptid_t save_ptid;

  save_ptid = inferior_ptid;
  inferior_ptid = ptid;
  write_register (AVR_PC_REGNUM, avr_convert_iaddr_to_raw (val));
  inferior_ptid = save_ptid;
}

static CORE_ADDR
avr_read_sp (void)
{
  return (avr_make_saddr (read_register (AVR_SP_REGNUM)));
}

static void
avr_write_sp (CORE_ADDR val)
{
  write_register (AVR_SP_REGNUM, avr_convert_saddr_to_raw (val));
}

static CORE_ADDR
avr_read_fp (void)
{
  return (avr_make_saddr (read_register (AVR_FP_REGNUM)));
}

/* Translate a GDB virtual ADDR/LEN into a format the remote target
   understands.  Returns number of bytes that can be transfered
   starting at TARG_ADDR.  Return ZERO if no bytes can be transfered
   (segmentation fault).

   TRoth/2002-04-08: Could this be used to check for dereferencing an invalid
   pointer? */

static void
avr_remote_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes,
				   CORE_ADDR *targ_addr, int *targ_len)
{
  long out_addr;
  long out_len;

  /* FIXME: TRoth: Do nothing for now. Will need to examine memaddr at this
     point and see if the high bit are set with the masks that we want. */

  *targ_addr = memaddr;
  *targ_len = nr_bytes;
}

/* Function pointers obtained from the target are half of what gdb expects so
   multiply by 2. */

static CORE_ADDR
avr_convert_from_func_ptr_addr (CORE_ADDR addr)
{
  return addr * 2;
}

/* avr_scan_prologue is also used as the frame_init_saved_regs().

   Put here the code to store, into fi->saved_regs, the addresses of
   the saved registers of frame described by FRAME_INFO.  This
   includes special registers such as pc and fp saved in special ways
   in the stack frame.  sp is even more special: the address we return
   for it IS the sp for the next frame. */

/* Function: avr_scan_prologue (helper function for avr_init_extra_frame_info)
   This function decodes a AVR function prologue to determine:
     1) the size of the stack frame
     2) which registers are saved on it
     3) the offsets of saved regs
   This information is stored in the "extra_info" field of the frame_info.

   A typical AVR function prologue might look like this:
        push rXX
        push r28
        push r29
        in r28,__SP_L__
        in r29,__SP_H__
        sbiw r28,<LOCALS_SIZE>
        in __tmp_reg__,__SREG__
        cli
        out __SP_L__,r28
        out __SREG__,__tmp_reg__
        out __SP_H__,r29

  A `-mcall-prologues' prologue look like this:
        ldi r26,<LOCALS_SIZE>
        ldi r27,<LOCALS_SIZE>/265
        ldi r30,pm_lo8(.L_foo_body)
        ldi r31,pm_hi8(.L_foo_body)
        rjmp __prologue_saves__+RRR
  .L_foo_body:  */

static void
avr_scan_prologue (struct frame_info *fi)
{
  CORE_ADDR prologue_start;
  CORE_ADDR prologue_end;
  int i;
  unsigned short insn;
  int regno;
  int scan_stage = 0;
  char *name;
  struct minimal_symbol *msymbol;
  int prologue_len;
  unsigned char prologue[AVR_MAX_PROLOGUE_SIZE];
  int vpc = 0;

  fi->extra_info->framereg = AVR_SP_REGNUM;

  if (find_pc_partial_function
      (fi->pc, &name, &prologue_start, &prologue_end))
    {
      struct symtab_and_line sal = find_pc_line (prologue_start, 0);

      if (sal.line == 0)	/* no line info, use current PC */
	prologue_end = fi->pc;
      else if (sal.end < prologue_end)	/* next line begins after fn end */
	prologue_end = sal.end;	/* (probably means no prologue)  */
    }
  else
    /* We're in the boondocks: allow for */
    /* 19 pushes, an add, and "mv fp,sp" */
    prologue_end = prologue_start + AVR_MAX_PROLOGUE_SIZE;

  prologue_end = min (prologue_end, fi->pc);

  /* Search the prologue looking for instructions that set up the
     frame pointer, adjust the stack pointer, and save registers.  */

  fi->extra_info->framesize = 0;
  prologue_len = prologue_end - prologue_start;
  read_memory (prologue_start, prologue, prologue_len);

  /* Scanning main()'s prologue
     ldi r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>)
     ldi r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>)
     out __SP_H__,r29
     out __SP_L__,r28 */

  if (name && strcmp ("main", name) == 0 && prologue_len == 8)
    {
      CORE_ADDR locals;
      unsigned char img[] = {
	0xde, 0xbf,		/* out __SP_H__,r29 */
	0xcd, 0xbf		/* out __SP_L__,r28 */
      };

      fi->extra_info->framereg = AVR_FP_REGNUM;
      insn = EXTRACT_INSN (&prologue[vpc]);
      /* ldi r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>) */
      if ((insn & 0xf0f0) == 0xe0c0)
	{
	  locals = (insn & 0xf) | ((insn & 0x0f00) >> 4);
	  insn = EXTRACT_INSN (&prologue[vpc + 2]);
	  /* ldi r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>) */
	  if ((insn & 0xf0f0) == 0xe0d0)
	    {
	      locals |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
	      if (memcmp (prologue + vpc + 4, img, sizeof (img)) == 0)
		{
		  fi->frame = locals;

		  /* TRoth: Does -1 mean we're in main? */
		  fi->extra_info->is_main = 1;
		  return;
		}
	    }
	}
    }

  /* Scanning `-mcall-prologues' prologue
     FIXME: mega prologue have a 12 bytes long */

  while (prologue_len <= 12)	/* I'm use while to avoit many goto's */
    {
      int loc_size;
      int body_addr;
      unsigned num_pushes;

      insn = EXTRACT_INSN (&prologue[vpc]);
      /* ldi r26,<LOCALS_SIZE> */
      if ((insn & 0xf0f0) != 0xe0a0)
	break;
      loc_size = (insn & 0xf) | ((insn & 0x0f00) >> 4);

      insn = EXTRACT_INSN (&prologue[vpc + 2]);
      /* ldi r27,<LOCALS_SIZE> / 256 */
      if ((insn & 0xf0f0) != 0xe0b0)
	break;
      loc_size |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;

      insn = EXTRACT_INSN (&prologue[vpc + 4]);
      /* ldi r30,pm_lo8(.L_foo_body) */
      if ((insn & 0xf0f0) != 0xe0e0)
	break;
      body_addr = (insn & 0xf) | ((insn & 0x0f00) >> 4);

      insn = EXTRACT_INSN (&prologue[vpc + 6]);
      /* ldi r31,pm_hi8(.L_foo_body) */
      if ((insn & 0xf0f0) != 0xe0f0)
	break;
      body_addr |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;

      if (body_addr != (prologue_start + 10) / 2)
	break;

      msymbol = lookup_minimal_symbol ("__prologue_saves__", NULL, NULL);
      if (!msymbol)
	break;

      /* FIXME: prologue for mega have a JMP instead of RJMP */
      insn = EXTRACT_INSN (&prologue[vpc + 8]);
      /* rjmp __prologue_saves__+RRR */
      if ((insn & 0xf000) != 0xc000)
	break;

      /* Extract PC relative offset from RJMP */
      i = (insn & 0xfff) | (insn & 0x800 ? (-1 ^ 0xfff) : 0);
      /* Convert offset to byte addressable mode */
      i *= 2;
      /* Destination address */
      i += vpc + prologue_start + 10;
      /* Resovle offset (in words) from __prologue_saves__ symbol.
         Which is a pushes count in `-mcall-prologues' mode */
      num_pushes = AVR_MAX_PUSHES - (i - SYMBOL_VALUE_ADDRESS (msymbol)) / 2;

      if (num_pushes > AVR_MAX_PUSHES)
	num_pushes = 0;

      if (num_pushes)
	{
	  int from;
	  fi->saved_regs[AVR_FP_REGNUM + 1] = num_pushes;
	  if (num_pushes >= 2)
	    fi->saved_regs[AVR_FP_REGNUM] = num_pushes - 1;
	  i = 0;
	  for (from = AVR_LAST_PUSHED_REGNUM + 1 - (num_pushes - 2);
	       from <= AVR_LAST_PUSHED_REGNUM; ++from)
	    fi->saved_regs[from] = ++i;
	}
      fi->extra_info->locals_size = loc_size;
      fi->extra_info->framesize = loc_size + num_pushes;
      fi->extra_info->framereg = AVR_FP_REGNUM;
      return;
    }

  /* Scan interrupt or signal function */

  if (prologue_len >= 12)
    {
      unsigned char img[] = {
	0x78, 0x94,		/* sei */
	0x1f, 0x92,		/* push r1 */
	0x0f, 0x92,		/* push r0 */
	0x0f, 0xb6,		/* in r0,0x3f SREG */
	0x0f, 0x92,		/* push r0 */
	0x11, 0x24		/* clr r1 */
      };
      if (memcmp (prologue, img, sizeof (img)) == 0)
	{
	  vpc += sizeof (img);
	  fi->saved_regs[0] = 2;
	  fi->saved_regs[1] = 1;
	  fi->extra_info->framesize += 3;
	}
      else if (memcmp (img + 1, prologue, sizeof (img) - 1) == 0)
	{
	  vpc += sizeof (img) - 1;
	  fi->saved_regs[0] = 2;
	  fi->saved_regs[1] = 1;
	  fi->extra_info->framesize += 3;
	}
    }

  /* First stage of the prologue scanning.
     Scan pushes */

  for (; vpc <= prologue_len; vpc += 2)
    {
      insn = EXTRACT_INSN (&prologue[vpc]);
      if ((insn & 0xfe0f) == 0x920f)	/* push rXX */
	{
	  /* Bits 4-9 contain a mask for registers R0-R32. */
	  regno = (insn & 0x1f0) >> 4;
	  ++fi->extra_info->framesize;
	  fi->saved_regs[regno] = fi->extra_info->framesize;
	  scan_stage = 1;
	}
      else
	break;
    }

  /* Second stage of the prologue scanning.
     Scan:
     in r28,__SP_L__
     in r29,__SP_H__ */

  if (scan_stage == 1 && vpc + 4 <= prologue_len)
    {
      unsigned char img[] = {
	0xcd, 0xb7,		/* in r28,__SP_L__ */
	0xde, 0xb7		/* in r29,__SP_H__ */
      };
      unsigned short insn1;

      if (memcmp (prologue + vpc, img, sizeof (img)) == 0)
	{
	  vpc += 4;
	  fi->extra_info->framereg = AVR_FP_REGNUM;
	  scan_stage = 2;
	}
    }

  /* Third stage of the prologue scanning. (Really two stages)
     Scan for:
     sbiw r28,XX or subi r28,lo8(XX)
     sbci r29,hi8(XX)
     in __tmp_reg__,__SREG__
     cli
     out __SP_L__,r28
     out __SREG__,__tmp_reg__
     out __SP_H__,r29 */

  if (scan_stage == 2 && vpc + 12 <= prologue_len)
    {
      int locals_size = 0;
      unsigned char img[] = {
	0x0f, 0xb6,		/* in r0,0x3f */
	0xf8, 0x94,		/* cli */
	0xcd, 0xbf,		/* out 0x3d,r28 ; SPL */
	0x0f, 0xbe,		/* out 0x3f,r0  ; SREG */
	0xde, 0xbf		/* out 0x3e,r29 ; SPH */
      };
      unsigned char img_sig[] = {
	0xcd, 0xbf,		/* out 0x3d,r28 ; SPL */
	0xde, 0xbf		/* out 0x3e,r29 ; SPH */
      };
      unsigned char img_int[] = {
	0xf8, 0x94,		/* cli */
	0xcd, 0xbf,		/* out 0x3d,r28 ; SPL */
	0x78, 0x94,		/* sei */
	0xde, 0xbf		/* out 0x3e,r29 ; SPH */
      };

      insn = EXTRACT_INSN (&prologue[vpc]);
      vpc += 2;
      if ((insn & 0xff30) == 0x9720)	/* sbiw r28,XXX */
	locals_size = (insn & 0xf) | ((insn & 0xc0) >> 2);
      else if ((insn & 0xf0f0) == 0x50c0)	/* subi r28,lo8(XX) */
	{
	  locals_size = (insn & 0xf) | ((insn & 0xf00) >> 4);
	  insn = EXTRACT_INSN (&prologue[vpc]);
	  vpc += 2;
	  locals_size += ((insn & 0xf) | ((insn & 0xf00) >> 4) << 8);
	}
      else
	return;
      fi->extra_info->locals_size = locals_size;
      fi->extra_info->framesize += locals_size;
    }
}

/* This function actually figures out the frame address for a given pc and
   sp.  This is tricky  because we sometimes don't use an explicit
   frame pointer, and the previous stack pointer isn't necessarily recorded
   on the stack.  The only reliable way to get this info is to
   examine the prologue.  */

static void
avr_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
  int reg;

  if (fi->next)
    fi->pc = FRAME_SAVED_PC (fi->next);

  fi->extra_info = (struct frame_extra_info *)
    frame_obstack_alloc (sizeof (struct frame_extra_info));
  frame_saved_regs_zalloc (fi);

  fi->extra_info->return_pc = 0;
  fi->extra_info->args_pointer = 0;
  fi->extra_info->locals_size = 0;
  fi->extra_info->framereg = 0;
  fi->extra_info->framesize = 0;
  fi->extra_info->is_main = 0;

  avr_scan_prologue (fi);

  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    {
      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
         by assuming it's always FP.  */
      fi->frame = generic_read_register_dummy (fi->pc, fi->frame, fi->frame);
    }
  else if (!fi->next)		/* this is the innermost frame? */
    fi->frame = read_register (fi->extra_info->framereg);
  else if (fi->extra_info->is_main != 1)	/* not the innermost frame, not `main' */
    /* If we have an next frame,  the callee saved it. */
    {
      struct frame_info *next_fi = fi->next;
      if (fi->extra_info->framereg == AVR_SP_REGNUM)
	fi->frame =
	  next_fi->frame + 2 /* ret addr */  + next_fi->extra_info->framesize;
      /* FIXME: I don't analyse va_args functions  */
      else
	{
	  CORE_ADDR fp = 0;
	  CORE_ADDR fp1 = 0;
	  unsigned int fp_low, fp_high;

	  /* Scan all frames */
	  for (; next_fi; next_fi = next_fi->next)
	    {
	      /* look for saved AVR_FP_REGNUM */
	      if (next_fi->saved_regs[AVR_FP_REGNUM] && !fp)
		fp = next_fi->saved_regs[AVR_FP_REGNUM];
	      /* look for saved AVR_FP_REGNUM + 1 */
	      if (next_fi->saved_regs[AVR_FP_REGNUM + 1] && !fp1)
		fp1 = next_fi->saved_regs[AVR_FP_REGNUM + 1];
	    }
	  fp_low = (fp ? read_memory_unsigned_integer (avr_make_saddr (fp), 1)
		    : read_register (AVR_FP_REGNUM)) & 0xff;
	  fp_high =
	    (fp1 ? read_memory_unsigned_integer (avr_make_saddr (fp1), 1) :
	     read_register (AVR_FP_REGNUM + 1)) & 0xff;
	  fi->frame = fp_low | (fp_high << 8);
	}
    }

  /* TRoth: Do we want to do this if we are in main? I don't think we should
     since return_pc makes no sense when we are in main. */

  if ((fi->pc) && (fi->extra_info->is_main == 0))	/* We are not in CALL_DUMMY */
    {
      CORE_ADDR addr;
      int i;

      addr = fi->frame + fi->extra_info->framesize + 1;

      /* Return address in stack in different endianness */

      fi->extra_info->return_pc =
	read_memory_unsigned_integer (avr_make_saddr (addr), 1) << 8;
      fi->extra_info->return_pc |=
	read_memory_unsigned_integer (avr_make_saddr (addr + 1), 1);

      /* This return address in words,
         must be converted to the bytes address */
      fi->extra_info->return_pc *= 2;

      /* Resolve a pushed registers addresses */
      for (i = 0; i < NUM_REGS; i++)
	{
	  if (fi->saved_regs[i])
	    fi->saved_regs[i] = addr - fi->saved_regs[i];
	}
    }
}

/* Restore the machine to the state it had before the current frame was
   created.  Usually used either by the "RETURN" command, or by
   call_function_by_hand after the dummy_frame is finished. */

static void
avr_pop_frame (void)
{
  unsigned regnum;
  CORE_ADDR saddr;
  struct frame_info *frame = get_current_frame ();

  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    {
      generic_pop_dummy_frame ();
    }
  else
    {
      /* TRoth: Why only loop over 8 registers? */

      for (regnum = 0; regnum < 8; regnum++)
	{
	  /* Don't forget AVR_SP_REGNUM in a frame_saved_regs struct is the
	     actual value we want, not the address of the value we want.  */
	  if (frame->saved_regs[regnum] && regnum != AVR_SP_REGNUM)
	    {
	      saddr = avr_make_saddr (frame->saved_regs[regnum]);
	      write_register (regnum,
			      read_memory_unsigned_integer (saddr, 1));
	    }
	  else if (frame->saved_regs[regnum] && regnum == AVR_SP_REGNUM)
	    write_register (regnum, frame->frame + 2);
	}

      /* Don't forget the update the PC too!  */
      write_pc (frame->extra_info->return_pc);
    }
  flush_cached_frames ();
}

/* Return the saved PC from this frame. */

static CORE_ADDR
avr_frame_saved_pc (struct frame_info *frame)
{
  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    return generic_read_register_dummy (frame->pc, frame->frame,
					AVR_PC_REGNUM);
  else
    return frame->extra_info->return_pc;
}

static CORE_ADDR
avr_saved_pc_after_call (struct frame_info *frame)
{
  unsigned char m1, m2;
  unsigned int sp = read_register (AVR_SP_REGNUM);
  m1 = read_memory_unsigned_integer (avr_make_saddr (sp + 1), 1);
  m2 = read_memory_unsigned_integer (avr_make_saddr (sp + 2), 1);
  return (m2 | (m1 << 8)) * 2;
}

/* Figure out where in REGBUF the called function has left its return value.
   Copy that into VALBUF. */

static void
avr_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
  int wordsize, len;

  wordsize = 2;

  len = TYPE_LENGTH (type);

  switch (len)
    {
    case 1:			/* (char) */
    case 2:			/* (short), (int) */
      memcpy (valbuf, regbuf + REGISTER_BYTE (24), 2);
      break;
    case 4:			/* (long), (float) */
      memcpy (valbuf, regbuf + REGISTER_BYTE (22), 4);
      break;
    case 8:			/* (double) (doesn't seem to happen, which is good,
				   because this almost certainly isn't right.  */
      error ("I don't know how a double is returned.");
      break;
    }
}

/* Returns the return address for a dummy. */

static CORE_ADDR
avr_call_dummy_address (void)
{
  return entry_point_address ();
}

/* Place the appropriate value in the appropriate registers.
   Primarily used by the RETURN command.  */

static void
avr_store_return_value (struct type *type, char *valbuf)
{
  int wordsize, len, regval;

  wordsize = 2;

  len = TYPE_LENGTH (type);
  switch (len)
    {
    case 1:			/* char */
    case 2:			/* short, int */
      regval = extract_address (valbuf, len);
      write_register (0, regval);
      break;
    case 4:			/* long, float */
      regval = extract_address (valbuf, len);
      write_register (0, regval >> 16);
      write_register (1, regval & 0xffff);
      break;
    case 8:			/* presumeably double, but doesn't seem to happen */
      error ("I don't know how to return a double.");
      break;
    }
}

/* Setup the return address for a dummy frame, as called by
   call_function_by_hand.  Only necessary when you are using an empty
   CALL_DUMMY. */

static CORE_ADDR
avr_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
  unsigned char buf[2];
  int wordsize = 2;
  struct minimal_symbol *msymbol;
  CORE_ADDR mon_brk;

  fprintf_unfiltered (gdb_stderr, "avr_push_return_address() was called\n");

  buf[0] = 0;
  buf[1] = 0;
  sp -= wordsize;
  write_memory (sp + 1, buf, 2);

#if 0
  /* FIXME: TRoth/2002-02-18: This should probably be removed since it's a
     left-over from Denis' original patch which used avr-mon for the target
     instead of the generic remote target. */
  if ((strcmp (target_shortname, "avr-mon") == 0)
      && (msymbol = lookup_minimal_symbol ("gdb_break", NULL, NULL)))
    {
      mon_brk = SYMBOL_VALUE_ADDRESS (msymbol);
      store_unsigned_integer (buf, wordsize, mon_brk / 2);
      sp -= wordsize;
      write_memory (sp + 1, buf + 1, 1);
      write_memory (sp + 2, buf, 1);
    }
#endif
  return sp;
}

static CORE_ADDR
avr_skip_prologue (CORE_ADDR pc)
{
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;

  /* See what the symbol table says */

  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      sal = find_pc_line (func_addr, 0);

      if (sal.line != 0 && sal.end < func_end)
	return sal.end;
    }

/* Either we didn't find the start of this function (nothing we can do),
   or there's no line info, or the line after the prologue is after
   the end of the function (there probably isn't a prologue). */

  return pc;
}

static CORE_ADDR
avr_frame_address (struct frame_info *fi)
{
  return avr_make_saddr (fi->frame);
}

/* Given a GDB frame, determine the address of the calling function's frame.
   This will be used to create a new GDB frame struct, and then
   INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.

   For us, the frame address is its stack pointer value, so we look up
   the function prologue to determine the caller's sp value, and return it.  */

static CORE_ADDR
avr_frame_chain (struct frame_info *frame)
{
  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    {
      /* initialize the return_pc now */
      frame->extra_info->return_pc = generic_read_register_dummy (frame->pc,
								  frame->
								  frame,
								  AVR_PC_REGNUM);
      return frame->frame;
    }
  return (frame->extra_info->is_main ? 0
	  : frame->frame + frame->extra_info->framesize + 2 /* ret addr */ );
}

/* Store the address of the place in which to copy the structure the
   subroutine will return.  This is called from call_function. 

   We store structs through a pointer passed in the first Argument
   register. */

static void
avr_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
  write_register (0, addr);
}

/* Extract from an array REGBUF containing the (raw) register state
   the address in which a function should return its structure value,
   as a CORE_ADDR (or an expression that can be used as one). */

static CORE_ADDR
avr_extract_struct_value_address (char *regbuf)
{
  return (extract_address ((regbuf) + REGISTER_BYTE (0),
			   REGISTER_RAW_SIZE (0)) | AVR_SMEM_START);
}

/* Setup the function arguments for calling a function in the inferior.

   On the AVR architecture, there are 18 registers (R25 to R8) which are
   dedicated for passing function arguments.  Up to the first 18 arguments
   (depending on size) may go into these registers.  The rest go on the stack.

   Arguments that are larger than WORDSIZE bytes will be split between two or
   more registers as available, but will NOT be split between a register and
   the stack.

   An exceptional case exists for struct arguments (and possibly other
   aggregates such as arrays) -- if the size is larger than WORDSIZE bytes but
   not a multiple of WORDSIZE bytes.  In this case the argument is never split
   between the registers and the stack, but instead is copied in its entirety
   onto the stack, AND also copied into as many registers as there is room
   for.  In other words, space in registers permitting, two copies of the same
   argument are passed in.  As far as I can tell, only the one on the stack is
   used, although that may be a function of the level of compiler
   optimization.  I suspect this is a compiler bug.  Arguments of these odd
   sizes are left-justified within the word (as opposed to arguments smaller
   than WORDSIZE bytes, which are right-justified).
 
   If the function is to return an aggregate type such as a struct, the caller
   must allocate space into which the callee will copy the return value.  In
   this case, a pointer to the return value location is passed into the callee
   in register R0, which displaces one of the other arguments passed in via
   registers R0 to R2. */

static CORE_ADDR
avr_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
		    int struct_return, CORE_ADDR struct_addr)
{
  int stack_alloc, stack_offset;
  int wordsize;
  int argreg;
  int argnum;
  struct type *type;
  CORE_ADDR regval;
  char *val;
  char valbuf[4];
  int len;

  wordsize = 1;
#if 0
  /* Now make sure there's space on the stack */
  for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
    stack_alloc += TYPE_LENGTH (VALUE_TYPE (args[argnum]));
  sp -= stack_alloc;		/* make room on stack for args */
  /* we may over-allocate a little here, but that won't hurt anything */
#endif
  argreg = 25;
  if (struct_return)		/* "struct return" pointer takes up one argreg */
    {
      write_register (--argreg, struct_addr);
    }

  /* Now load as many as possible of the first arguments into registers, and
     push the rest onto the stack.  There are 3N bytes in three registers
     available.  Loop thru args from first to last.  */

  for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
    {
      type = VALUE_TYPE (args[argnum]);
      len = TYPE_LENGTH (type);
      val = (char *) VALUE_CONTENTS (args[argnum]);

      /* NOTE WELL!!!!!  This is not an "else if" clause!!!  That's because
         some *&^%$ things get passed on the stack AND in the registers!  */
      while (len > 0)
	{			/* there's room in registers */
	  len -= wordsize;
	  regval = extract_address (val + len, wordsize);
	  write_register (argreg--, regval);
	}
    }
  return sp;
}

/* Initialize the gdbarch structure for the AVR's. */

static struct gdbarch *
avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  /* FIXME: TRoth/2002-02-18: I have no idea if avr_call_dummy_words[] should
     be bigger or not. Initial testing seems to show that `call my_func()`
     works and backtrace from a breakpoint within the call looks correct.
     Admittedly, I haven't tested with more than a very simple program. */
  static LONGEST avr_call_dummy_words[] = { 0 };

  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;

  /* Find a candidate among the list of pre-declared architectures. */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  /* None found, create a new architecture from the information provided. */
  tdep = XMALLOC (struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);

  /* If we ever need to differentiate the device types, do it here. */
  switch (info.bfd_arch_info->mach)
    {
    case bfd_mach_avr1:
    case bfd_mach_avr2:
    case bfd_mach_avr3:
    case bfd_mach_avr4:
    case bfd_mach_avr5:
      break;
    }

  set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
  set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_addr_bit (gdbarch, 32);
  set_gdbarch_bfd_vma_bit (gdbarch, 32);	/* FIXME: TRoth/2002-02-18: Is this needed? */

  set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);

  set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_little);
  set_gdbarch_double_format (gdbarch, &floatformat_ieee_single_little);
  set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_single_little);

  set_gdbarch_read_pc (gdbarch, avr_read_pc);
  set_gdbarch_write_pc (gdbarch, avr_write_pc);
  set_gdbarch_read_fp (gdbarch, avr_read_fp);
  set_gdbarch_read_sp (gdbarch, avr_read_sp);
  set_gdbarch_write_sp (gdbarch, avr_write_sp);

  set_gdbarch_num_regs (gdbarch, AVR_NUM_REGS);

  set_gdbarch_sp_regnum (gdbarch, AVR_SP_REGNUM);
  set_gdbarch_fp_regnum (gdbarch, AVR_FP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, AVR_PC_REGNUM);

  set_gdbarch_register_name (gdbarch, avr_register_name);
  set_gdbarch_register_size (gdbarch, 1);
  set_gdbarch_register_bytes (gdbarch, AVR_NUM_REG_BYTES);
  set_gdbarch_register_byte (gdbarch, avr_register_byte);
  set_gdbarch_register_raw_size (gdbarch, avr_register_raw_size);
  set_gdbarch_max_register_raw_size (gdbarch, 4);
  set_gdbarch_register_virtual_size (gdbarch, avr_register_virtual_size);
  set_gdbarch_max_register_virtual_size (gdbarch, 4);
  set_gdbarch_register_virtual_type (gdbarch, avr_register_virtual_type);

  /* We might need to define our own here or define FRAME_INIT_SAVED_REGS */
  set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);

  set_gdbarch_print_insn (gdbarch, print_insn_avr);

  set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
  set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
  set_gdbarch_call_dummy_address (gdbarch, avr_call_dummy_address);
  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
  set_gdbarch_call_dummy_length (gdbarch, 0);
  set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
  set_gdbarch_call_dummy_p (gdbarch, 1);
  set_gdbarch_call_dummy_words (gdbarch, avr_call_dummy_words);
  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
  set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);

/*    set_gdbarch_believe_pcc_promotion (gdbarch, 1); // TRoth: should this be set? */

  set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer);
  set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address);
  set_gdbarch_extract_return_value (gdbarch, avr_extract_return_value);
  set_gdbarch_push_arguments (gdbarch, avr_push_arguments);
  set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
/*    set_gdbarch_push_return_address (gdbarch, avr_push_return_address); */
  set_gdbarch_pop_frame (gdbarch, avr_pop_frame);

  set_gdbarch_store_return_value (gdbarch, avr_store_return_value);

  set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
  set_gdbarch_store_struct_return (gdbarch, avr_store_struct_return);
  set_gdbarch_extract_struct_value_address (gdbarch,
					    avr_extract_struct_value_address);

  set_gdbarch_frame_init_saved_regs (gdbarch, avr_scan_prologue);
  set_gdbarch_init_extra_frame_info (gdbarch, avr_init_extra_frame_info);
  set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue);
/*    set_gdbarch_prologue_frameless_p (gdbarch, avr_prologue_frameless_p); */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  set_gdbarch_decr_pc_after_break (gdbarch, 0);

  set_gdbarch_function_start_offset (gdbarch, 0);
  set_gdbarch_remote_translate_xfer_address (gdbarch,
					     avr_remote_translate_xfer_address);
  set_gdbarch_frame_args_skip (gdbarch, 0);
  set_gdbarch_frameless_function_invocation (gdbarch, frameless_look_for_prologue);	/* ??? */
  set_gdbarch_frame_chain (gdbarch, avr_frame_chain);
  set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid);
  set_gdbarch_frame_saved_pc (gdbarch, avr_frame_saved_pc);
  set_gdbarch_frame_args_address (gdbarch, avr_frame_address);
  set_gdbarch_frame_locals_address (gdbarch, avr_frame_address);
  set_gdbarch_saved_pc_after_call (gdbarch, avr_saved_pc_after_call);
  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);

  set_gdbarch_convert_from_func_ptr_addr (gdbarch,
					  avr_convert_from_func_ptr_addr);

  return gdbarch;
}

/* Send a query request to the avr remote target asking for values of the io
   registers. If args parameter is not NULL, then the user has requested info
   on a specific io register [This still needs implemented and is ignored for
   now]. The query string should be one of these forms:

   "Ravr.io_reg" -> reply is "NN" number of io registers

   "Ravr.io_reg:addr,len" where addr is first register and len is number of
   registers to be read. The reply should be "<NAME>,VV;" for each io register
   where, <NAME> is a string, and VV is the hex value of the register.

   All io registers are 8-bit. */

static void
avr_io_reg_read_command (char *args, int from_tty)
{
  int bufsiz = 0;
  char buf[400];
  char query[400];
  char *p;
  unsigned int nreg = 0;
  unsigned int val;
  int i, j, k, step;

/*    fprintf_unfiltered (gdb_stderr, "DEBUG: avr_io_reg_read_command (\"%s\", %d)\n", */
/*             args, from_tty); */

  if (!current_target.to_query)
    {
      fprintf_unfiltered (gdb_stderr,
			  "ERR: info io_registers NOT supported by current target\n");
      return;
    }

  /* Just get the maximum buffer size. */
  target_query ((int) 'R', 0, 0, &bufsiz);
  if (bufsiz > sizeof (buf))
    bufsiz = sizeof (buf);

  /* Find out how many io registers the target has. */
  strcpy (query, "avr.io_reg");
  target_query ((int) 'R', query, buf, &bufsiz);

  if (strncmp (buf, "", bufsiz) == 0)
    {
      fprintf_unfiltered (gdb_stderr,
			  "info io_registers NOT supported by target\n");
      return;
    }

  if (sscanf (buf, "%x", &nreg) != 1)
    {
      fprintf_unfiltered (gdb_stderr,
			  "Error fetching number of io registers\n");
      return;
    }

  reinitialize_more_filter ();

  printf_unfiltered ("Target has %u io registers:\n\n", nreg);

  /* only fetch up to 8 registers at a time to keep the buffer small */
  step = 8;

  for (i = 0; i < nreg; i += step)
    {
      j = step - (nreg % step);	/* how many registers this round? */

      snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
      target_query ((int) 'R', query, buf, &bufsiz);

      p = buf;
      for (k = i; k < (i + j); k++)
	{
	  if (sscanf (p, "%[^,],%x;", query, &val) == 2)
	    {
	      printf_filtered ("[%02x] %-15s : %02x\n", k, query, val);
	      while ((*p != ';') && (*p != '\0'))
		p++;
	      p++;		/* skip over ';' */
	      if (*p == '\0')
		break;
	    }
	}
    }
}

void
_initialize_avr_tdep (void)
{
  register_gdbarch_init (bfd_arch_avr, avr_gdbarch_init);

  /* Add a new command to allow the user to query the avr remote target for
     the values of the io space registers in a saner way than just using
     `x/NNNb ADDR`. */

  /* FIXME: TRoth/2002-02-18: This should probably be changed to 'info avr
     io_registers' to signify it is not available on other platforms. */

  add_cmd ("io_registers", class_info, avr_io_reg_read_command,
	   "query remote avr target for io space register values", &infolist);
}
