OSDN Git Service

[bsp/ChangeLog]
authormrg <mrg>
Sat, 13 Jan 2001 14:26:05 +0000 (14:26 +0000)
committermrg <mrg>
Sat, 13 Jan 2001 14:26:05 +0000 (14:26 +0000)
2001-01-13  matthew green  <mrg@redhat.com>

* configrun-sid.in: `load-accessor' becomes Harvard architecture
friendly.  Split into `load-accessor-insn' and `load-accessor-data'.

[component/loader/ChangeLog]
2001-01-13  matthew green  <mrg@redhat.com>

* compLoader.cxx (load_accessor): Delete member.
(load_accessor_insn, load_accessor_data): New bus* members.
(ctor): Initialise load_accessor_insn and load_accessor_data.
Add `load-accessor-insn' and `load-accessor-data' accessors
and delete `load-accessor'.
(load_function): Extend to 64 bit addresses, and have an instruction
space identifier.
(load_it): Check both load_accessor_insn and load_accessor_data are set,
and use the appropriate one.  Extend messages to meantion instruction or
data loads.
* elfload.h (fetchQuadLittle, fetchQuadBig, fetchQuad): New macros.
(PFLOAD): Make 64-bit & Harvard address space friendly
(sw-load-elf.txt): Document `load-accessor-insn' and `load-accessor-data'
accessors.
        * elfload.c (readElfFile): Support 64-bit ELF as well as 32-bit ELF.
* sw-load-elf.txt: Document `load-accessor-insn' and `load-accessor-data'
accessors.

sid/bsp/ChangeLog
sid/bsp/configrun-sid.in
sid/component/loader/ChangeLog
sid/component/loader/compLoader.cxx
sid/component/loader/elfload.c
sid/component/loader/elfload.h
sid/component/loader/sw-load-elf.txt

index 6e358af..530d064 100644 (file)
@@ -1,3 +1,8 @@
+2001-01-13  matthew green  <mrg@redhat.com>
+       
+       * configrun-sid.in: `load-accessor' becomes Harvard architecture
+       friendly.  Split into `load-accessor-insn' and `load-accessor-data'.
+
 2001-01-11  Nicholas Duffek  <nsd@redhat.com>
 
        * configrun-sid.in ($enable_z_packet): New variable.
index bd44ade..4e7db27 100644 (file)
@@ -821,7 +821,8 @@ if ($exec)
     $second_section .= "# loader
 set loader file \"$exec\"
 set loader verbose? $opt_verbose
-connect-bus loader load-accessor mapper access-port # don't trace loading
+connect-bus loader load-accessor-data mapper access-port # don't trace loading
+connect-bus loader load-accessor-insn mapper access-port # don't trace loading
 connect-pin init-sequence output-1 -> loader load!
 connect-pin loader start-pc-set -> cpu start-pc-set!
 connect-pin loader endian-set -> cpu endian-set!
index ca5480e..512baed 100644 (file)
@@ -1,3 +1,23 @@
+2001-01-13  matthew green  <mrg@redhat.com>
+
+       * compLoader.cxx (load_accessor): Delete member.
+       (load_accessor_insn, load_accessor_data): New bus* members.
+       (ctor): Initialise load_accessor_insn and load_accessor_data.
+       Add `load-accessor-insn' and `load-accessor-data' accessors
+       and delete `load-accessor'.
+       (load_function): Extend to 64 bit addresses, and have an instruction
+       space identifier.
+       (load_it): Check both load_accessor_insn and load_accessor_data are set,
+       and use the appropriate one.  Extend messages to meantion instruction or
+       data loads.
+       * elfload.h (fetchQuadLittle, fetchQuadBig, fetchQuad): New macros.
+       (PFLOAD): Make 64-bit & Harvard address space friendly
+       (sw-load-elf.txt): Document `load-accessor-insn' and `load-accessor-data'
+       accessors.
+        * elfload.c (readElfFile): Support 64-bit ELF as well as 32-bit ELF.
+       * sw-load-elf.txt: Document `load-accessor-insn' and `load-accessor-data'
+       accessors.
+
 2000-11-21  Frank Ch. Eigler  <fche@redhat.com>
 
        * Makefile.in: Regenerated.
