Regenerate configure in sim
[deliverable/binutils-gdb.git] / sim / ppc / corefile.c
index c112a63f5383940c7def4314b4bf8880d1e92033..d784d64f4650eb2922ef063b93c6b2f3954b016b 100644 (file)
@@ -1,10 +1,10 @@
 /*  This file is part of the program psim.
 
-    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+    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
+    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,
@@ -13,8 +13,7 @@
     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.
+    along with this program; if not, see <http://www.gnu.org/licenses/>.
  
     */
 
 #ifndef _CORE_C_
 #define _CORE_C_
 
-#ifndef STATIC_INLINE_CORE
-#define STATIC_INLINE_CORE STATIC_INLINE
-#endif
-
-
 #include "basics.h"
-#include "device_tree.h"
+#include "device_table.h"
 #include "corefile.h"
 
-
 typedef struct _core_mapping core_mapping;
 struct _core_mapping {
-  /* ram map */
-  int free_buffer;
-  void *buffer;
-  /* device map */
-  const device *device;
-  device_io_read_buffer_callback *reader;
-  device_io_write_buffer_callback *writer;
   /* common */
+  int level;
   int space;
   unsigned_word base;
   unsigned_word bound;
   unsigned nr_bytes;
+  /* memory map */
+  void *free_buffer;
+  void *buffer;
+  /* callback map */
+  device *device;
+  /* growth */
   core_mapping *next;
 };
 
 struct _core_map {
   core_mapping *first;
-  core_mapping *default_map;
 };
 
 typedef enum {
@@ -66,15 +58,26 @@ struct _core {
 };
 
 
-INLINE_CORE core *
+INLINE_CORE\
+(core *)
 core_create(void)
 {
-  core *new_core = ZALLOC(core);
-  return new_core;
+  return ZALLOC(core);
 }
 
 
-STATIC_INLINE_CORE void
+INLINE_CORE\
+(core *)
+core_from_device(device *root)
+{
+  root = device_root(root);
+  ASSERT(strcmp(device_name(root), "core") == 0);
+  return device_data(root);
+}
+
+
+INLINE_CORE\
+(void)
 core_init(core *memory)
 {
   core_map_types access_type;
@@ -87,19 +90,13 @@ core_init(core *memory)
     while (curr != NULL) {
       core_mapping *tbd = curr;
       curr = curr->next;
-      if (tbd->free_buffer) {
+      if (tbd->free_buffer != NULL) {
        ASSERT(tbd->buffer != NULL);
-       zfree(tbd->buffer);
+       free(tbd->free_buffer);
       }
-      zfree(tbd);
+      free(tbd);
     }
     map->first = NULL;
-    /* blow away the default */
-    if (map->default_map != NULL) {
-      ASSERT(map->default_map->buffer == NULL);
-      zfree(map->default_map);
-    }
-    map->default_map = NULL;
   }
 }
 
@@ -108,19 +105,22 @@ core_init(core *memory)
 /* the core has three sub mappings that the more efficient
    read/write fixed quantity functions use */
 
-INLINE_CORE core_map *
+INLINE_CORE\
+(core_map *)
 core_readable(core *memory)
 {
   return memory->map + core_read_map;
 }
 
-INLINE_CORE core_map *
+INLINE_CORE\
+(core_map *)
 core_writeable(core *memory)
 {
   return memory->map + core_write_map;
 }
 
-INLINE_CORE core_map *
+INLINE_CORE\
+(core_map *)
 core_executable(core *memory)
 {
   return memory->map + core_execute_map;
@@ -128,106 +128,112 @@ core_executable(core *memory)
 
 
 
-STATIC_INLINE_CORE core_mapping *
+STATIC_INLINE_CORE\
+(core_mapping *)
 new_core_mapping(attach_type attach,
                 int space,
                 unsigned_word addr,
                 unsigned nr_bytes,
-                const device *device,
+                device *device,
                 void *buffer,
-                int free_buffer)
+                void *free_buffer)
 {
   core_mapping *new_mapping = ZALLOC(core_mapping);
-  switch (attach) {
-  case attach_default:
-  case attach_callback:
-    new_mapping->device = device;
-    new_mapping->reader = device->callback->io_read_buffer;
-    new_mapping->writer = device->callback->io_write_buffer;
-    break;
-  case attach_raw_memory:
-    new_mapping->buffer = buffer;
-    new_mapping->free_buffer = free_buffer;
-    break;
-  default:
-    error("new_core_mapping() - internal error - unknown attach type %d\n",
-         attach);
-  }
   /* common */
+  new_mapping->level = attach;
   new_mapping->space = space;
   new_mapping->base = addr;
   new_mapping->nr_bytes = nr_bytes;
   new_mapping->bound = addr + (nr_bytes - 1);
+  if (attach == attach_raw_memory) {
+    new_mapping->buffer = buffer;
+    new_mapping->free_buffer = free_buffer;
+  }
+  else if (attach >= attach_callback) {
+    new_mapping->device = device;
+  }
+  else {
+    error("new_core_mapping() - internal error - unknown attach type %d\n",
+         attach);
+  }
   return new_mapping;
 }
 
 
-STATIC_INLINE_CORE void
+STATIC_INLINE_CORE\
+(void)
 core_map_attach(core_map *access_map,
                attach_type attach,
                int space,
                unsigned_word addr,
                unsigned nr_bytes, /* host limited */
-               const device *device, /*callback/default*/
+               device *client, /*callback/default*/
                void *buffer, /*raw_memory*/
-               int free_buffer) /*raw_memory*/
+               void *free_buffer) /*raw_memory*/
 {
-  if (attach == attach_default) {
-    if (access_map->default_map != NULL)
-      error("core_map_attach() default mapping already in place\n");
-    ASSERT(buffer == NULL);
-    access_map->default_map = new_core_mapping(attach, 
-                                              space, addr, nr_bytes,
-                                              device, buffer, free_buffer);
+  /* find the insertion point for this additional mapping and insert */
+  core_mapping *next_mapping;
+  core_mapping **last_mapping;
+
+  /* actually do occasionally get a zero size map */
+  if (nr_bytes == 0) {
+    device_error(client, "called on core_map_attach() with size zero");
   }
-  else {
-    /* find the insertion point for this additional mapping and insert */
-    core_mapping *next_mapping;
-    core_mapping **last_mapping;
-
-    /* actually do occasionally get a zero size map */
-    if (nr_bytes == 0)
-      error("core_map_attach() size == 0\n");
-
-    /* find the insertion point (between last/next) */
-    next_mapping = access_map->first;
-    last_mapping = &access_map->first;
-    while(next_mapping != NULL && next_mapping->bound < addr) {
-      /* assert: next_mapping->base > all bases before next_mapping */
-      /* assert: next_mapping->bound >= all bounds before next_mapping */
-      last_mapping = &next_mapping->next;
-      next_mapping = next_mapping->next;
-    }
 
-    /* check insertion point correct */
-    if (next_mapping != NULL && next_mapping->base < (addr + (nr_bytes - 1))) {
-      error("core_map_attach() map overlap\n");
-    }
+  /* find the insertion point (between last/next) */
+  next_mapping = access_map->first;
+  last_mapping = &access_map->first;
+  while(next_mapping != NULL
+       && (next_mapping->level < attach
+           || (next_mapping->level == attach
+               && next_mapping->bound < addr))) {
+    /* provided levels are the same */
+    /* assert: next_mapping->base > all bases before next_mapping */
+    /* assert: next_mapping->bound >= all bounds before next_mapping */
+    last_mapping = &next_mapping->next;
+    next_mapping = next_mapping->next;
+  }
 
-    /* create/insert the new mapping */
-    *last_mapping = new_core_mapping(attach,
-                                    space, addr, nr_bytes,
-                                    device, buffer, free_buffer);
-    (*last_mapping)->next = next_mapping;
+  /* check insertion point correct */
+  ASSERT(next_mapping == NULL || next_mapping->level >= attach);
+  if (next_mapping != NULL && next_mapping->level == attach
+      && next_mapping->base < (addr + (nr_bytes - 1))) {
+    device_error(client, "map overlap when attaching %d:0x%lx (%ld)",
+                space, (long)addr, (long)nr_bytes);
   }
+
+  /* create/insert the new mapping */
+  *last_mapping = new_core_mapping(attach,
+                                  space, addr, nr_bytes,
+                                  client, buffer, free_buffer);
+  (*last_mapping)->next = next_mapping;
 }
 
 
-INLINE_CORE void
+INLINE_CORE\
+(void)
 core_attach(core *memory,
            attach_type attach,
            int space,
            access_type access,
            unsigned_word addr,
            unsigned nr_bytes, /* host limited */
-           const device *device) /*callback/default*/
+           device *client) /*callback/default*/
 {
   core_map_types access_map;
-  int free_buffer = 0;
-  void *buffer = NULL;
-  ASSERT(attach == attach_default || nr_bytes > 0);
-  if (attach == attach_raw_memory)
-    buffer = zalloc(nr_bytes);
+  void *buffer;
+  void *free_buffer;
+  if (attach == attach_raw_memory) {
+    /* Padd out the raw buffer to ensure that ADDR starts on a
+       correctly aligned boundary */
+    int padding = (addr % sizeof (unsigned64));
+    free_buffer = zalloc(nr_bytes + padding);
+    buffer = (char*)free_buffer + padding;
+  }
+  else {
+    buffer = NULL;
+    free_buffer = &buffer; /* marker for assertion */
+  }
   for (access_map = 0; 
        access_map < nr_core_map_types;
        access_map++) {
@@ -237,35 +243,37 @@ core_attach(core *memory,
        core_map_attach(memory->map + access_map,
                        attach,
                        space, addr, nr_bytes,
-                       device, buffer, !free_buffer);
-      free_buffer ++;
+                       client, buffer, free_buffer);
+      free_buffer = NULL;
       break;
     case core_write_map:
       if (access & access_write)
        core_map_attach(memory->map + access_map,
                        attach,
                        space, addr, nr_bytes,
-                       device, buffer, !free_buffer);
-      free_buffer ++;
+                       client, buffer, free_buffer);
+      free_buffer = NULL;
       break;
     case core_execute_map:
       if (access & access_exec)
        core_map_attach(memory->map + access_map,
                        attach,
                        space, addr, nr_bytes,
-                       device, buffer, !free_buffer);
-      free_buffer ++;
+                       client, buffer, free_buffer);
+      free_buffer = NULL;
       break;
     default:
       error("core_attach() internal error\n");
       break;
     }
   }
