/*  This file is part of the program psim.

    Copyright (C) 1994-1997, 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_MEMORY_C_
#define _HW_MEMORY_C_

#ifndef STATIC_INLINE_HW_MEMORY
#define STATIC_INLINE_HW_MEMORY STATIC_INLINE
#endif

#include <stdlib.h>

#include "device_table.h"

/* DEVICE


   memory - description of system memory


   DESCRIPTION


   This device describes the size and location of the banks of
   physical memory within the simulation.

   In addition, this device supports the "claim" and "release" methods
   that can be used by OpenBoot client programs to manage the
   allocation of physical memory.


   PROPERTIES


   reg = { <address> <size> } (required)

   Each pair specify one bank of memory.

   available = { <address> <size> } (automatic)

   Each pair specifies a block of memory that is currently unallocated.  


   BUGS


   OpenFirmware doesn't make it clear if, when releasing memory the
   same address + size pair as was used during the claim should be
   specified.

   It is assumed that #size-cells and #address-cells for the parent
   node of this device are both one i.e. an address or size can be
   specified using a single memory cell (word).

   Significant work will be required before the <<memory>> device can
   support 64bit addresses (#address-cells equal two).

   */

typedef struct _memory_reg_spec {
  unsigned_cell base;
  unsigned_cell size;
} memory_reg_spec;

typedef struct _hw_memory_chunk hw_memory_chunk;
struct _hw_memory_chunk {
  unsigned_word address;
  unsigned_word size;
  int available;
  hw_memory_chunk *next;
};

typedef struct _hw_memory_device {
  hw_memory_chunk *heap;
} hw_memory_device;


static void *
hw_memory_create(const char *name,
		 const device_unit *unit_address,
		 const char *args)
{
  hw_memory_device *hw_memory = ZALLOC(hw_memory_device);
  return hw_memory;
}


static void
hw_memory_set_available(device *me,
			hw_memory_device *hw_memory)
{
  hw_memory_chunk *chunk = NULL;
  memory_reg_spec *available = NULL;
  int nr_available = 0;
  int curr = 0;
  int sizeof_available = 0;
  /* determine the nr of available chunks */
  chunk = hw_memory->heap;
  nr_available = 0;
  while (chunk != NULL) {
    if (chunk->available)
      nr_available += 1;
    ASSERT(chunk->next == NULL
	   || chunk->address < chunk->next->address);
    ASSERT(chunk->next == NULL
	   || chunk->address + chunk->size == chunk->next->address);
    chunk = chunk->next;
  }
  /* now create the available struct */
  ASSERT(nr_available > 0);
  sizeof_available = sizeof(memory_reg_spec) * nr_available;
  available = zalloc(sizeof_available);
  chunk = hw_memory->heap;
  curr = 0;
  while (chunk != NULL) {
    if (chunk->available) {
      available[curr].base = H2BE_cell(chunk->address);
      available[curr].size = H2BE_cell(chunk->size);
      curr += 1;
    }
    chunk = chunk->next;
  }
  /* update */
  device_set_array_property(me, "available", available, sizeof_available);
  free(available);
}


