diff options
Diffstat (limited to 'sim/ppc/hw_eeprom.c')
-rw-r--r-- | sim/ppc/hw_eeprom.c | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/sim/ppc/hw_eeprom.c b/sim/ppc/hw_eeprom.c deleted file mode 100644 index 8a52e9d..0000000 --- a/sim/ppc/hw_eeprom.c +++ /dev/null @@ -1,289 +0,0 @@ -/* 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 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. - - */ - - -#ifndef _HW_EEPROM_C_ -#define _HW_EEPROM_C_ - -#ifndef STATIC_INLINE_HW_EEPROM -#define STATIC_INLINE_HW_EEPROM STATIC_INLINE -#endif - -#include "device_table.h" - -#ifdef HAVE_STRING_H -#include <string.h> -#else -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#endif - -/* EEPROM - electricaly erasable programable memory - - Description: - - This device implements a small byte addressable EEPROM. - Programming is performed using the same write sequences as used by - modern EEPROM components. Writes occure in real time, the device - returning a progress value until the programing has been completed. - - Properties: - - reg = <address> <size>. Determine where the device lives in the - parents address space. - - nr-sectors = <integer>. When erasing an entire sector is cleared - at a time. This specifies the number of sectors in the EEPROM - component. - - byte-write-delay = <integer>. Number of clock ticks before the - programming of a single byte completes. - - sector-start-delay = <integer>. When erasing sectors, the number - of clock ticks after the sector has been specified and the actual - erase process commences. - - erase-delay = <intger>. Number of clock ticks before an erase - program completes. */ - -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, chip_erasing, - sector_erase, sector_erasing, - sector_erase_suspend, - sector_erase_resume, -} eeprom_states; - -typedef struct _eeprom_device { - unsigned8 *memory; - unsigned sizeof_memory; - unsigned sector_size; - unsigned nr_sectors; - unsigned byte_write_delay; - unsigned sector_start_delay; - unsigned erase_delay; - signed64 programme_start_time; - unsigned program_byte_address; - eeprom_states state; -} eeprom_device; - -static void * -eeprom_create(const char *name, - const device_unit *unit_address, - const char *args, - device *parent) -{ - eeprom_device *eeprom = ZALLOC(eeprom_device); - return eeprom; -} - -typedef struct _eeprom_reg_spec { - unsigned32 base; - unsigned32 size; -} eeprom_reg_spec; - -static void -eeprom_init_address(device *me, - psim *system) -{ - eeprom_device *eeprom = (eeprom_device*)device_data(me); - const device_property *reg = device_find_array_property(me, "reg"); - const eeprom_reg_spec *spec = reg->array; - int nr_entries = reg->sizeof_array / sizeof(*spec); - - if ((reg->sizeof_array % sizeof(*spec)) != 0) - error("devices/%s reg property of incorrect size\n", device_name(me)); - if (nr_entries > 1) - error("devices/%s reg property contains multiple specs\n", - device_name(me)); - - /* initialize the eeprom */ - if (eeprom->memory == NULL) { - eeprom->sizeof_memory = BE2H_4(spec->size); - eeprom->memory = zalloc(eeprom->sizeof_memory); - } - else - memset(eeprom->memory, eeprom->sizeof_memory, 0); - - /* figure out the sectors in the eeprom */ - eeprom->nr_sectors = device_find_integer_property(me, "nr-sectors"); - eeprom->sector_size = eeprom->sizeof_memory / eeprom->nr_sectors; - if (eeprom->sector_size * eeprom->nr_sectors != eeprom->sizeof_memory) - error("device/%s nr-sectors does not evenly divide eeprom\n", - device_name(me)); - - /* 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"); - - device_attach_address(device_parent(me), - device_name(me), - attach_callback, - 0 /*address space*/, - BE2H_4(spec->base), - eeprom->sizeof_memory, - access_read_write_exec, - me); -} - - -static unsigned -eeprom_io_read_buffer(device *me, - void *dest, - int space, - unsigned_word addr, - unsigned nr_bytes, - cpu *processor, - unsigned_word cia) -{ - eeprom_device *eeprom = (eeprom_device*)device_data(me); - int i; - for (i = 0; i < nr_bytes; i++) { - unsigned_word address = (addr + nr_bytes) % eeprom->sizeof_memory; - eeprom->memory[address] = eeprom_io_read_byte(address); - } - return nr_bytes; -} - -static void -eeprom_io_write_byte() -{ - switch (state) { - case read_reset: - if (address == 0x5555 && data = 0xaa) - state = first_write; - else - state = read_reset; - break; - case first_write: - if (address == 0x2aaa && data == 0x55) - state = second_write; - else - state = read_reset; /* issue warning */ - break; - case second_write: - if (address == 0x5555 && data == 0xf0) - state = read_reset; - else if (address == 0x5555 && data == 0x90) - state = auto_select; - else if (address == 0x5555 && data == 0xa0) - state = byte_program; - else if (address == 0x5555 && data == 0x80) - state = third_write; - else - state = read_reset; - break; - case fourth_write: - if (address == 0x5555 && data == 0xaa) - state = fith_write; - else - state = read_reset; - break; - case fith_write: - if (address == 0x2aaa && data == 0x55) - state = sixth_write; - else - state = read_reset; - break; - case sixth_write: - if (address == 0x5555 && data == 0x10) - state = chip_erase; - else - sector_erase(); - break; - case auto_select: - if (data == 0xf0) - state = read_reset; - else if (address == 0x5555 && data == 0xaa) - state = second_write; - else - state = read_reset; /* issue warning */ - break; - case sector_erase: - if (data == 0xb0) - state = sector_erase_suspend; - else - state = sector_erase; /* ignore */ - break; - case sector_erase_suspend: - if (data == 0x30) - state = sector_erase; - else - state = sector_erase_suspend; /* ignore */ - break; - case byte_program: - /* perform the byte program */ - program_address = address; - program_start = some_time(); - toggle = 0; - /* but only make things `0' and never 1 */ - byte[address] = data; - state = byte_programming; - break; - case byte_programming: - if (finished) - state = read_reset; - else - state = byte_programming; - break; - } -} - -static unsigned -eeprom_io_write_buffer(device *me, - const void *source, - int space, - unsigned_word addr, - unsigned nr_bytes, - cpu *processor, - unsigned_word cia) -{ - eeprom_device *eeprom = (eeprom_device*)device_data(me); - int i; - for (i = 0; i < nr_bytes; i++) { - unsigned_word address = (addr + nr_bytes) % eeprom->sizeof_memory; - eeprom_io_read_byte(address, eeprom->memory[address]); - } - return nr_bytes; -} - - - -static device_callbacks const eeprom_callbacks = { - { eeprom_init_address, }, - { NULL, }, /* address */ - { eeprom_io_read_buffer, eeprom_io_write_buffer }, /* IO */ -}; - -const device_descriptor eeprom_device_descriptor[] = { - { "eeprom", eeprom_create, &eeprom_callbacks }, - { NULL }, -}; - -#endif /* _HW_EEPROM_C_ */ |