/*  This file is part of the program psim.
    
    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
    
    */


#ifndef _HW_VM_C_
#define _HW_VM_C_

#include "device_table.h"
#include "cpu.h"

#include <signal.h>

/* DEVICE

   vm - virtual memory device for user simulation modes

   DESCRIPTION

   In user mode, mapped text, data and stack addresses are managed by
   the core.  Unmapped addresses are passed onto this device (because
   it establishes its self as the fallback device) for processing.

   During initialization, children of this device will request the
   mapping of the initial text and data segments.  Those requests are
   passed onto the core device so that that may establish the initial
   memory regions.

   Once the simulation has started (as noted above) any access to an
   unmapped address range will be passed down to this device as an IO
   access.  This device will then either attach additional memory to
   the core device or signal the access as being invalid.

   The IOCTL function is used to notify this device of any changes to
   the users `brk' point.

   PROPERTIES

   stack-base = <number>

   Specifies the lower address of the stack segment in the users
   virtual address space.  The initial stack page is defined by
   stack-base + nr-bytes.

   nr-bytes = <number>

   Specifies the maximum size of the stack segment in the users
   address space.

   */

typedef struct _hw_vm_device {
  /* area of memory valid for stack addresses */
  unsigned_word stack_base; /* min possible stack value */
  unsigned_word stack_bound;
  unsigned_word stack_lower_limit;
  /* area of memory valid for heap addresses */
  unsigned_word heap_base;
  unsigned_word heap_bound;
  unsigned_word heap_upper_limit;
} hw_vm_device;


static void
hw_vm_init_address_callback(device *me)
{
  hw_vm_device *vm = (hw_vm_device*)device_data(me);

  /* revert the stack/heap variables to their defaults */
  vm->stack_base = device_find_integer_property(me, "stack-base");
  vm->stack_bound = (vm->stack_base
		     + device_find_integer_property(me, "nr-bytes"));
  vm->stack_lower_limit = vm->stack_bound;
  vm->heap_base = 0;
  vm->heap_bound = 0;
  vm->heap_upper_limit = 0;

  /* establish this device as the default memory handler */
  device_attach_address(device_parent(me),
			attach_callback + 1,
			0 /*address space - ignore*/,
			0 /*addr - ignore*/,
			(((unsigned)0)-1) /*nr_bytes - ignore*/,
			access_read_write /*access*/,
			me);
}


static void
hw_vm_attach_address(device *me,
		     attach_type attach,
		     int space,
		     unsigned_word addr,
		     unsigned nr_bytes,
		     access_type access,
		     device *client) /*callback/default*/
{
  hw_vm_device *vm = (hw_vm_device*)device_data(me);
  /* update end of bss if necessary */
  if (vm->heap_base < addr + nr_bytes) {
    vm->heap_base = addr + nr_bytes;
    vm->heap_bound = addr + nr_bytes;
    vm->heap_upper_limit = addr + nr_bytes;
  }
  device_attach_address(device_parent(me),
			attach_raw_memory,
			0 /*address space*/,
			addr,
			nr_bytes,
			access,
			me);
}


static unsigned
hw_vm_add_space(device *me,
		unsigned_word addr,
		unsigned nr_bytes,
		cpu *processor,
		unsigned_word cia)
{
  hw_vm_device *vm = (hw_vm_device*)device_data(me);
  unsigned_word block_addr;
  unsigned block_nr_bytes;

  /* an address in the stack area, allocate just down to the addressed
     page */
  if (addr >= vm->stack_base && addr < vm->stack_lower_limit) {
    block_addr = FLOOR_PAGE(addr);
    block_nr_bytes = vm->stack_lower_limit - block_addr;
    vm->stack_lower_limit = block_addr;
  }
  /* an address in the heap area, allocate all of the required heap */
  else if (addr >= vm->heap_upper_limit && addr < vm->heap_bound) {
    block_addr = vm->heap_upper_limit;
    block_nr_bytes = vm->heap_bound - vm->heap_upper_limit;
    vm->heap_upper_limit = vm->heap_bound;
  }
  /* oops - an invalid address - abort the cpu */
  else if (processor != NULL) {
    cpu_halt(processor, cia, was_signalled, SIGSEGV);
    return 0;
  }
  /* 2*oops - an invalid address and no processor */
  else {
    return 0;
  }

  /* got the parameters, allocate the space */
  device_attach_address(device_parent(me),
			attach_raw_memory,
			0 /*address space*/,
			block_addr,
			block_nr_bytes,
			access_read_write,
			me);
  return block_nr_bytes;
}


static unsigned
hw_vm_io_read_buffer_callback(device *me,
			   void *dest,
			   int space,
			   unsigned_word addr,
			   unsigned nr_bytes,
			   cpu *processor,
			   unsigned_word cia)
{
  if (hw_vm_add_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
    memset(dest, 0, nr_bytes); /* always initialized to zero */
    return nr_bytes;
  }
  else 
    return 0;
}


static unsigned
hw_vm_io_write_buffer_callback(device *me,
			    const void *source,
			    int space,
			    unsigned_word addr,
			    unsigned nr_bytes,
			    cpu *processor,
			    unsigned_word cia)
{
  if (hw_vm_add_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
    return device_dma_write_buffer(device_parent(me), source,
				   space, addr,
				   nr_bytes,
				   0/*violate_read_only*/);
  }
  else
    return 0;
}


static int
hw_vm_ioctl(device *me,
	    cpu *processor,
	    unsigned_word cia,
	    device_ioctl_request request,
	    va_list ap)
{
  /* While the caller is notified that the heap has grown by the
     requested amount, the heap is actually extended out to a page
     boundary. */
  hw_vm_device *vm = (hw_vm_device*)device_data(me);
  switch (request) {
  case device_ioctl_break:
    {
      unsigned_word requested_break = va_arg(ap, unsigned_word);
      unsigned_word new_break = ALIGN_8(requested_break);
      unsigned_word old_break = vm->heap_bound;
      signed_word delta = new_break - old_break;
      if (delta > 0)
	vm->heap_bound = ALIGN_PAGE(new_break);
      break;
    }
  default:
    device_error(me, "Unsupported ioctl request");
    break;
  }
  return 0;
    
}


static device_callbacks const hw_vm_callbacks = {
  { hw_vm_init_address_callback, },
  { hw_vm_attach_address,
    passthrough_device_address_detach, },
  { hw_vm_io_read_buffer_callback,
    hw_vm_io_write_buffer_callback, },
  { NULL, passthrough_device_dma_write_buffer, },
  { NULL, }, /* interrupt */
  { generic_device_unit_decode,
    generic_device_unit_encode, },
  NULL, /* instance */
  hw_vm_ioctl,
};


static void *
hw_vm_create(const char *name,
	     const device_unit *address,
	     const char *args)
{
  hw_vm_device *vm = ZALLOC(hw_vm_device);
  return vm;
}

const device_descriptor hw_vm_device_descriptor[] = {
  { "vm", hw_vm_create, &hw_vm_callbacks },
  { NULL },
};

#endif /* _HW_VM_C_ */