index 732010d..1cb9f2f 100644 (file)
@@ -60,7 +60,6 @@ using sidutil::std_error_string;
 
 // ----------------------------------------------------------------------------
 
-
 class generic_loader: public virtual component,
                      protected no_bus_component,
                      protected fixed_attribute_map_component,
@@ -86,7 +85,8 @@ protected:
   string load_file;
 
   // accessors
-  bus* load_accessor;
+  bus* load_accessor_insn;
+  bus* load_accessor_data;
 
   // The load pin was triggered.
   virtual void load_it (host_int_4) = 0;
@@ -103,13 +103,15 @@ public:
     doit_pin(this, & generic_loader::load_it), 
     verbose_p(false),
     load_file("/dev/null"),
-    load_accessor(0)
+    load_accessor_insn(0),
+    load_accessor_data(0)
     {
       add_pin("load!", & this->doit_pin);
       add_pin("start-pc-set", & this->start_pc_pin);
       add_pin("endian-set", & this->endian_pin);
       add_pin("error", & this->error_pin);
-      add_accessor("load-accessor", & this->load_accessor);
+      add_accessor("load-accessor-insn", & this->load_accessor_insn);
+      add_accessor("load-accessor-data", & this->load_accessor_data);
       add_attribute("file", & this->load_file, "setting");
       add_attribute("verbose?", & this->verbose_p, "setting");
       add_attribute_virtual ("state-snapshot", this,
@@ -119,7 +121,6 @@ public:
     
 };
 
-
 ostream& 
 operator << (ostream& out, const generic_loader& it)
 {
@@ -149,27 +150,25 @@ operator >> (istream& in, generic_loader& it)
   return in;
 }
 
-
-
 // ----------------------------------------------------------------------------
 
-
 class elf_loader: public generic_loader
 {
   // static pointer to active instance (XXX: concurrency?)
   static elf_loader* freeloader;
 
   // callback function from C code in elfload.c
-  static int load_function(char* dest_addr, char* host_addr, int file_offset, int bytes);
+  static int load_function(host_int_8 dest_addr, char* host_addr, host_int_8 file_offset, host_int_8 bytes, int insn_space);
+  static int verbose_function(char* s);
 
   // stream for current file  
   ifstream* file;
 
   void load_it (host_int_4)
     {
-      if (this->load_accessor == 0)
+      if (this->load_accessor_insn == 0 || this->load_accessor_data == 0)
        {
-         cerr << "loader: error - target accessor not configured!" << endl;
+         cerr << "loader: error - target accessors not configured!" << endl;
          this->error_pin.drive (0);
          return;
        }
@@ -181,7 +180,7 @@ class elf_loader: public generic_loader
 
       assert(elf_loader::freeloader == 0);
       this->file = new ifstream(this->load_file.c_str(), ios::binary | ios::in);
-      if(! this->file->good())
+      if (! this->file->good())
        {
          cerr << "loader: error opening " << load_file << ": "
               << std_error_string() << endl;
@@ -215,40 +214,46 @@ class elf_loader: public generic_loader
     }
 };
 
-
 // static variable
 elf_loader* elf_loader::freeloader = 0;
 
 // static function
 int
-elf_loader::load_function(char* dest_addr, char* host_addr, int file_offset, int bytes)
+elf_loader::load_function(host_int_8 dest_addr, char *host_addr, host_int_8 file_offset, host_int_8 bytes, int insn_space)
 {
-  if (elf_loader::freeloader->verbose_p)
+  elf_loader& l = * elf_loader::freeloader;
+  string who = insn_space ? "instruction" : "data";
+
+  if (l.verbose_p)
     {
-      if(host_addr == 0)
+      if (host_addr == 0)
        cout << "loader: reading "
             << make_numeric_attribute (bytes, ios::hex | ios::showbase)
             << " bytes from file offset "
             << make_numeric_attribute (file_offset, ios::hex | ios::showbase)
-            << " into target memory at "
+            << " into target " << who << " memory at "
             << make_numeric_attribute ((void *)dest_addr, ios::hex | ios::showbase)
             << endl;
     }
 
-  elf_loader& l = * elf_loader::freeloader;
   ifstream& f = * l.file;
-  bus* b = l.load_accessor;
+  bus* b;
+
+  if (insn_space)
+    b = l.load_accessor_insn;
+  else
+    b = l.load_accessor_data;
   assert (b);
 
   // go to proper offset in file
   f.seekg(file_offset);
 
   // fetch lots of characters
-  for(int n=0; n<bytes; n++)
+  for (int n = 0; n < bytes; n++)
     {
       char c;
       f.get(c);
-      if(! f.good())
+      if (!f.good())
        {
          cerr << "loader: error reading byte " << file_offset+n
               << " from file " << l.load_file << endl;
@@ -262,19 +267,20 @@ elf_loader::load_function(char* dest_addr, char* host_addr, int file_offset, int
        }
       else // read into target memory
        {
-         host_int_4 a = (host_int_4)(dest_addr ++);
+         host_int_8 a = dest_addr++;
          little_int_1 data = c;
          host_int_4 addr = a;
 
          bus::status s;
+
          do // loop while memory getting ready
            {
              s = b->write(addr, data);
-           } while(s == bus::delayed);
+           } while (s == bus::delayed);
 
-         if(s != bus::ok) // abort on error
+         if (s != bus::ok) // abort on error
            {
-             cerr << "loader: write to accessor failed at address "
+             cerr << "loader: write to " << who << " accessor failed at address "
                   << make_numeric_attribute (addr, ios::hex | ios::showbase)
                   << ", status "
                   << (int) s << endl;
@@ -287,11 +293,8 @@ elf_loader::load_function(char* dest_addr, char* host_addr, int file_offset, int
   return bytes;
 }
 
-
-
 // ----------------------------------------------------------------------------
 
-
 static
 vector<string>
 compLoaderListTypes()
@@ -301,18 +304,16 @@ compLoaderListTypes()
   return types;
 }
 
-
 static
 component*
 compLoaderCreate(const string& typeName)
 {
-  if(typeName == "sw-load-elf")
+  if (typeName == "sw-load-elf")
     return new elf_loader();
   else
     return 0;
 }
 
-
 static
 void
 compLoaderDelete(component* c)
@@ -320,7 +321,6 @@ compLoaderDelete(component* c)
   delete dynamic_cast<elf_loader*>(c);
 }
 
-
 // static object
 extern const component_library loader_component_library;
 
index 94b9c40..52b3015 100644 (file)
 #include <elfload.h>
 #include <unistd.h>
 
-unsigned char fileHeader [52];
-unsigned char psymHdr[32];
+unsigned char fileHeader [64];
+unsigned char psymHdr[56];
 
 #define PT_LOAD 1
 
 struct LoadAreas
 {
-  char *loadAddr;
-  int memsize;
-  int filesize;
-  int offset;
+  host_int_8 loadAddr;
+  host_int_8 filesize;
+  host_int_8 offset;
+  int flags;
   int loaded;
 } loadAreas[100]; // XXX: limit on number of loadable sections
 
-
 /* Read in an ELF file, using FUNC to read data from the stream.
    The result is a boolean indicating success.
    The entry point as specified in the ELF header is stored in *ENTRY_POINT.
@@ -39,13 +38,14 @@ struct LoadAreas
 int
 readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian)
 {
-  int psymOffset;
+  host_int_8 psymOffset;
   int psymSize;
   int psymNum;
-  unsigned entryPoint = 0;
+  host_int_8 entryPoint = 0;
   int loadAreaCount = 0;
   int x;
   int littleEndian;
+  int sixtyfourbit;
 
   /* This is relatively straightforward. We first read in the file header,
      find out how many sections there are, determine which ones are loadable
@@ -53,38 +53,80 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian)
 
      There is one major failing, tho--if the psym header isn't at the front
      of the file, and we're loading from a stream that we can't back
-     up on, we will lose. */
-  if (func (NULL, fileHeader, 0, 52) != 52)
+     up on, we will lose.  */
+  if (func (NULL, fileHeader, 0, 64, 0) != 64)
     {
       return 0;
     }
+
+  /* Check this is an ELF file.  */
+  if (fileHeader[0] != 0x7f
+    || fileHeader[1] != 'E'
+    || fileHeader[2] != 'L'
+    || fileHeader[3] != 'F')
+      return 0;
+
+  sixtyfourbit = (fileHeader[EI_CLASS] == ELFCLASS64);
   littleEndian = (fileHeader[EI_DATA] == ELFDATA2LSB);
-  entryPoint = fetchWord (fileHeader+24, littleEndian);
-  psymOffset = fetchWord (fileHeader+28, littleEndian);
-  psymSize = fetchShort (fileHeader+42, littleEndian);
-  psymNum = fetchShort (fileHeader+44, littleEndian);
+
+  if (sixtyfourbit) 
+    {
+      entryPoint = fetchQuad (fileHeader+24, littleEndian);
+      psymOffset = fetchQuad (fileHeader+32, littleEndian);
+      psymSize = fetchShort (fileHeader+54, littleEndian);
+      psymNum = fetchShort (fileHeader+56, littleEndian);
+    }
+  else
+    {
+      entryPoint = fetchWord (fileHeader+24, littleEndian);
+      psymOffset = fetchWord (fileHeader+28, littleEndian);
+      psymSize = fetchShort (fileHeader+42, littleEndian);
+      psymNum = fetchShort (fileHeader+44, littleEndian);
+    }
   for (x = 0; x < psymNum; x++)
     {
-      if (func (NULL, psymHdr, psymOffset, 32) != 32)
-       {
-         return 0;
-       }
-      if (fetchWord (psymHdr, littleEndian) == PT_LOAD)
-       {
-         loadAreas[loadAreaCount].loadAddr = (char *)fetchWord(psymHdr+8,
-                                                               littleEndian);
-         loadAreas[loadAreaCount].offset = fetchWord(psymHdr+4, littleEndian);
-         loadAreas[loadAreaCount].filesize = fetchWord(psymHdr+16,
-                                                       littleEndian);
-         loadAreas[loadAreaCount].loaded = 0;
-         loadAreaCount++;
-       }
+      if (sixtyfourbit)
+        {
+         if (func (NULL, psymHdr, psymOffset, 56, 0) != 56)
+           {
+             return 0;
+           }
+         if (fetchWord (psymHdr, littleEndian) == PT_LOAD)
+           {
+             loadAreas[loadAreaCount].loadAddr = fetchQuad(psymHdr+16,
+                                                           littleEndian);
+             loadAreas[loadAreaCount].offset = fetchQuad(psymHdr+8, littleEndian);
+             loadAreas[loadAreaCount].filesize = fetchQuad(psymHdr+32,
+                                                           littleEndian);
+             loadAreas[loadAreaCount].flags = fetchWord(psymHdr+4, littleEndian);
+             loadAreas[loadAreaCount].loaded = 0;
+             loadAreaCount++;
+           }
+        }
+      else
+        {
+         if (func (NULL, psymHdr, psymOffset, 32, 0) != 32)
+           {
+             return 0;
+           }
+         if (fetchWord (psymHdr, littleEndian) == PT_LOAD)
+           {
+             loadAreas[loadAreaCount].loadAddr = fetchWord(psymHdr+8,
+                                                                   littleEndian);
+             loadAreas[loadAreaCount].offset = fetchWord(psymHdr+4, littleEndian);
+             loadAreas[loadAreaCount].filesize = fetchWord(psymHdr+16,
+                                                           littleEndian);
+             loadAreas[loadAreaCount].flags = fetchWord(psymHdr+24, littleEndian);
+             loadAreas[loadAreaCount].loaded = 0;
+             loadAreaCount++;
+           }
+        }
       psymOffset += psymSize;
     }
   /* Yuck. N^2 behavior (where N is the # of loadable sections). */
   for (x = 0; x < loadAreaCount; x++)
     {
-      int which;
+      int which, is_insn;
       int smallest = -1, smallestSz = -1;
       /* Find smallest not-loaded */
       for (which = 0; which < loadAreaCount; which++)
@@ -98,10 +140,13 @@ readElfFile (PFLOAD func, unsigned* entry_point, int* little_endian)
                }
            }
        }
+      is_insn = (((loadAreas[smallest].loadAddr) & PF_X|PF_R) == (PF_X|PF_R))
+             || ((loadAreas[smallest].loadAddr >> 32) & 1);
       if (func (loadAreas[smallest].loadAddr,
                NULL,
                loadAreas[smallest].offset,
-               loadAreas[smallest].filesize) != loadAreas[smallest].filesize)
+               loadAreas[smallest].filesize,
+               is_insn) != loadAreas[smallest].filesize)
        {
          return 0;
        }
