Replace accidentally broken configure from previous regenerate.
[deliverable/binutils-gdb.git] / sim / ppc / hw_nvram.c
index fbd8e11517d7e8c27a5b52a5cf625de516339b26..32308f754a06ddaef8be18c7d71367d7f91d071d 100644 (file)
 #endif
 #endif
 
-/* NVRAM - non-volatile memory with optional clock.
+/* DEVICE
 
-   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.
+   nvram - non-volatile memory with clock
 
-   Properties:
 
-   reg = <address> <size>.  Determine where the device lives in the
-   parents address space.
+   DESCRIPTION
 
-   timezone = <integer>.  Adjustment to current host's GMT (in secons)
-   that should be applied when updating the NVRAM's clock. */
+
+   This device implements a small byte addressable non-volatile
+   memory.  The top 8 bytes of this memory include a real-time clock.
+
+
+   PROPERTIES
+
+
+   reg = <address> <size> (required)
+
+   Specify the address/size of this device within its parents address
+   space.
+
+
+   timezone = <integer> (optional)
+
+   Adjustment to the hosts current GMT (in seconds) that should be
+   applied when updating the NVRAM's clock.  If no timezone is
+   specified, zero (GMT or UCT) is assumed.
+
+
+   */
 
 typedef struct _hw_nvram_device {
   unsigned8 *memory;
@@ -79,11 +94,10 @@ typedef struct _hw_nvram_device {
 static void *
 hw_nvram_create(const char *name,
                const device_unit *unit_address,
-               const char *args,
-               device *parent)
+               const char *args)
 {
-  hw_nvram_device *hw_nvram = ZALLOC(hw_nvram_device);
-  return hw_nvram;
+  hw_nvram_device *nvram = ZALLOC(hw_nvram_device);
+  return nvram;
 }
 
 typedef struct _hw_nvram_reg_spec {
@@ -94,74 +108,90 @@ typedef struct _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));
+  hw_nvram_device *nvram = (hw_nvram_device*)device_data(me);
   
+  /* use the generic init code to attach this device to its parent bus */
+  generic_device_init_address(me);
+
+  /* find the first non zero reg property and use that as the device
+     size */
+  if (nvram->sizeof_memory == 0) {
+    reg_property_spec reg;
+    int reg_nr;
+    for (reg_nr = 0;
+        device_find_reg_array_property(me, "reg", reg_nr, &reg);
+        reg_nr++) {
+      unsigned attach_size;
+      if (device_size_to_attach_size(device_parent(me),
+                                    &reg.size, &attach_size,
+                                    me)) {
+       nvram->sizeof_memory = attach_size;
+       break;
+      }
+    }
+    if (nvram->sizeof_memory == 0)
+      device_error(me, "reg property must contain a non-zero phys-addr:size tupple");
+    if (nvram->sizeof_memory < 8)
+      device_error(me, "NVRAM must be at least 8 bytes in size");
+  }
+
   /* 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);
+  if (nvram->memory == NULL) {
+    nvram->memory = zalloc(nvram->sizeof_memory);
   }
   else
-    memset(hw_nvram->memory, hw_nvram->sizeof_memory, 0);
+    memset(nvram->memory, 0, nvram->sizeof_memory);
   
-  hw_nvram->timezone = device_find_integer_property(me, "timezone");
+  if (device_find_property(me, "timezone") == NULL)
+    nvram->timezone = 0;
+  else
+    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;
+  nvram->addr_year = nvram->sizeof_memory - 1;
+  nvram->addr_month = nvram->sizeof_memory - 2;
+  nvram->addr_date = nvram->sizeof_memory - 3;
+  nvram->addr_day = nvram->sizeof_memory - 4;
+  nvram->addr_hour = nvram->sizeof_memory - 5;
+  nvram->addr_minutes = nvram->sizeof_memory - 6;
+  nvram->addr_seconds = nvram->sizeof_memory - 7;
+  nvram->addr_control = 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)
 {
+  val = val % 100;
+  if (val < 0)
+    val += 100;
   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)
+hw_nvram_update_clock(hw_nvram_device *nvram,
+                     cpu *processor)
 {
 #ifdef HAVE_TIME_H
-  if (!(hw_nvram->memory[hw_nvram->addr_control] & 0xc0)) {
+  if (!(nvram->memory[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;
+    if (nvram->host_time != host_time) {
+      time_t nvtime = host_time + 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);
+      nvram->host_time = host_time;
+      nvram->memory[nvram->addr_year] = hw_nvram_bcd(clock->tm_year);
+      nvram->memory[nvram->addr_month] = hw_nvram_bcd(clock->tm_mon + 1);
+      nvram->memory[nvram->addr_date] = hw_nvram_bcd(clock->tm_mday);
+      nvram->memory[nvram->addr_day] = hw_nvram_bcd(clock->tm_wday + 1);
+      nvram->memory[nvram->addr_hour] = hw_nvram_bcd(clock->tm_hour);
+      nvram->memory[nvram->addr_minutes] = hw_nvram_bcd(clock->tm_min);
+      nvram->memory[nvram->addr_seconds] = hw_nvram_bcd(clock->tm_sec);
     }
   }
 #else
@@ -170,7 +200,7 @@ hw_nvram_update_clock(hw_nvram_device *hw_nvram, cpu *processor)
 }
 
 static void
-hw_nvram_set_clock(hw_nvram_device *hw_nvram, cpu *processor)
+hw_nvram_set_clock(hw_nvram_device *nvram, cpu *processor)
 {
   error ("fixme - how do I set the localtime\n");
 }
@@ -185,11 +215,11 @@ hw_nvram_io_read_buffer(device *me,
                        unsigned_word cia)
 {
   int i;
-  hw_nvram_device *hw_nvram = (hw_nvram_device*)device_data(me);
+  hw_nvram_device *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);
+    unsigned address = (addr + i) % nvram->sizeof_memory;
+    unsigned8 data = nvram->memory[address];
+    hw_nvram_update_clock(nvram, processor);
     ((unsigned8*)dest)[i] = data;
   }
   return nr_bytes;
@@ -205,17 +235,17 @@ hw_nvram_io_write_buffer(device *me,
                         unsigned_word cia)
 {
   int i;
-  hw_nvram_device *hw_nvram = (hw_nvram_device*)device_data(me);
+  hw_nvram_device *nvram = (hw_nvram_device*)device_data(me);
   for (i = 0; i < nr_bytes; i++) {
-    unsigned address = (addr + i) % hw_nvram->sizeof_memory;
+    unsigned address = (addr + i) % nvram->sizeof_memory;
     unsigned8 data = ((unsigned8*)source)[i];
-    if (address == hw_nvram->addr_control
+    if (address == nvram->addr_control
        && (data & 0x80) == 0
-       && (hw_nvram->memory[address] & 0x80) == 0x80)
-      hw_nvram_set_clock(hw_nvram, processor);
+       && (nvram->memory[address] & 0x80) == 0x80)
+      hw_nvram_set_clock(nvram, processor);
     else
-      hw_nvram_update_clock(hw_nvram, processor);
-    hw_nvram->memory[address] = data;
+      hw_nvram_update_clock(nvram, processor);
+    nvram->memory[address] = data;
   }
   return nr_bytes;
 }
This page took 0.057685 seconds and 4 git commands to generate.