static void
hw_memory_init_address(device *me)
{
  hw_memory_device *hw_memory = (hw_memory_device*)device_data(me);

  /* free up any previous structures */
  {
    hw_memory_chunk *curr_chunk = hw_memory->heap;
    hw_memory->heap = NULL;
    while (curr_chunk != NULL) {
      hw_memory_chunk *dead_chunk = curr_chunk;
      curr_chunk = dead_chunk->next;
      dead_chunk->next = NULL;
      free(dead_chunk);
    }
  }

  /* attach memory regions according to the "reg" property */
  {
    int reg_nr;
    reg_property_spec reg;
    for (reg_nr = 0;
	 device_find_reg_array_property(me, "reg", reg_nr, &reg);
	 reg_nr++) {
      int i;
      /* check that the entry meets restrictions */
      for (i = 0; i < reg.address.nr_cells - 1; i++)
	if (reg.address.cells[i] != 0)
	  device_error(me, "Only single celled addresses supported");
      for (i = 0; i < reg.size.nr_cells - 1; i++)
	if (reg.size.cells[i] != 0)
	  device_error(me, "Only single celled sizes supported");
      /* attach the range */
      device_attach_address(device_parent(me),
			    attach_raw_memory,
			    0 /*address space*/,
			    reg.address.cells[reg.address.nr_cells - 1],
			    reg.size.cells[reg.size.nr_cells - 1],
			    access_read_write_exec,
			    me);
    }
  }

  /* create the initial `available memory' data structure */
  if (device_find_property(me, "available") != NULL) {
    hw_memory_chunk **curr_chunk = &hw_memory->heap;
    int cell_nr;
    signed_cell dummy;
    int nr_cells = device_find_integer_array_property(me, "available", 0, &dummy);
    if ((nr_cells % 2) != 0)
      device_error(me, "property \"available\" invalid - contains an odd number of cells");
    for (cell_nr = 0;
	 cell_nr < nr_cells;
	 cell_nr += 2) {
      hw_memory_chunk *new_chunk = ZALLOC(hw_memory_chunk);
      device_find_integer_array_property(me, "available", cell_nr,
					 (signed_cell *)&new_chunk->address);
      device_find_integer_array_property(me, "available", cell_nr + 1,
					 (signed_cell *)&new_chunk->size);
      new_chunk->available = 1;
      *curr_chunk = new_chunk;
      curr_chunk = &new_chunk->next;
    }
  }
  else {
    hw_memory_chunk **curr_chunk = &hw_memory->heap;
    int reg_nr;
    reg_property_spec reg;
    for (reg_nr = 0;
	 device_find_reg_array_property(me, "reg", reg_nr, &reg);
	 reg_nr++) {
      hw_memory_chunk *new_chunk;
      new_chunk = ZALLOC(hw_memory_chunk);
      new_chunk->address = reg.address.cells[reg.address.nr_cells - 1];
      new_chunk->size = reg.size.cells[reg.size.nr_cells - 1];
      new_chunk->available = 1;
      *curr_chunk = new_chunk;
      curr_chunk = &new_chunk->next;
    }
  }

  /* initialize the alloc property for this device */
  hw_memory_set_available(me, hw_memory);
}

static void
hw_memory_instance_delete(device_instance *instance)
{
  return;
}

