/*  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_EEPROM_C_
#define _HW_EEPROM_C_

#include "device_table.h"

#include <string.h>


/* DEVICE


   eeprom - JEDEC? compatible electricaly erasable programable device


   DESCRIPTION


   This device implements a small byte addressable EEPROM.
   Programming is performed using the same write sequences as used by
   standard modern EEPROM components.  Writes occure in real time, the
   device returning a progress value until the programing has been
   completed.

   It is based on the AMD 29F040 component.


   PROPERTIES


   reg = <address> <size> (required)

   Determine where the device lives in the parents address space.


   nr-sectors = <integer> (required)

   When erasing an entire sector is cleared at a time.  This specifies
   the number of sectors in the EEPROM component.


   sector-size = <integer> (required)

   The number of bytes in a sector.  When erasing, memory chunks of
   this size are cleared.

   NOTE: The product nr-sectors * sector-size does not need to map the
   size specified in the reg property.  If the specified size is
   smaller part of the eeprom will not be accessible while if it is
   larger the addresses will wrap.


   byte-write-delay = <integer> (required)

   Number of clock ticks before the programming of a single byte
   completes.


   sector-start-delay = <integer> (required)

   When erasing sectors, the number of clock ticks after the sector
   has been specified that the actual erase process commences.


   erase-delay = <intger> (required)

   Number of clock ticks before an erase program completes


   manufacture-code = <integer> (required)

   The one byte value returned when the auto-select manufacturer code
   is read.


   device-code = <integer> (required)

   The one byte value returned when the auto-select device code is
   read.


   input-file = <file-name> (optional)

   Initialize the eeprom using the specified binary file.


   output-file = <file-name> (optional)

   When ever the eeprom is updated, save the modified image into the
   specified file.


   EXAMPLES


   Enable tracing of the eeprom:

   |  bash$ psim -t eeprom-device \


   Configure something very like the Amd Am29F040 - 512byte EEPROM
   (but a bit faster):

   |  -o '/eeprom@0xfff00000/reg 0xfff00000 0x80000' \
   |  -o '/eeprom@0xfff00000/nr-sectors 8' \
   |  -o '/eeprom@0xfff00000/sector-size 0x10000' \
   |  -o '/eeprom@0xfff00000/byte-write-delay 1000' \
   |  -o '/eeprom@0xfff00000/sector-start-delay 100' \
   |  -o '/eeprom@0xfff00000/erase-delay 1000' \
   |  -o '/eeprom@0xfff00000/manufacture-code 0x01' \
   |  -o '/eeprom@0xfff00000/device-code 0xa4' \


   Initialize the eeprom from the file <</dev/zero>>:

   |  -o '/eeprom@0xfff00000/input-file /dev/zero'


   BUGS


   */

typedef enum {
  read_reset,
  write_nr_2,
  write_nr_3,
  write_nr_4,
  write_nr_5,
  write_nr_6,
  byte_program,
  byte_programming,
  chip_erase,
  sector_erase,
  sector_erase_suspend,
  autoselect,
} hw_eeprom_states;

static const char *
state2a(hw_eeprom_states state)
{
  switch (state) {
  case read_reset: return "read_reset";
  case write_nr_2: return "write_nr_2";
  case write_nr_3: return "write_nr_3";
  case write_nr_4: return "write_nr_4";
  case write_nr_5: return "write_nr_5";
  case write_nr_6: return "write_nr_6";
  case byte_program: return "byte_program";
  case byte_programming: return "byte_programming";
  case chip_erase: return "chip_erase";
  case sector_erase: return "sector_erase";
  case sector_erase_suspend: return "sector_erase_suspend";
  case autoselect: return "autoselect";
  }
  return NULL;
}