-  ASSERT(free_buffer > 0); /* must attach to at least one thing */
+  /* allocated buffer must attach to at least one thing */
+  ASSERT(free_buffer == NULL);
 }
 
 
-STATIC_INLINE_CORE core_mapping *
+STATIC_INLINE_CORE\
+(core_mapping *)
 core_map_find_mapping(core_map *map,
                      unsigned_word addr,
                      unsigned nr_bytes,
@@ -282,8 +290,6 @@ core_map_find_mapping(core_map *map,
       return mapping;
     mapping = mapping->next;
   }
-  if (map->default_map != NULL)
-    return map->default_map;
   if (abort)
     error("core_find_mapping() - access to unmaped address, attach a default map to handle this - addr=0x%x nr_bytes=0x%x processor=0x%x cia=0x%x\n",
          addr, nr_bytes, processor, cia);
@@ -291,23 +297,24 @@ core_map_find_mapping(core_map *map,
 }
 
 
-STATIC_INLINE_CORE void *
+STATIC_INLINE_CORE\
+(void *)
 core_translate(core_mapping *mapping,
-                    unsigned_word addr)
+              unsigned_word addr)
 {
-  return mapping->buffer + addr - mapping->base;
+  return (void *)(((char *)mapping->buffer) + addr - mapping->base);
 }
 
 
