ld: Require GCC 5 for Build pr25749-1b (-pie -fPIE)
[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.
 
 /*  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
 
     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,
     (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
     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 _CORE_C_
 #define _CORE_C_
 
-#ifndef STATIC_INLINE_CORE
-#define STATIC_INLINE_CORE STATIC_INLINE
-#endif
-
-
 #include "basics.h"
 #include "basics.h"
-#include "device_tree.h"
+#include "device_table.h"
 #include "corefile.h"
 
 #include "corefile.h"
 
-
 typedef struct _core_mapping core_mapping;
 struct _core_mapping {
 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 */
   /* common */
+  int level;
   int space;
   unsigned_word base;
   unsigned_word bound;
   unsigned nr_bytes;
   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 *next;
 };
 
 struct _core_map {
   core_mapping *first;
-  core_mapping *default_map;
 };
 
 typedef enum {
 };
 
 typedef enum {
@@ -66,15 +58,26 @@ struct _core {
 };
 
 
 };
 
 
-INLINE_CORE core *
+INLINE_CORE\
+(core *)
 core_create(void)
 {
 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;
 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;
     while (curr != NULL) {
       core_mapping *tbd = curr;
       curr = curr->next;
-      if (tbd->free_buffer) {
+      if (tbd->free_buffer != NULL) {
        ASSERT(tbd->buffer != NULL);
        ASSERT(tbd->buffer != NULL);
-       zfree(tbd->buffer);
+       free(tbd->free_buffer);
       }
       }
-      zfree(tbd);
+      free(tbd);
     }
     map->first = NULL;
     }
     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 */
 
 /* 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;
 }
 
 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;
 }
 
 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;
 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,
 new_core_mapping(attach_type attach,
                 int space,
                 unsigned_word addr,
                 unsigned nr_bytes,
-                const device *device,
+                device *device,
                 void *buffer,
                 void *buffer,
-                int free_buffer)
+                void *free_buffer)
 {
   core_mapping *new_mapping = ZALLOC(core_mapping);
 {
   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 */
   /* 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);
   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;
 }
 
 
   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 */
 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*/
                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 */
 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;
 {
   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++) {
   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,
        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,
       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,
       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;
     }
   }
       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,
 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;
   }
       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);
   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,
 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)
 {
 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,
     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;
                            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;
        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;
 }
 
 
   }
   return count;
 }
 
 
-INLINE_CORE unsigned
+INLINE_CORE\
+(unsigned)
 core_map_write_buffer(core_map *map,
                      const void *buffer,
                      unsigned_word addr,
                      unsigned len)
 {
 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,
     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;
                                                  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;
        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;
 }
 
 
   }
   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 */
 
 /* define the read/write 1/2/4/8/word functions */
 
-#undef N
 #define N 1
 #define N 1
-#include "core_n.h"
-
+#include "corefile-n.h"
 #undef N
 #undef N
-#define N 2
-#include "core_n.h"
 
 
+#define N 2
+#include "corefile-n.h"
 #undef N
 #undef N
-#define N 4
-#include "core_n.h"
 
 
+#define N 4
+#include "corefile-n.h"
 #undef N
 #undef N
-#define N 8
-#include "core_n.h"
 
 
+#define N 8
+#include "corefile-n.h"
 #undef N
 #undef N
+
 #define N word
 #define N word
-#include "core_n.h"
+#include "corefile-n.h"
+#undef N
 
 #endif /* _CORE_C_ */
 
 #endif /* _CORE_C_ */
This page took 0.035963 seconds and 4 git commands to generate.