static int
hw_memory_instance_claim(device_instance *instance,
			 int n_stack_args,
			 unsigned_cell stack_args[/*n_stack_args*/],
			 int n_stack_returns,
			 unsigned_cell stack_returns[/*n_stack_returns*/])
{
  hw_memory_device *hw_memory = device_instance_data(instance);
  device *me = device_instance_device(instance);
  int stackp = 0;
  unsigned_word alignment;
  unsigned_cell size;
  unsigned_cell address;
  hw_memory_chunk *chunk = NULL;

  /* get the alignment from the stack */
  if (n_stack_args < stackp + 1)
    device_error(me, "claim - incorrect number of arguments (alignment missing)");
  alignment = stack_args[stackp];
  stackp++;

  /* get the size from the stack */
  {
    int i;
    int nr_cells = device_nr_size_cells(device_parent(me));
    if (n_stack_args < stackp + nr_cells)
      device_error(me, "claim - incorrect number of arguments (size missing)");
    for (i = 0; i < nr_cells - 1; i++) {
      if (stack_args[stackp] != 0)
	device_error(me, "claim - multi-cell sizes not supported");
      stackp++;
    }
    size = stack_args[stackp];
    stackp++;
  }

  /* get the address from the stack */
  {
    int nr_cells = device_nr_address_cells(device_parent(me));
    if (alignment != 0) {
      if (n_stack_args != stackp) {
	if (n_stack_args == stackp + nr_cells)
	  DTRACE(memory, ("claim - extra address argument ignored\n"));
	else
	  device_error(me, "claim - incorrect number of arguments (optional addr)");
      }
      address = 0;
    }
    else {
      int i;
      if (n_stack_args != stackp + nr_cells)
	device_error(me, "claim - incorrect number of arguments (addr missing)");
      for (i = 0; i < nr_cells - 1; i++) {
	if (stack_args[stackp] != 0)
	  device_error(me, "claim - multi-cell addresses not supported");
	stackp++;
      }
      address = stack_args[stackp];
    }
  }

  /* check that there is space for the result */
  if (n_stack_returns != 0
      && n_stack_returns != device_nr_address_cells(device_parent(me)))
    device_error(me, "claim - invalid number of return arguments");

  /* find a chunk candidate, either according to address or alignment */
  if (alignment == 0) {
    chunk = hw_memory->heap;
    while (chunk != NULL) {
      if ((address + size) <= (chunk->address + chunk->size))
	break;
      chunk = chunk->next;
    }
    if (chunk == NULL || address < chunk->address || !chunk->available)
      device_error(me, "failed to allocate %ld bytes at 0x%lx",
		   (unsigned long)size, (unsigned long)address);
    DTRACE(memory, ("claim - address=0x%lx size=0x%lx\n",
		    (unsigned long)address,
		    (unsigned long)size));
  }
  else {
    /* adjust the alignment so that it is a power of two */
    unsigned_word align_mask = 1;
    while (align_mask < alignment && align_mask != 0)
      align_mask <<= 1;
    if (align_mask == 0)
      device_error(me, "alignment 0x%lx is to large", (unsigned long)alignment);
    align_mask -= 1;
    /* now find an aligned chunk that fits */
    chunk = hw_memory->heap;
    while (chunk != NULL) {
      address = ((chunk->address + align_mask) & ~align_mask);
      if ((chunk->available)
	  && (chunk->address + chunk->size >= address + size))
	break;
      chunk = chunk->next;
    }
    if (chunk == NULL)
      device_error(me, "failed to allocate %ld bytes with alignment %ld",
		   (unsigned long)size, (unsigned long)alignment);
    DTRACE(memory, ("claim - size=0x%lx alignment=%ld (0x%lx), address=0x%lx\n",
		    (unsigned long)size,
		    (unsigned long)alignment,
		    (unsigned long)alignment,
		    (unsigned long)address));
  }

  /* break off a bit before this chunk if needed */
  ASSERT(address >= chunk->address);
  if (address > chunk->address) {
    hw_memory_chunk *next_chunk = ZALLOC(hw_memory_chunk);
    /* insert a new chunk */
    next_chunk->next = chunk->next;
    chunk->next = next_chunk;
    /* adjust the address/size */
    next_chunk->address = address;
    next_chunk->size = chunk->address + chunk->size - next_chunk->address;
    next_chunk->available = 1;
    chunk->size = next_chunk->address - chunk->address;
    /* make this new chunk the one to allocate */
    chunk = next_chunk;
  }
  ASSERT(address == chunk->address);

  /* break off a bit after this chunk if needed */
  ASSERT(address + size <= chunk->address + chunk->size);
  if (address + size < chunk->address + chunk->size) {
    hw_memory_chunk *next_chunk = ZALLOC(hw_memory_chunk);
    /* insert it in to the list */
    next_chunk->next = chunk->next;
    chunk->next = next_chunk;
    /* adjust the address/size */
    next_chunk->address = address + size;
    next_chunk->size = chunk->address + chunk->size - next_chunk->address;
    next_chunk->available = 1;
    chunk->size = next_chunk->address - chunk->address;
  }
  ASSERT(address + size == chunk->address + chunk->size);

  /* now allocate/return it */
  chunk->available = 0;
  hw_memory_set_available(device_instance_device(instance), hw_memory);
  if (n_stack_returns > 0) {
    int i;
    for (i = 0; i < n_stack_returns - 1; i++)
      stack_returns[i] = 0;
    stack_returns[n_stack_returns - 1] = address;
  }

  return 0;
}