index 3b037c3..2a7bb18 100644 (file)
 #define BYTE(X,offset) (((X)[offset]) & 255)
 #define fetchShortLittle(addr) (BYTE((addr),1)*256+BYTE((addr),0))
 #define fetchWordLittle(addr) (fetchShortLittle (addr) + fetchShortLittle((addr) + 2) * 65536)
+#define fetchQuadLittle(addr) (fetchWordLittle ((addr)) + ((host_int_8)fetchWordLittle((addr) + 4) << 32))
 #define fetchShortBig(addr) (BYTE((addr),0)*256+BYTE((addr),1))
 #define fetchWordBig(addr) (fetchShortBig (addr) * 65536 + fetchShortBig((addr) + 2))
-#define fetchWord(ADDR,LITTLE) ((LITTLE) ? fetchWordLittle((ADDR)) : fetchWordBig((ADDR)))
+#define fetchQuadBig(addr) (((host_int_8)fetchWordBig ((addr)) << 32) + fetchWordBig((addr) + 4))
 #define fetchShort(ADDR,LITTLE) ((LITTLE) ? fetchShortLittle((ADDR)) : fetchShortBig((ADDR)))
+#define fetchWord(ADDR,LITTLE) ((LITTLE) ? fetchWordLittle((ADDR)) : fetchWordBig((ADDR)))
+#define fetchQuad(ADDR,LITTLE) ((LITTLE) ? fetchQuadLittle((ADDR)) : fetchQuadBig((ADDR)))
 
 /* 
    PFLOAD represents a function that will read file data. 
    raw file data. If DEST is NULL, then DEST2 should be used.
    OFFSET is the byte offset into the file to be read.
    AMOUNT is the number of bytes to read.
+   INSN_SPACE is true if this data should be loaded into instruction space.
 
    If OFFSET and AMOUNT are both negative, then the file should be
    closed (any remaining bytes are to be ignored). */
 
