/* 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"
#include "gdb_string.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 const 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;

		  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 (DEPRECATED_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 = deprecated_read_register_dummy (fi->pc, fi->frame,
						  AVR_PC_REGNUM);
    }
  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 (DEPRECATED_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 (DEPRECATED_PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    return deprecated_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;
#if 0
  struct minimal_symbol *msymbol;
  CORE_ADDR mon_brk;
#endif

  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);

      /* troth/2002-08-05: For some very simple functions, gcc doesn't
         generate a prologue and the sal.end ends up being the 2-byte ``ret''
         instruction at the end of the function, but func_end ends up being
         the address of the first instruction of the _next_ function. By
         adjusting func_end by 2 bytes, we can catch these functions and not
         return sal.end if it is the ``ret'' instruction. */

      if (sal.line != 0 && sal.end < (func_end-2))
	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 DEPRECATED_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 (DEPRECATED_PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    {
      /* initialize the return_pc now */
      frame->extra_info->return_pc
	= deprecated_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);

  /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
     ready to unwind the PC first (see frame.c:get_prev_frame()).  */
  set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);

  /* 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);

  set_gdbarch_print_insn (gdbarch, print_insn_avr);

  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_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_deprecated_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_deprecated_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_deprecated_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);
}