static int
hw_memory_instance_release(device_instance *instance,
			   int n_stack_args,
			   unsigned_cell stack_args[/*n_stack_args*/],
			   int n_stack_returns,
			   unsigned_cell stack_returns[/*n_stack_returns*/])
{
  hw_memory_device *hw_memory = device_instance_data(instance);
  device *me = device_instance_device(instance);
  unsigned_word length;
  unsigned_word address;
  int stackp = 0;
  hw_memory_chunk *chunk;
  
  /* get the length from the stack */
  {
    int i;
    int nr_cells = device_nr_size_cells(device_parent(me));
    if (n_stack_args < stackp + nr_cells)
      device_error(me, "release - incorrect number of arguments (length missing)");
    for (i = 0; i < nr_cells - 1; i++) {
      if (stack_args[stackp] != 0)
	device_error(me, "release - multi-cell length not supported");
      stackp++;
    }
    length = stack_args[stackp];
    stackp++;
  }

  /* get the address from the stack */
  {
    int i;
    int nr_cells = device_nr_address_cells(device_parent(me));
    if (n_stack_args != stackp + nr_cells)
      device_error(me, "release - incorrect number of arguments (addr missing)");
    for (i = 0; i < nr_cells - 1; i++) {
      if (stack_args[stackp] != 0)
	device_error(me, "release - multi-cell addresses not supported");
      stackp++;
    }
    address = stack_args[stackp];
  }

  /* returns ok */
  if (n_stack_returns != 0)
    device_error(me, "release - nonzero number of results");

  /* try to free the corresponding memory chunk */
  chunk = hw_memory->heap;
  while (chunk != NULL) {
    if (chunk->address == address
	&& chunk->size == length) {
      /* an exact match */
      if (chunk->available)
	device_error(me, "memory chunk 0x%lx (size 0x%lx) already available",
		     (unsigned long)address,
		     (unsigned long)length);
      else {
	/* free this chunk */
	DTRACE(memory, ("release - address=0x%lx, length=0x%lx\n",
			(unsigned long) address,
			(unsigned long) length));
	chunk->available = 1;
	break;
      }
    }
    else if (chunk->address >= address
	     && chunk->address + chunk->size <= address + length) {
      /* a sub region */
      if (!chunk->available) {
	DTRACE(memory, ("release - address=0x%lx, size=0x%lx within region 0x%lx length 0x%lx\n",
			(unsigned long) chunk->address,
			(unsigned long) chunk->size,
			(unsigned long) address,
			(unsigned long) length));
	chunk->available = 1;
      }
    }
    chunk = chunk->next;
  }
  if (chunk == NULL) {
    printf_filtered("warning: released chunks within region 0x%lx..0x%lx\n",
		    (unsigned long)address,
		    (unsigned long)(address + length - 1));
  }

  /* check for the chance to merge two adjacent available memory chunks */
  chunk = hw_memory->heap;
  while (chunk != NULL) {
    if (chunk->available
	&& chunk->next != NULL && chunk->next->available) {
      /* adjacent */
      hw_memory_chunk *delete = chunk->next;
      ASSERT(chunk->address + chunk->size == delete->address);
      chunk->size += delete->size;
      chunk->next = delete->next;
      free(delete);
    }
    else {
      chunk = chunk->next;
    }
  }

  /* update the corresponding property */
  hw_memory_set_available(device_instance_device(instance), hw_memory);

  return 0;
}


static device_instance_methods hw_memory_instance_methods[] = {
  { "claim", hw_memory_instance_claim },
  { "release", hw_memory_instance_release },
  { NULL, },
};

static device_instance_callbacks const hw_memory_instance_callbacks = {
  hw_memory_instance_delete,
  NULL /*read*/, NULL /*write*/, NULL /*seek*/,
  hw_memory_instance_methods
};

static device_instance *
hw_memory_create_instance(device *me,
			  const char *path,
			  const char *args)
{
  return device_create_instance_from(me, NULL,
				     device_data(me), /* nothing better */
				     path, args,
				     &hw_memory_instance_callbacks);
}

static device_callbacks const hw_memory_callbacks = {
  { hw_memory_init_address, },
  { NULL, }, /* address */
  { NULL, }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
  hw_memory_create_instance,
};

const device_descriptor hw_memory_device_descriptor[] = {
  { "memory", hw_memory_create, &hw_memory_callbacks },
  { NULL },
};

#endif /* _HW_MEMORY_C_ */