typedef struct _hw_eeprom_device {
  /* general */
  hw_eeprom_states state;
  unsigned8 *memory;
  unsigned sizeof_memory;
  unsigned erase_delay;
  signed64 program_start_time;
  signed64 program_finish_time;
  unsigned8 manufacture_code;
  unsigned8 device_code;
  unsigned8 toggle_bit;
  /* initialization */
  const char *input_file_name;
  const char *output_file_name;
  /* for sector and sector programming */
  hw_eeprom_states sector_state;
  unsigned8 *sectors;
  unsigned nr_sectors;
  unsigned sizeof_sector;
  unsigned sector_start_delay;
  unsigned sector_start_time;
  /* byte and byte programming */
  unsigned byte_write_delay;
  unsigned_word byte_program_address;
  unsigned8 byte_program_byte;
} hw_eeprom_device;

typedef struct _hw_eeprom_reg_spec {
  unsigned32 base;
  unsigned32 size;
} hw_eeprom_reg_spec;

static void
hw_eeprom_init_data(device *me)
{
  hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);

  /* have we any input or output files */
  if (device_find_property(me, "input-file") != NULL)
    eeprom->input_file_name = device_find_string_property(me, "input-file");
  if (device_find_property(me, "output-file") != NULL)
    eeprom->input_file_name = device_find_string_property(me, "output-file");

  /* figure out the sectors in the eeprom */
  if (eeprom->sectors == NULL) {
    eeprom->nr_sectors = device_find_integer_property(me, "nr-sectors");
    eeprom->sizeof_sector = device_find_integer_property(me, "sector-size");
    eeprom->sectors = zalloc(eeprom->nr_sectors);
  }
  else
    memset(eeprom->sectors, 0, eeprom->nr_sectors);

  /* initialize the eeprom */
  if (eeprom->memory == NULL) {
    eeprom->sizeof_memory = eeprom->sizeof_sector * eeprom->nr_sectors;
    eeprom->memory = zalloc(eeprom->sizeof_memory);
  }
  else
    memset(eeprom->memory, 0, eeprom->sizeof_memory);
  if (eeprom->input_file_name != NULL) {
    int i;
    FILE *input_file = fopen(eeprom->input_file_name, "r");
    if (input_file == NULL) {
      perror("eeprom");
      device_error(me, "Failed to open input file %s\n", eeprom->input_file_name);
    }
    for (i = 0; i < eeprom->sizeof_memory; i++) {
      if (fread(&eeprom->memory[i], 1, 1, input_file) != 1)
	break;
    }
    fclose(input_file);
  }

  /* timing */
  eeprom->byte_write_delay = device_find_integer_property(me, "byte-write-delay");
  eeprom->sector_start_delay = device_find_integer_property(me, "sector-start-delay");
  eeprom->erase_delay = device_find_integer_property(me, "erase-delay");

  /* misc */
  eeprom->manufacture_code = device_find_integer_property(me, "manufacture-code");
  eeprom->device_code = device_find_integer_property(me, "device-code");
}


static void
invalid_read(device *me,
	     hw_eeprom_states state,
	     unsigned_word address,
	     const char *reason)
{
  DTRACE(eeprom, ("Invalid read to 0x%lx while in state %s (%s)\n",
		  (unsigned long)address,
		  state2a(state),
		  reason));
}

static void
invalid_write(device *me,
	      hw_eeprom_states state,
	      unsigned_word address,
	      unsigned8 data,
	      const char *reason)
{
  DTRACE(eeprom, ("Invalid write of 0x%lx to 0x%lx while in state %s (%s)\n",
		  (unsigned long)data,
		  (unsigned long)address,
		  state2a(state),
		  reason));
}

static void
dump_eeprom(device *me,
	    hw_eeprom_device *eeprom)
{
  if (eeprom->output_file_name != NULL) {
    int i;
    FILE *output_file = fopen(eeprom->output_file_name, "w");
    if (output_file == NULL) {
      perror("eeprom");
      device_error(me, "Failed to open output file %s\n",
		   eeprom->output_file_name);
    }
    for (i = 0; i < eeprom->sizeof_memory; i++) {
      if (fwrite(&eeprom->memory[i], 1, 1, output_file) != 1)
	break;
    }
    fclose(output_file);
  }
}


/* program a single byte of eeprom */

