/*  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;
  uint8_t *memory;
  unsigned sizeof_memory;
  unsigned erase_delay;
  int64_t program_start_time;
  int64_t program_finish_time;
  uint8_t manufacture_code;
  uint8_t device_code;
  uint8_t toggle_bit;
  /* initialization */
  const char *input_file_name;
  const char *output_file_name;
  /* for sector and sector programming */
  hw_eeprom_states sector_state;
  uint8_t *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;
  uint8_t byte_program_byte;
} hw_eeprom_device;

typedef struct _hw_eeprom_reg_spec {
  uint32_t base;
  uint32_t 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,
	      uint8_t 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,
		       uint8_t new_byte)
{
  uint8_t 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 uint8_t
toggle(hw_eeprom_device *eeprom,
       uint8_t byte)
{
  eeprom->toggle_bit = eeprom->toggle_bit ^ 0x40; /* le-bit 6 */
  return eeprom->toggle_bit ^ byte;
}

static uint8_t
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;
    uint8_t byte = read_byte(me, eeprom, address);
    ((uint8_t*)dest)[i] = byte;
  }
  return nr_bytes;
}


/* eeprom writes */

static void
write_byte(device *me,
	   hw_eeprom_device *eeprom,
	   unsigned_word address,
	   uint8_t 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;
    uint8_t byte = ((uint8_t*)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++) {
    ((uint8_t*)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] = ((uint8_t*)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_ */