-INLINE_CORE unsigned
+INLINE_CORE\
+(unsigned)
 core_map_read_buffer(core_map *map,
                     void *buffer,
                     unsigned_word addr,
                     unsigned len)
 {
-  unsigned count;
-  unsigned_1 byte;
-  for (count = 0; count < len; count++) {
+  unsigned count = 0;
+  while (count < len) {
     unsigned_word raddr = addr + count;
     core_mapping *mapping =
       core_map_find_mapping(map,
@@ -317,34 +324,39 @@ core_map_read_buffer(core_map *map,
                            0); /*dont-abort*/
     if (mapping == NULL)
       break;
-    if (mapping->reader != NULL) {
-      if (mapping->reader(mapping->device,
-                         &byte,
-                         mapping->space,
-                         raddr - mapping->base,
-                         1, /* nr_bytes */
-                         0, /*processor*/
-                         0 /*cpu*/) != 1)
+    if (mapping->device != NULL) {
+      int nr_bytes = len - count;
+      if (raddr + nr_bytes - 1> mapping->bound)
+       nr_bytes = mapping->bound - raddr + 1;
+      if (device_io_read_buffer(mapping->device,
+                               (unsigned_1*)buffer + count,
+                               mapping->space,
+                               raddr,
+                               nr_bytes,
+                               0, /*processor*/
+                               0 /*cpu*/) != nr_bytes)
        break;
+      count += nr_bytes;
+    }
+    else {
+      ((unsigned_1*)buffer)[count] =
+       *(unsigned_1*)core_translate(mapping, raddr);
+      count += 1;
     }
-    else
-      byte = *(unsigned_1*)core_translate(mapping,
-                                               raddr);
-    ((unsigned_1*)buffer)[count] = T2H_1(byte);
   }
   return count;
 }
 
 
-INLINE_CORE unsigned
+INLINE_CORE\
+(unsigned)
 core_map_write_buffer(core_map *map,
                      const void *buffer,
                      unsigned_word addr,
                      unsigned len)
 {
-  unsigned count;
-  unsigned_1 byte;
-  for (count = 0; count < len; count++) {
+  unsigned count = 0;
+  while (count < len) {
     unsigned_word raddr = addr + count;
     core_mapping *mapping = core_map_find_mapping(map,
                                                  raddr, 1,
@@ -353,144 +365,50 @@ core_map_write_buffer(core_map *map,
                                                  0); /*dont-abort*/
     if (mapping == NULL)
       break;
-    byte = H2T_1(((unsigned_1*)buffer)[count]);
-    if (mapping->writer != NULL) {
-      if (mapping->writer(mapping->device,
-                         &byte,
-                         mapping->space,
-                         raddr - mapping->base,
-                         1, /*nr_bytes*/
-                         0, /*processor*/
-                         0 /*cpu*/) != 1)
+    if (mapping->device != NULL) {
+      int nr_bytes = len - count;
+      if (raddr + nr_bytes - 1 > mapping->bound)
+       nr_bytes = mapping->bound - raddr + 1;
+      if (device_io_write_buffer(mapping->device,
+                                (unsigned_1*)buffer + count,
+                                mapping->space,
+                                raddr,
+                                nr_bytes,
+                                0, /*processor*/
+                                0 /*cpu*/) != nr_bytes)
        break;
+      count += nr_bytes;
+    }
+    else {
+      *(unsigned_1*)core_translate(mapping, raddr) =
+       ((unsigned_1*)buffer)[count];
+      count += 1;
     }
-    else
-      *(unsigned_1*)core_translate(mapping, raddr) = byte;
   }
   return count;
 }
 
 
-
-/* Top level core(root) device: core@garbage
-
-   The core device captures incomming dma requests and changes them to
-   outgoing io requests. */
-
-STATIC_INLINE_CORE void
-core_init_callback(const device *me,
-                  psim *system)
-{
-  core *memory = (core*)me->data;
-  DTRACE_INIT(core);
-  core_init(memory);
-}
-
-
-STATIC_INLINE_CORE void
-core_attach_address_callback(const device *me,
-                            const char *name,
-                            attach_type attach,
-                            int space,
-                            unsigned_word addr,
-                            unsigned nr_bytes,
-                            access_type access,
-                            const device *who) /*callback/default*/
-{
-  core *memory = (core*)me->data;
-  DTRACE_ATTACH_ADDRESS(core);
-  if (space != 0)
-    error("core_attach_address_callback() invalid address space\n");
-  core_attach(memory,
-             attach,
-             space,
-             access,
-             addr,
-             nr_bytes,
-             who);
-}
-
-
-STATIC_INLINE_CORE unsigned
-core_dma_read_buffer_callback(const device *me,
-                             void *dest,
-                             int space,
-                             unsigned_word addr,
-                             unsigned nr_bytes)
-{
-  core *memory = (core*)me->data;
-  DTRACE_DMA_READ_BUFFER(core);
-  return core_map_read_buffer(core_readable(memory),
-                             dest,
-                             addr,
-                             nr_bytes);
-}
-
-
-STATIC_INLINE_CORE unsigned
-core_dma_write_buffer_callback(const device *me,
-                              const void *source,
-                              int space,
-                              unsigned_word addr,
-                              unsigned nr_bytes,
-                              int violate_read_only_section)
-{
-  core *memory = (core*)me->data;
-  core_map *map = (violate_read_only_section
-                  ? core_readable(memory)
-                  : core_writeable(memory));
-  DTRACE_DMA_WRITE_BUFFER(core);
-  return core_map_write_buffer(map,
-                              source,
-                              addr,
-                              nr_bytes);
-}
-
-
-static device_callbacks const core_callbacks = {
-  core_init_callback,
-  core_attach_address_callback,
-  unimp_device_detach_address,
-  unimp_device_io_read_buffer,
-  unimp_device_io_write_buffer,
-  core_dma_read_buffer_callback,
-  core_dma_write_buffer_callback,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
-  unimp_device_ioctl,
-};
-
-
-INLINE_CORE const device *
-core_device_create(core *memory)
-{
-  return device_create_from("core", "/", memory, &core_callbacks, NULL);
-}
-
-
-
 /* define the read/write 1/2/4/8/word functions */
 
-#undef N
 #define N 1
-#include "core_n.h"
-
+#include "corefile-n.h"
 #undef N
-#define N 2
-#include "core_n.h"
 
+#define N 2
+#include "corefile-n.h"
 #undef N
-#define N 4
-#include "core_n.h"
 
+#define N 4
+#include "corefile-n.h"
 #undef N
-#define N 8
-#include "core_n.h"
 
+#define N 8
+#include "corefile-n.h"
 #undef N
+
 #define N word
-#include "core_n.h"
+#include "corefile-n.h"
+#undef N
 
 #endif /* _CORE_C_ */
This page took 0.031495 seconds and 4 git commands to generate.