static void
start_programming_byte(device *me,
		       hw_eeprom_device *eeprom,
		       unsigned_word address,
		       unsigned8 new_byte)
{
  unsigned8 old_byte = eeprom->memory[address];
  DTRACE(eeprom, ("start-programing-byte - address 0x%lx, new 0x%lx, old 0x%lx\n",
		  (unsigned long)address,
		  (unsigned long)new_byte,
		  (unsigned long)old_byte));
  eeprom->byte_program_address = address;
  /* : old new : ~old : new&~old
     :  0   0  :   1  :    0
     :  0   1  :   1  :    1     -- can not set a bit
     :  1   0  :   0  :    0
     :  1   1  :   0  :    0 */
  if (~old_byte & new_byte)
    invalid_write(me, eeprom->state, address, new_byte, "setting cleared bit");
  /* : old new : old&new
     :  0   0  :    0
     :  0   1  :    0
     :  1   0  :    0
     :  1   1  :    1 */
  eeprom->byte_program_byte = new_byte & old_byte;
  eeprom->memory[address] = ~new_byte & ~0x24; /* LE-bits 5:3 zero */
  eeprom->program_start_time = device_event_queue_time(me);
  eeprom->program_finish_time = (eeprom->program_start_time
				 + eeprom->byte_write_delay);
}

static void
finish_programming_byte(device *me,
			hw_eeprom_device *eeprom)
{
  DTRACE(eeprom, ("finish-programming-byte - address 0x%lx, byte 0x%lx\n",
		  (unsigned long)eeprom->byte_program_address,
		  (unsigned long)eeprom->byte_program_byte));
  eeprom->memory[eeprom->byte_program_address] = eeprom->byte_program_byte;
  dump_eeprom(me, eeprom);
}


/* erase the eeprom completly */

static void
start_erasing_chip(device *me,
		   hw_eeprom_device *eeprom)
{
  DTRACE(eeprom, ("start-erasing-chip\n"));
  memset(eeprom->memory, 0, eeprom->sizeof_memory);
  eeprom->program_start_time = device_event_queue_time(me);
  eeprom->program_finish_time = (eeprom->program_start_time
				 + eeprom->erase_delay);
}

static void
finish_erasing_chip(device *me,
		    hw_eeprom_device *eeprom)
{
  DTRACE(eeprom, ("finish-erasing-chip\n"));
  memset(eeprom->memory, 0xff, eeprom->sizeof_memory);
  dump_eeprom(me, eeprom);
}


/* erase a single sector of the eeprom */

static void
start_erasing_sector(device *me,
		     hw_eeprom_device *eeprom,
		     unsigned_word address)
{
  int sector = address / eeprom->sizeof_sector;
  DTRACE(eeprom, ("start-erasing-sector - address 0x%lx, sector %d\n",
		  (unsigned long)address, sector));
  ASSERT(sector < eeprom->nr_sectors);
  eeprom->sectors[sector] = 1;
  memset(eeprom->memory + sector * eeprom->sizeof_sector,
	 0x4, eeprom->sizeof_sector);
  eeprom->program_start_time = device_event_queue_time(me);
  eeprom->sector_start_time = (eeprom->program_start_time
			       + eeprom->sector_start_delay);
  eeprom->program_finish_time = (eeprom->sector_start_time
				 + eeprom->erase_delay);

}

static void
finish_erasing_sector(device *me,
		      hw_eeprom_device *eeprom)
{
  int sector;
  DTRACE(eeprom, ("finish-erasing-sector\n"));
  for (sector = 0; sector < eeprom->nr_sectors; sector++) {
    if (eeprom->sectors[sector]) {
      eeprom->sectors[sector] = 0;
      memset(eeprom->memory + sector * eeprom->sizeof_sector,
	     0xff, eeprom->sizeof_sector);
    }
  }
  dump_eeprom(me, eeprom);
}


/* eeprom reads */

static unsigned8
toggle(hw_eeprom_device *eeprom,
       unsigned8 byte)
{
  eeprom->toggle_bit = eeprom->toggle_bit ^ 0x40; /* le-bit 6 */
  return eeprom->toggle_bit ^ byte;
}

