diff options
Diffstat (limited to 'sim/ppc/hw_nvram.c')
-rw-r--r-- | sim/ppc/hw_nvram.c | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/sim/ppc/hw_nvram.c b/sim/ppc/hw_nvram.c deleted file mode 100644 index fbd8e11..0000000 --- a/sim/ppc/hw_nvram.c +++ /dev/null @@ -1,234 +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_NVRAM_C_ -#define _HW_NVRAM_C_ - -#ifndef STATIC_INLINE_HW_NVRAM -#define STATIC_INLINE_HW_NVRAM STATIC_INLINE -#endif - -#include "device_table.h" - -#ifdef HAVE_TIME_H -#include <time.h> -#endif - -#ifdef HAVE_STRING_H -#include <string.h> -#else -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#endif - -/* NVRAM - non-volatile memory with optional clock. - - Description: - - This device implements a small byte addressable non-volatile memory - component. The component may include an optional real-time clock - at its upper addresses. - - Properties: - - reg = <address> <size>. Determine where the device lives in the - parents address space. - - timezone = <integer>. Adjustment to current host's GMT (in secons) - that should be applied when updating the NVRAM's clock. */ - -typedef struct _hw_nvram_device { - unsigned8 *memory; - unsigned sizeof_memory; -#ifdef HAVE_TIME_H - time_t host_time; -#else - long host_time; -#endif - unsigned timezone; - /* useful */ - unsigned addr_year; - unsigned addr_month; - unsigned addr_date; - unsigned addr_day; - unsigned addr_hour; - unsigned addr_minutes; - unsigned addr_seconds; - unsigned addr_control; -} hw_nvram_device; - -static void * -hw_nvram_create(const char *name, - const device_unit *unit_address, - const char *args, - device *parent) -{ - hw_nvram_device *hw_nvram = ZALLOC(hw_nvram_device); - return hw_nvram; -} - -typedef struct _hw_nvram_reg_spec { - unsigned32 base; - unsigned32 size; -} hw_nvram_reg_spec; - -static void -hw_nvram_init_address(device *me) -{ - hw_nvram_device *hw_nvram = (hw_nvram_device*)device_data(me); - const device_property *reg = device_find_array_property(me, "reg"); - const hw_nvram_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 hw_nvram */ - if (hw_nvram->memory == NULL) { - hw_nvram->sizeof_memory = BE2H_4(spec->size); - hw_nvram->memory = zalloc(hw_nvram->sizeof_memory); - } - else - memset(hw_nvram->memory, hw_nvram->sizeof_memory, 0); - - hw_nvram->timezone = device_find_integer_property(me, "timezone"); - - hw_nvram->addr_year = hw_nvram->sizeof_memory - 1; - hw_nvram->addr_month = hw_nvram->sizeof_memory - 2; - hw_nvram->addr_date = hw_nvram->sizeof_memory - 3; - hw_nvram->addr_day = hw_nvram->sizeof_memory - 4; - hw_nvram->addr_hour = hw_nvram->sizeof_memory - 5; - hw_nvram->addr_minutes = hw_nvram->sizeof_memory - 6; - hw_nvram->addr_seconds = hw_nvram->sizeof_memory - 7; - hw_nvram->addr_control = hw_nvram->sizeof_memory - 8; - - device_attach_address(device_parent(me), - device_name(me), - attach_callback, - 0 /*address space*/, - BE2H_4(spec->base), - hw_nvram->sizeof_memory, - access_read_write_exec, - me); -} - -static int -hw_nvram_bcd(int val) -{ - return ((val / 10) << 4) + (val % 10); -} - -/* If reached an update interval and allowed, update the clock within - the hw_nvram. While this function could be implemented using events - it isn't on the assumption that the HW_NVRAM will hardly ever be - referenced and hence there is little need in keeping the clock - continually up-to-date */ -static void -hw_nvram_update_clock(hw_nvram_device *hw_nvram, cpu *processor) -{ -#ifdef HAVE_TIME_H - if (!(hw_nvram->memory[hw_nvram->addr_control] & 0xc0)) { - time_t host_time = time(NULL); - if (hw_nvram->host_time != host_time) { - time_t nvtime = hw_nvram->host_time + hw_nvram->timezone; - struct tm *clock = gmtime(&nvtime); - hw_nvram->host_time = host_time; - hw_nvram->memory[hw_nvram->addr_year] = hw_nvram_bcd(clock->tm_year); - hw_nvram->memory[hw_nvram->addr_month] = hw_nvram_bcd(clock->tm_mon + 1); - hw_nvram->memory[hw_nvram->addr_date] = hw_nvram_bcd(clock->tm_mday); - hw_nvram->memory[hw_nvram->addr_day] = hw_nvram_bcd(clock->tm_wday + 1); - hw_nvram->memory[hw_nvram->addr_hour] = hw_nvram_bcd(clock->tm_hour); - hw_nvram->memory[hw_nvram->addr_minutes] = hw_nvram_bcd(clock->tm_min); - hw_nvram->memory[hw_nvram->addr_seconds] = hw_nvram_bcd(clock->tm_sec); - } - } -#else - error("fixme - where do I find out GMT\n"); -#endif -} - -static void -hw_nvram_set_clock(hw_nvram_device *hw_nvram, cpu *processor) -{ - error ("fixme - how do I set the localtime\n"); -} - -static unsigned -hw_nvram_io_read_buffer(device *me, - void *dest, - int space, - unsigned_word addr, - unsigned nr_bytes, - cpu *processor, - unsigned_word cia) -{ - int i; - hw_nvram_device *hw_nvram = (hw_nvram_device*)device_data(me); - for (i = 0; i < nr_bytes; i++) { - unsigned address = (addr + i) % hw_nvram->sizeof_memory; - unsigned8 data = hw_nvram->memory[address]; - hw_nvram_update_clock(hw_nvram, processor); - ((unsigned8*)dest)[i] = data; - } - return nr_bytes; -} - -static unsigned -hw_nvram_io_write_buffer(device *me, - const void *source, - int space, - unsigned_word addr, - unsigned nr_bytes, - cpu *processor, - unsigned_word cia) -{ - int i; - hw_nvram_device *hw_nvram = (hw_nvram_device*)device_data(me); - for (i = 0; i < nr_bytes; i++) { - unsigned address = (addr + i) % hw_nvram->sizeof_memory; - unsigned8 data = ((unsigned8*)source)[i]; - if (address == hw_nvram->addr_control - && (data & 0x80) == 0 - && (hw_nvram->memory[address] & 0x80) == 0x80) - hw_nvram_set_clock(hw_nvram, processor); - else - hw_nvram_update_clock(hw_nvram, processor); - hw_nvram->memory[address] = data; - } - return nr_bytes; -} - -static device_callbacks const hw_nvram_callbacks = { - { hw_nvram_init_address, }, - { NULL, }, /* address */ - { hw_nvram_io_read_buffer, hw_nvram_io_write_buffer }, /* IO */ -}; - -const device_descriptor hw_nvram_device_descriptor[] = { - { "nvram", hw_nvram_create, &hw_nvram_callbacks }, - { NULL }, -}; - -#endif /* _HW_NVRAM_C_ */ |