-typedef int (*PFLOAD)(char *dest, char *dest2, int offset, int amount);
+typedef unsigned long long host_int_8; /* XXX */
+
+typedef int (*PFLOAD)(host_int_8 dest, char *dest2, host_int_8 offset, host_int_8 amount, int insn_space);
 /* Load an ELF executable into memory. FUNC is used to actually read the
    file. */
 extern int readElfFile(PFLOAD func, unsigned*, int*);
 
+#define EI_CLASS 4
+#define ELFCLASS64  2 /* 64 bit */
 #define EI_DATA 5
 #define ELFDATA2LSB 1 /* little endian */
 #define ELFDATA2MSB 2 /* big endian */
 
+/* Elf program header flags */
+#define PF_X   0x01    /* executable */
+#define PF_R   0x04    /* readable */
+
 #endif
index 8582f81..88695ac 100644 (file)
@@ -6,7 +6,7 @@
 
   Attributes: file verbose? state-snapshot
   Pins: load! start-pc-set endian-set error
-  Accessors: load-accessor
+  Accessors: load-accessor-insn load-accessor-data
 
   Shared library: libloader.la
   Symbol: loader_component_library
@@ -61,7 +61,8 @@
        new mapper bus
        connect-pin reset-manager input <- main starting
        connect-pin reset-manager output-1 -> loader load!
-        connect-bus loader load-accessor bus access-port
+        connect-bus loader load-accessor-insn bus access-port
+        connect-bus loader load-accessor-data bus access-port
        set loader file "/foo/bar.x"
         set loader verbose? 1
        connect-pin loader start-pc-set -> cpu start-pc-set!
@@ -82,4 +83,5 @@
       - verbose? | setting | 1/0 | 0 | configuration
 
     * accessors
-      - load-accessor | write little_int_1 | loading
+      - load-accessor-insn | write little_int_1 | loading
+      - load-accessor-data | write little_int_1 | loading