static unsigned8
read_byte(device *me,
	  hw_eeprom_device *eeprom,
	  unsigned_word address)
{
  /* may need multiple iterations of this */
  while (1) {
    switch (eeprom->state) {

    case read_reset:
      return eeprom->memory[address];

    case autoselect:
      if ((address & 0xff) == 0x00)
	return eeprom->manufacture_code;
      else if ((address & 0xff) == 0x01)
	return eeprom->device_code;
      else
	return 0; /* not certain about this */

    case byte_programming:
      if (device_event_queue_time(me) > eeprom->program_finish_time) {
	finish_programming_byte(me, eeprom);
	eeprom->state = read_reset;
	continue;
      }
      else if (address == eeprom->byte_program_address) {
	return toggle(eeprom, eeprom->memory[address]);
      }
      else {
	/* trash that memory location */
	invalid_read(me, eeprom->state, address, "not byte program address");
	eeprom->memory[address] = (eeprom->memory[address]
				   & eeprom->byte_program_byte);
	return toggle(eeprom, eeprom->memory[eeprom->byte_program_address]);
      }

    case chip_erase:
      if (device_event_queue_time(me) > eeprom->program_finish_time) {
	finish_erasing_chip(me, eeprom);
	eeprom->state = read_reset;
	continue;
      }
      else {
	return toggle(eeprom, eeprom->memory[address]);
      }

    case sector_erase:
      if (device_event_queue_time(me) > eeprom->program_finish_time) {
	finish_erasing_sector(me, eeprom);
	eeprom->state = read_reset;
	continue;
      }
      else if (!eeprom->sectors[address / eeprom->sizeof_sector]) {
	/* read to wrong sector */
	invalid_read(me, eeprom->state, address, "sector not being erased");
	return toggle(eeprom, eeprom->memory[address]) & ~0x8;
      }
      else if (device_event_queue_time(me) > eeprom->sector_start_time) {
	return toggle(eeprom, eeprom->memory[address]) | 0x8;
      }
      else {
	return toggle(eeprom, eeprom->memory[address]) & ~0x8;
      }

    case sector_erase_suspend:
      if (!eeprom->sectors[address / eeprom->sizeof_sector]) {
	return eeprom->memory[address];
      }
      else {
	invalid_read(me, eeprom->state, address, "sector being erased");
	return eeprom->memory[address];
      }

    default:
      invalid_read(me, eeprom->state, address, "invalid state");
      return eeprom->memory[address];

    }
  }
  return 0;
}
		       
static unsigned
hw_eeprom_io_read_buffer(device *me,
			 void *dest,
			 int space,
			 unsigned_word addr,
			 unsigned nr_bytes,
			 cpu *processor,
			 unsigned_word cia)
{
  hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
  int i;
  for (i = 0; i < nr_bytes; i++) {
    unsigned_word address = (addr + i) % eeprom->sizeof_memory;
    unsigned8 byte = read_byte(me, eeprom, address);
    ((unsigned8*)dest)[i] = byte;
  }
  return nr_bytes;
}


/* eeprom writes */

static void
write_byte(device *me,
	   hw_eeprom_device *eeprom,
	   unsigned_word address,
	   unsigned8 data)
{
  /* may need multiple transitions to process a write */
  while (1) {
    switch (eeprom->state) {

    case read_reset:
      if (address == 0x5555 && data == 0xaa)
	eeprom->state = write_nr_2;
      else if (data == 0xf0)
	eeprom->state = read_reset;
      else {
	invalid_write(me, eeprom->state, address, data, "unexpected");
	eeprom->state = read_reset;
      }
      return;

    case write_nr_2:
      if (address == 0x2aaa && data == 0x55)
	eeprom->state = write_nr_3;
      else {
	invalid_write(me, eeprom->state, address, data, "unexpected");
	eeprom->state = read_reset;
      }
      return;

    case write_nr_3:
      if (address == 0x5555 && data == 0xf0)
	eeprom->state = read_reset;
      else if (address == 0x5555 && data == 0x90)
	eeprom->state = autoselect;
      else if (address == 0x5555 && data == 0xa0) {
	eeprom->state = byte_program;
      }
      else if (address == 0x5555 && data == 0x80)
	eeprom->state = write_nr_4;
      else {
	invalid_write(me, eeprom->state, address, data, "unexpected");
	eeprom->state = read_reset;
      }
      return;

    case write_nr_4:
      if (address == 0x5555 && data == 0xaa)
	eeprom->state = write_nr_5;
      else {
	invalid_write(me, eeprom->state, address, data, "unexpected");
	eeprom->state = read_reset;
      }
      return;

    case write_nr_5:
      if (address == 0x2aaa && data == 0x55)
	eeprom->state = write_nr_6;
      else {
	invalid_write(me, eeprom->state, address, data, "unexpected");
	eeprom->state = read_reset;
      }
      return;

    case write_nr_6:
      if (address == 0x5555 && data == 0x10) {
	start_erasing_chip(me, eeprom);
	eeprom->state = chip_erase;
      }
      else {
	start_erasing_sector(me, eeprom, address);
	eeprom->sector_state = read_reset;
	eeprom->state = sector_erase;
      }
      return;

    case autoselect:
      if (data == 0xf0)
	eeprom->state = read_reset;
      else if (address == 0x5555 && data == 0xaa)
	eeprom->state = write_nr_2;
      else {
	invalid_write(me, eeprom->state, address, data, "unsupported address");
	eeprom->state = read_reset;
      }
      return;

    case byte_program:
      start_programming_byte(me, eeprom, address, data);
      eeprom->state = byte_programming;
      return;

    case byte_programming:
      if (device_event_queue_time(me) > eeprom->program_finish_time) {
	finish_programming_byte(me, eeprom);
	eeprom->state = read_reset;
	continue;
      }
      /* ignore it */
      return;

    case chip_erase:
      if (device_event_queue_time(me) > eeprom->program_finish_time) {
	finish_erasing_chip(me, eeprom);
	eeprom->state = read_reset;
	continue;
      }
      /* ignore it */
      return;

    case sector_erase:
      if (device_event_queue_time(me) > eeprom->program_finish_time) {
	finish_erasing_sector(me, eeprom);
	eeprom->state = eeprom->sector_state;
	continue;
      }
      else if (device_event_queue_time(me) > eeprom->sector_start_time
	       && data == 0xb0) {
	eeprom->sector_state = read_reset;
	eeprom->state = sector_erase_suspend;
      }
      else {
	if (eeprom->sector_state == read_reset
	    && address == 0x5555 && data == 0xaa)
	  eeprom->sector_state = write_nr_2;
	else if (eeprom->sector_state == write_nr_2
		 && address == 0x2aaa && data == 0x55)
	  eeprom->sector_state = write_nr_3;
	else if (eeprom->sector_state == write_nr_3
		 && address == 0x5555 && data == 0x80)
	  eeprom->sector_state = write_nr_4;
	else if (eeprom->sector_state == write_nr_4
		 && address == 0x5555 && data == 0xaa)
	  eeprom->sector_state = write_nr_5;
	else if (eeprom->sector_state == write_nr_5
		 && address == 0x2aaa && data == 0x55)
	  eeprom->sector_state = write_nr_6;
	else if (eeprom->sector_state == write_nr_6
		 && address != 0x5555 && data == 0x30) {
	  if (device_event_queue_time(me) > eeprom->sector_start_time) {
	    DTRACE(eeprom, ("sector erase command after window closed\n"));
	    eeprom->sector_state = read_reset;
	  }
	  else {
	    start_erasing_sector(me, eeprom, address);
	    eeprom->sector_state = read_reset;
	  }
	}
	else {
	  invalid_write(me, eeprom->state, address, data, state2a(eeprom->sector_state));
	  eeprom->state = read_reset;
	}
      }
      return;

    case sector_erase_suspend:
      if (data == 0x30)
	eeprom->state = sector_erase;
      else {
	invalid_write(me, eeprom->state, address, data, "not resume command");
	eeprom->state = read_reset;
      }
      return;

    }
  }
}

static unsigned
hw_eeprom_io_write_buffer(device *me,
			  const void *source,
			  int space,
			  unsigned_word addr,
			  unsigned nr_bytes,
			  cpu *processor,
			  unsigned_word cia)
{
  hw_eeprom_device *eeprom = (hw_eeprom_device*)device_data(me);
  int i;
  for (i = 0; i < nr_bytes; i++) {
    unsigned_word address = (addr + i) % eeprom->sizeof_memory;
    unsigned8 byte = ((unsigned8*)source)[i];
    write_byte(me, eeprom, address, byte);
  }
  return nr_bytes;
}


/* An instance of the eeprom */

typedef struct _hw_eeprom_instance {
  unsigned_word pos;
  hw_eeprom_device *eeprom;
  device *me;
} hw_eeprom_instance;

static void
hw_eeprom_instance_delete(device_instance *instance)
{
  hw_eeprom_instance *data = device_instance_data(instance);
  free(data);
}

static int
hw_eeprom_instance_read(device_instance *instance,
			void *buf,
			unsigned_word len)
{
  hw_eeprom_instance *data = device_instance_data(instance);
  int i;
  if (data->eeprom->state != read_reset)
    DITRACE(eeprom, ("eeprom not idle during instance read\n"));
  for (i = 0; i < len; i++) {
    ((unsigned8*)buf)[i] = data->eeprom->memory[data->pos];
    data->pos = (data->pos + 1) % data->eeprom->sizeof_memory;
  }
  return len;
}

static int
hw_eeprom_instance_write(device_instance *instance,
			 const void *buf,
			 unsigned_word len)
{
  hw_eeprom_instance *data = device_instance_data(instance);
  int i;
  if (data->eeprom->state != read_reset)
    DITRACE(eeprom, ("eeprom not idle during instance write\n"));
  for (i = 0; i < len; i++) {
    data->eeprom->memory[data->pos] = ((unsigned8*)buf)[i];
    data->pos = (data->pos + 1) % data->eeprom->sizeof_memory;
  }
  dump_eeprom(data->me, data->eeprom);
  return len;
}

static int
hw_eeprom_instance_seek(device_instance *instance,
		      unsigned_word pos_hi,
		      unsigned_word pos_lo)
{
  hw_eeprom_instance *data = device_instance_data(instance);
  if (pos_lo >= data->eeprom->sizeof_memory)
    device_error(data->me, "seek value 0x%lx out of range\n",
		 (unsigned long)pos_lo);
  data->pos = pos_lo;
  return 0;
}

static const device_instance_callbacks hw_eeprom_instance_callbacks = {
  hw_eeprom_instance_delete,
  hw_eeprom_instance_read,
  hw_eeprom_instance_write,
  hw_eeprom_instance_seek,
};

static device_instance *
hw_eeprom_create_instance(device *me,
			  const char *path,
			  const char *args)
{
  hw_eeprom_device *eeprom = device_data(me);
  hw_eeprom_instance *data = ZALLOC(hw_eeprom_instance);
  data->eeprom = eeprom;
  data->me = me;
  return device_create_instance_from(me, NULL,
				     data,
				     path, args,
				     &hw_eeprom_instance_callbacks);
}



static device_callbacks const hw_eeprom_callbacks = {
  { generic_device_init_address,
    hw_eeprom_init_data },
  { NULL, }, /* address */
  { hw_eeprom_io_read_buffer,
    hw_eeprom_io_write_buffer }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
  hw_eeprom_create_instance,
};

static void *
hw_eeprom_create(const char *name,
		 const device_unit *unit_address,
		 const char *args)
{
  hw_eeprom_device *eeprom = ZALLOC(hw_eeprom_device);
  return eeprom;
}



const device_descriptor hw_eeprom_device_descriptor[] = {
  { "eeprom", hw_eeprom_create, &hw_eeprom_callbacks },
  { NULL },
};

#endif /* _HW_EEPROM_C_ */
