Hello community,

here is the log from the commit of package silo for openSUSE:Factory checked in 
at 2013-07-16 16:23:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/silo (Old)
 and      /work/SRC/openSUSE:Factory/.silo.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "silo"

Changes:
--------
--- /work/SRC/openSUSE:Factory/silo/silo.changes        2011-09-23 
12:46:17.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.silo.new/silo.changes   2013-07-16 
16:23:58.000000000 +0200
@@ -1,0 +2,7 @@
+Sun Jul  7 19:20:13 UTC 2013 - [email protected]
+
+- Update to new git snapshot 1.4.14+git20
+* Support for running Firmware Flash executables
+* rewrite the ext2 module so that it no longer depends on libext2fs
+
+-------------------------------------------------------------------

Old:
----
  silo-1.4.14+git8.tar.xz

New:
----
  silo-1.4.14+git20.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ silo.spec ++++++
--- /var/tmp/diff_new_pack.K0DXsL/_old  2013-07-16 16:23:58.000000000 +0200
+++ /var/tmp/diff_new_pack.K0DXsL/_new  2013-07-16 16:23:59.000000000 +0200
@@ -1,7 +1,7 @@
 #
-# spec file for package silo (Version 1.4.14+git8)
+# spec file for package silo
 #
-# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,18 +16,19 @@
 #
 
 
-
 Name:           silo
-Version:        1.4.14+git8
-Release:        1
-Group:          System/Boot
+Version:        1.4.14+git20
+Release:        0
 Summary:        Bootloader for SPARC systems
 License:        GPL-2.0+
+Group:          System/Boot
+
 #Git-Clone:    git://git.kernel.org/pub/scm/linux/kernel/git/davem/silo
 #Git-Web:      
http://git.kernel.org/?p=linux/kernel/git/davem/silo.git;a=summary
 Source:         silo-%version.tar.xz
 ExclusiveArch:  sparc sparcv8 sparcv9 sparcv9v
-BuildRequires:  elftoaout libext2fs-devel xz
+BuildRequires:  elftoaout
+BuildRequires:  xz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
 %description

++++++ silo-1.4.14+git8.tar.xz -> silo-1.4.14+git20.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/common/malloc.c new/silo/common/malloc.c
--- old/silo/common/malloc.c    2010-06-30 12:21:43.000000000 +0200
+++ new/silo/common/malloc.c    2012-10-28 02:25:30.000000000 +0200
@@ -18,6 +18,8 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
    USA.  */
 
+#include <stringops.h>
+
 #ifndef MALLOC_BASE
 extern unsigned long _start;
 static char *malloc_ptr = ((char *)&_start) + 0x30000;
@@ -27,6 +29,12 @@
 
 static char *last_alloc = 0;
 
+static char *align_ptr_to(char *ptr, unsigned long align)
+{
+    return (char *) ((((unsigned long) ptr) + (align - 1UL)) &
+                    ~(align - 1UL));
+}
+
 void *malloc (int size)
 {
     char *caddr;
@@ -34,10 +42,51 @@
     caddr = malloc_ptr;
     malloc_ptr += size;
     last_alloc = caddr;
-    malloc_ptr = (char *) ((((unsigned long) malloc_ptr) + 7) & (~7));
+    malloc_ptr = align_ptr_to(malloc_ptr, 8UL);
     return caddr;
 }
 
+void *calloc (int nmemb, int memb_size)
+{
+    char *ret;
+    int size;
+
+    if (!nmemb || !memb_size)
+        return (void *) 0;
+
+    size = nmemb * memb_size;
+    ret = malloc(size);
+
+    if (ret)
+        memset(ret, 0, size);
+
+    return ret;
+}
+
+int posix_memalign(void **memptr, unsigned long alignment, unsigned long size)
+{
+    char *caddr;
+
+    if (alignment & (alignment - 1UL))
+        return -1;
+    if (alignment & (sizeof(void *) - 1UL))
+        return -1;
+
+    if (size == 0) {
+      *memptr = (void *) 0;
+      return 0;
+    }
+
+    caddr = align_ptr_to(malloc_ptr, alignment);
+    malloc_ptr = (caddr + size);
+    last_alloc = caddr;
+    malloc_ptr = align_ptr_to(malloc_ptr, 8UL);
+
+    *memptr = caddr;
+
+    return 0;
+}
+
 void free (void *m)
 {
     if (m == last_alloc)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/include/silo.h new/silo/include/silo.h
--- old/silo/include/silo.h     2010-06-30 12:21:43.000000000 +0200
+++ new/silo/include/silo.h     2012-10-28 02:25:30.000000000 +0200
@@ -125,6 +125,7 @@
 int decompress (char *, char *, unsigned char (*)(void), void (*)(void));
 /* main.c */
 extern enum arch architecture;
+extern int sun4v_cpu;
 /* timer.c */
 int init_timer ();
 void close_timer ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/include/stringops.h new/silo/include/stringops.h
--- old/silo/include/stringops.h        2010-06-30 12:21:43.000000000 +0200
+++ new/silo/include/stringops.h        2012-10-28 02:25:30.000000000 +0200
@@ -2,6 +2,7 @@
 #define __STRINGOPS_H
 
 #include <silo.h>
+#include <stddef.h>
 
 /* common */
 #ifndef __SIZE_TYPE__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/second/Makefile new/silo/second/Makefile
--- old/silo/second/Makefile    2010-06-30 12:21:43.000000000 +0200
+++ new/silo/second/Makefile    2012-10-28 02:25:30.000000000 +0200
@@ -58,13 +58,13 @@
        $(AR) rc $@ $(FS_OBJS)
 
 second: $(OBJS) mark.o
-       $(LD) $(LDFLAGS_SMALL) -Bstatic -o second $(OBJS) -lext2fs mark.o 
`$(CC) -print-libgcc-file-name`
-       $(LD) $(LDFLAGS_LARGE) -Bstatic -o second2 $(OBJS) -lext2fs mark.o 
`$(CC) -print-libgcc-file-name`
+       $(LD) $(LDFLAGS_SMALL) -Bstatic -o second $(OBJS) mark.o `$(CC) 
-print-libgcc-file-name`
+       $(LD) $(LDFLAGS_LARGE) -Bstatic -o second2 $(OBJS) mark.o `$(CC) 
-print-libgcc-file-name`
        $(NM) second | grep -v '*ABS*' | sort > second.map
 
 silotftp: $(OBJSNET) mark.o
-       $(LD) $(LDFLAGS_SMALL) -Bstatic -o silotftp $(OBJSNET) -lext2fs mark.o 
`$(CC) -print-libgcc-file-name`
-       $(LD) $(LDFLAGS_LARGE) -Bstatic -o silotftp2 $(OBJSNET) -lext2fs mark.o 
`$(CC) -print-libgcc-file-name`
+       $(LD) $(LDFLAGS_SMALL) -Bstatic -o silotftp $(OBJSNET) mark.o `$(CC) 
-print-libgcc-file-name`
+       $(LD) $(LDFLAGS_LARGE) -Bstatic -o silotftp2 $(OBJSNET) mark.o `$(CC) 
-print-libgcc-file-name`
        $(NM) silotftp | grep -v '*ABS*' | sort > silotftp.map
 
 second.l: second
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/second/cfg.c new/silo/second/cfg.c
--- old/silo/second/cfg.c       2010-06-30 12:21:43.000000000 +0200
+++ new/silo/second/cfg.c       2013-07-07 21:19:00.000000000 +0200
@@ -93,6 +93,7 @@
     {cft_flag, "pause-after", NULL},
     {cft_strg, "pause-message", NULL},
     {cft_flag, "solaris", NULL},
+    {cft_flag, "flash", NULL},
     {cft_flag, "fill-reboot-cmd", NULL},
     {cft_strg, "bootblock", NULL},
     {cft_flag, "single-key", NULL},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/second/fs/ext2.c new/silo/second/fs/ext2.c
--- old/silo/second/fs/ext2.c   2010-06-30 12:21:43.000000000 +0200
+++ new/silo/second/fs/ext2.c   2012-10-28 02:25:30.000000000 +0200
@@ -3,6 +3,7 @@
    Copyright (C) 1996 Maurizio Plaza
                 1996,1997,1999 Jakub Jelinek
                 2001 Ben Collins
+                2012 David S. Miller
    
    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
@@ -27,118 +28,654 @@
 static ino_t inode = 0;
 struct fs_ops ext2_fs_ops;
 
-void com_err (const char *a, long i, const char *fmt,...)
+#define EXT2_SUPER_MAGIC       0xEF53
+
+static __u32 ext2_to_cpu_32(__u32 v)
 {
-    printf ((char *) fmt);
+       const __u8 *p = (const __u8 *) &v;
+
+       return ((__u32)p[3] << 24 |
+               (__u32)p[2] << 16 |
+               (__u32)p[1] <<  8 |
+               (__u32)p[0]);
 }
 
-static void ext2fs_error (int errcode)
+static __u16 ext2_to_cpu_16(__u16 v)
 {
-#if 0
-    int i;
-    for (i = 0; i < sizeof (ext2errors) / sizeof (ext2errors[0]); i++)
-       if (ext2errors[i].errnum == errcode) {
-           printf ("%s", ext2errors [i].desc);
-           return;
-       }
-#endif
-    printf ("Unknown ext2 error: %d", errcode);
+       const __u8 *p = (const __u8 *) &v;
+
+       return ((__u16)p[1] << 8) | ((__u16)p[0]);
 }
 
-static int open_ext2 (char *device)
+struct silo_ext2_state {
+       struct ext2_super_block *super;
+
+       void                    *scratch_block[4];
+       __u32                   scratch_block_blk[4];
+
+       __u32                   inode_size;
+       __u32                   block_size;
+       __u32                   addr_per_block;
+       __u32                   addr_per_block_bits;
+       __u32                   desc_per_block;
+       __u32                   desc_per_block_bits;
+};
+static struct silo_ext2_state *sstate;
+
+static __u32 ext2_inode_size(struct silo_ext2_state *s)
 {
-    int retval;
+       __u32 rev = ext2_to_cpu_32(s->super->s_rev_level);
 
-    retval = ext2fs_open (device, EXT2_FLAG_DIRTY, 0, 0, silo_io_manager, &fs);
-    if (retval == EXT2_ET_BAD_MAGIC)
-        return 0;
-    if (retval) {
-        printf ("\n");
-        ext2fs_error (retval);
-        printf ("\n");
-       return 0;
-    }
-    root = EXT2_ROOT_INO;
-    return 1;
+       if (rev == 0)
+               return 128;
+
+       return ext2_to_cpu_16(s->super->s_inode_size);
 }
 
-static int dump_block_ext2 (ext2_filsys fs, blk_t *blocknr,
-                           int blockcnt, void *private)
+static __u32 ext2_block_size(struct silo_ext2_state *s)
 {
-    return dump_block(blocknr, blockcnt);
+       __u32 x = ext2_to_cpu_32(s->super->s_log_block_size);
+
+       x += 1;
+
+       return ((__u32) 1 << x) * 512;
 }
 
-static int dump_ext2 (void)
+static void read_scratch_block(struct silo_ext2_state *s, __u32 block, int N)
 {
-    if (ext2fs_block_iterate (fs, inode, 0, 0, dump_block_ext2, 0))
+       if (s->scratch_block_blk[N] == block)
+               return;
+       io_channel_read_blk(fs->io, block, 1, s->scratch_block[N]);
+       s->scratch_block_blk[N] = block;
+}
+
+static void read_data(struct silo_ext2_state *s, __u32 block, __u32 off, __u32 
len, void *buf)
+{
+       read_scratch_block(s, block, 0);
+       memcpy(buf, s->scratch_block[0] + off, len);
+}
+
+static int has_extents(struct ext2_inode *ip)
+{
+       if (ext2_to_cpu_32(ip->i_flags) & 0x80000)
+               return 1;
        return 0;
+}
+
+#define EXT4_EXT_MAGIC         0xf30a
+
+struct ext4_extent_header {
+       __u16   eh_magic;
+       __u16   eh_entries;
+       __u16   eh_max;
+       __u16   eh_depth;
+       __u32   eh_generation;
+};
+
+struct ext4_extent_idx {
+       __u32   ei_block;
+       __u32   ei_leaf_lo;
+       __u16   ei_leaf_hi;
+       __u16   ei_unused;
+};
+
+struct ext4_extent {
+       __u32   ee_block;
+       __u16   ee_len;
+       __u16   ee_start_hi;
+       __u32   ee_start_lo;
+};
+
+static struct ext4_extent_header *search_leaf(struct silo_ext2_state *s,
+                                             struct ext2_inode *ip,
+                                             unsigned long long file_block)
+{
+       struct ext4_extent_header *ehp;
+
+       ehp = (struct ext4_extent_header *) &ip->i_block[0];
+       for (;;) {
+               unsigned long long ext_block, hi, lo;
+               struct ext4_extent_idx *idxp;
+               int i;
+
+               idxp = (struct ext4_extent_idx *) (ehp + 1);
+
+               if (ext2_to_cpu_16(ehp->eh_magic) != EXT4_EXT_MAGIC)
+                       return (struct ext4_extent_header *) 0;
+
+               if (ehp->eh_depth == ext2_to_cpu_16(0))
+                       return ehp;
+
+               for (i = 0; i < ext2_to_cpu_16(ehp->eh_entries); i++, idxp++)
+                       if (file_block < ext2_to_cpu_32(idxp->ei_block))
+                               break;
+
+               if (i == 0)
+                       return (struct ext4_extent_header *) 0;
+
+               idxp -= 1;
+
+               hi = ((unsigned long long)ext2_to_cpu_16(idxp->ei_leaf_hi)) << 
32;
+               lo = ext2_to_cpu_32(idxp->ei_leaf_lo);
+               ext_block = hi | lo;
+
+               read_scratch_block(s, ext_block, 0);
+               ehp = (struct ext4_extent_header *) s->scratch_block[0];
+       }
+}
+
+#define BLOCK_MAP_ERROR (~0ULL)
+
+static int block_to_path(struct silo_ext2_state *s, struct ext2_inode *ip,
+                        int offsets[4], long file_block)
+{
+       int ptrs_bits = s->addr_per_block_bits;
+       int ptrs = s->addr_per_block;
+       const long direct_blocks = EXT2_NDIR_BLOCKS,
+               indirect_blocks = ptrs,
+               double_blocks = (1 << (ptrs_bits * 2));
+       int n = 0;
+
+       if (file_block < 0) {
+               printf("EXT2: Illegal file block %ld\n", file_block);
+       } else if (file_block < direct_blocks) {
+               offsets[n++] = file_block;
+       } else if ((file_block -= direct_blocks) < indirect_blocks) {
+               offsets[n++] = EXT2_IND_BLOCK;
+               offsets[n++] = file_block;
+       } else if ((file_block -= indirect_blocks) < double_blocks) {
+               offsets[n++] = EXT2_DIND_BLOCK;
+               offsets[n++] = file_block >> ptrs_bits;
+               offsets[n++] = file_block & (ptrs - 1);
+       } else if (((file_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) {
+               offsets[n++] = EXT2_TIND_BLOCK;
+               offsets[n++] = file_block >> (ptrs_bits * 2);
+               offsets[n++] = (file_block >> ptrs_bits) & (ptrs - 1);
+               offsets[n++] = file_block & (ptrs - 1);
+       } else {
+               printf("EXT2: File block %ld is too big\n", file_block);
+       }
+
+       return n;
+}
+
+static unsigned long long resolve_path(struct silo_ext2_state *s,
+                                      struct ext2_inode *ip,
+                                      int *offsets, int depth)
+{
+       __u32 *p = ip->i_block + *offsets;
+
+       while (--depth) {
+               __u32 block = ext2_to_cpu_32(*p);
+
+               read_scratch_block(s, block, depth);
+               p = (__u32 *) s->scratch_block[depth] + *++offsets;
+       }
+
+       return ext2_to_cpu_32(*p);
+}
+
+static unsigned long long resolve_extent(struct silo_ext2_state *s,
+                                        struct ext4_extent_header *ehp,
+                                        unsigned long long file_block)
+{
+       unsigned long long hi, lo;
+       struct ext4_extent *ep;
+       int i;
+
+       ep = (struct ext4_extent *) (ehp + 1);
+
+       for (i = 0; i < ext2_to_cpu_16(ehp->eh_entries); i++, ep++)
+               if (file_block < ext2_to_cpu_32(ep->ee_block))
+                       break;
+
+       if (i == 0)
+               return BLOCK_MAP_ERROR;
+
+       ep -= 1;
+       file_block -= ext2_to_cpu_32(ep->ee_block);
+       if (file_block >= ext2_to_cpu_16(ep->ee_len))
+               return BLOCK_MAP_ERROR;
 
-    return dump_finish ();
+       hi = ((unsigned long long)ext2_to_cpu_16(ep->ee_start_hi)) << 32;
+       lo = ext2_to_cpu_32(ep->ee_start_lo);
+
+       return (hi | lo) + file_block;
 }
 
-static int ls_ext2_proc(struct ext2_dir_entry *dirent, int offset,
-                       int blocksize, char *buf, void *private)
+static unsigned long long file_to_disk_block(struct silo_ext2_state *s,
+                                            struct ext2_inode *ip,
+                                            unsigned long long file_block)
 {
-    struct ext2_inode ino;
-    int sl = 0, name_len = dirent->name_len & 0xFF;
-    char name[256], symlink[256];
+       if (has_extents(ip)) {
+               struct ext4_extent_header *ehp = search_leaf(s, ip, file_block);
 
-    strncpy(name, dirent->name, name_len);
-    name[name_len] = 0;
+               if (ehp)
+                       return resolve_extent(s, ehp, file_block);
 
-    if (ext2fs_read_inode(fs, dirent->inode, &ino))
-       strcpy (name, "--- error ---");
+               printf("EXT2: Extent leaf search for block %d failed\n",
+                      (int) file_block);
 
-    if (LINUX_S_ISLNK (ino.i_mode)) {
-       sl = 1;
-       if (ext2fs_inode_data_blocks(fs, &ino)) {
-           if (io_channel_read_blk(fs->io, ino.i_block[0], 1, symlink))
-               ino.i_size = 0;
+               return BLOCK_MAP_ERROR;
        } else {
-           strncpy (symlink, (char *)&(ino.i_block[0]),ino.i_size);
+               int depth, offsets[4];
+
+               depth = block_to_path(s, ip, offsets, file_block);
+               if (depth)
+                       return resolve_path(s, ip, offsets, depth);
+
+               printf("EXT2: block --> path on block %d failed\n",
+                      (int) file_block);
+
+               return BLOCK_MAP_ERROR;
+       }
+}
+
+static void read_file(struct silo_ext2_state *s, struct ext2_inode *ip,
+                     __u32 off, __u32 len, void *buf)
+{
+       unsigned long long disk_block;
+
+       disk_block = file_to_disk_block(s, ip, off / s->block_size);
+
+       read_scratch_block(s, disk_block, 0);
+       memcpy(buf, s->scratch_block[0] + (off % s->block_size), len);
+}
+
+static void read_group(struct silo_ext2_state *s, __u32 grp_no,
+                      struct ext2_group_desc *grp)
+{
+       __u32 first = ext2_to_cpu_32(s->super->s_first_data_block);
+       __u32 blk, offset;
+
+       blk = first + 1 + (grp_no >> s->desc_per_block_bits);
+       offset = (grp_no & (s->desc_per_block - 1)) * sizeof(*grp);
+
+       read_data(s, blk, offset, sizeof(*grp), grp);
+}
+
+static void read_inode(struct silo_ext2_state *s, __u32 ino, struct ext2_inode 
*ip)
+{
+       __u32 grp_no, blk_no, inode_in_block, ipg, ipb;
+       struct ext2_super_block *sb = s->super;
+       struct ext2_group_desc gd;
+
+       ipg = ext2_to_cpu_32(sb->s_inodes_per_group);
+
+       grp_no = (ino - 1) / ipg;
+       read_group(s, grp_no, &gd);
+
+       blk_no = (ino - 1) % ipg;
+       inode_in_block = blk_no;
+
+       ipb = s->block_size / s->inode_size;
+       blk_no /= ipb;
+       inode_in_block %= ipb;
+
+       read_data(s,
+                 ext2_to_cpu_32(gd.bg_inode_table) + blk_no,
+                 inode_in_block * s->inode_size,
+                 sizeof(struct ext2_inode), ip);
+}
+
+static int calc_ilog2(__u32 n)
+{
+       int i = 0;
+
+       while ((n >>= 1) != 0)
+               i++;
+
+       return i;
+}
+
+static int open_ext2(char *device)
+{
+       struct silo_ext2_state *s = malloc(sizeof(*s));
+       struct ext2_super_block *sb;
+       int err, i;
+
+       if (!s) {
+               printf("Cannot allocate silo_ext2_state\n");
+               return 0;
+       }
+       memset(s, 0, sizeof(*s));
+
+       fs = malloc(sizeof(*fs));
+       if (!fs) {
+               printf("Cannot allocate ext2_filsys\n");
+               goto out_free_s;
+       }
+       memset(fs, 0, sizeof(*fs));
+       err = silo_io_manager->open(device, 0, &fs->io);
+       if (err) {
+               printf("I/O manager open failed (err=%d)\n", err);
+               goto out_free_fs;
+       }
+       fs->io->app_data = fs;
+
+       sb = s->super = malloc(1024);
+       if (!sb) {
+               printf("Cannot allocate ext2 super block\n");
+               goto out_free_fs;
+       }
+
+       io_channel_set_blksize(fs->io, 1024);
+       err = io_channel_read_blk(fs->io, 1, -1024, sb);
+
+       if (ext2_to_cpu_16(sb->s_magic) != EXT2_SUPER_MAGIC) {
+               printf("EXT2 superblock magic is wrong\n");
+               goto out_free_super;
+       }
+
+       s->inode_size = ext2_inode_size(s);
+       s->block_size = ext2_block_size(s);
+
+       io_channel_set_blksize(fs->io, s->block_size);
+
+       s->addr_per_block = s->block_size / sizeof(__u32);
+       s->addr_per_block_bits = calc_ilog2(s->addr_per_block);
+       s->desc_per_block = s->block_size / sizeof(struct ext2_group_desc);
+       s->desc_per_block_bits = calc_ilog2(s->desc_per_block);
+
+       s->scratch_block[0] = malloc(s->block_size * 4);
+       if (!s->scratch_block[0]) {
+               printf("Cannot allocate ext2 scratch blocks\n");
+               goto out_free_super;
+       }
+       for (i = 1; i < 4; i++)
+               s->scratch_block[i] =
+                       s->scratch_block[i - 1] + s->block_size;
+       for (i = 0; i < 4; i++)
+               s->scratch_block_blk[i] = ~(__u32)0;
+
+       root = EXT2_ROOT_INO;
+
+       sstate = s;
+
+       return 1;
+
+out_free_super:
+       free(s->super);
+
+out_free_fs:
+       free(fs);
+       fs = NULL;
+
+out_free_s:
+       free(s);
+       return 0;
+}
+
+void close_ext2 (void)
+{
+       struct silo_ext2_state *s = sstate;
+
+       if (s) {
+               free(s->scratch_block[0]);
+               free(s->super);
+               free(s);
+
+               sstate = (struct silo_ext2_state *) 0;
        }
-       symlink[ino.i_size] = 0;
-    }
+}
+
+static int dump_ext2 (void)
+{
+       struct silo_ext2_state *s = sstate;
+       struct ext2_inode ei;
+       long file_offset;
+       int sz, blk_sz;
+       int blk_cnt;
+
+       read_inode(s, inode, &ei);
+
+       sz = ext2_to_cpu_32(ei.i_size);
+       blk_sz = s->block_size;
+
+       blk_cnt = 0;
+       for (file_offset = 0; file_offset < sz; file_offset += blk_sz) {
+               blk_t disk_block;
+
+               disk_block = file_to_disk_block(s, &ei,
+                                               file_offset / blk_sz);
+               if (disk_block == BLOCK_MAP_ERROR)
+                       return 0;
+
+               if (disk_block)
+                       dump_block(&disk_block, blk_cnt);
+
+               blk_cnt++;
+       }
+
+       return dump_finish ();
+}
+
+static char *read_symlink(struct silo_ext2_state *s, struct ext2_inode *ip, 
char *namebuf)
+{
+       __u32 isize = ext2_to_cpu_32(ip->i_size);
+
+       if (isize <= 60)
+               return (char *) &ip->i_block[0];
+
+       read_data(s, ext2_to_cpu_32(ip->i_block[0]), 0, isize, namebuf);
+
+       return namebuf;
+}
+
+static int is_symlink(__u16 mode)
+{
+       if ((mode & 0xf000) == 0xa000)
+               return 1;
+       return 0;
+}
+
+typedef int (*dir_callback_t)(struct silo_ext2_state *, struct 
ext2_dir_entry_2 *, void *);
+
+static int ls_callback(struct silo_ext2_state *s, struct ext2_dir_entry_2 
*dirent, void *priv_data)
+{
+       struct ext2_inode e_ino;
+       char *sym = (char *) 0;
+       char symlink_buf[256];
+
+       read_inode(s, ext2_to_cpu_32(dirent->inode), &e_ino);
+
+       if (is_symlink(ext2_to_cpu_16(e_ino.i_mode)))
+               sym = read_symlink(s, &e_ino, symlink_buf);
+
+       register_silo_inode(ext2_to_cpu_32(e_ino.i_mtime),
+                           ext2_to_cpu_32(e_ino.i_size),
+                           ext2_to_cpu_16(e_ino.i_mode),
+                           ext2_to_cpu_16(e_ino.i_uid),
+                           ext2_to_cpu_16(e_ino.i_gid),
+                           dirent->name, sym);
+       return 0;
+}
+
+static void iterate_dir(struct silo_ext2_state *s, __u32 ino, dir_callback_t 
cb, void *cb_arg)
+{
+       struct ext2_dir_entry_2 e;
+       struct ext2_inode ei;
+       __u32 off, size;
 
-    register_silo_inode(ino.i_mtime, ino.i_size, ino.i_mode, ino.i_uid,
-                       ino.i_gid, name, sl ? symlink : NULL);
+       read_inode(s, ino, &ei);
+       size = ext2_to_cpu_32(ei.i_size);
 
-    return 0;
+       for (off = 0; off < size; ) {
+               read_file(s, &ei, off, 8, &e);
+
+               if (ext2_to_cpu_16(e.rec_len) == 0)
+                       break;
+
+               if (ext2_to_cpu_32(e.inode) == 0 ||
+                   e.name_len == 0) {
+                       off += ext2_to_cpu_16(e.rec_len);
+                       continue;
+               }
+
+               read_file(s, &ei, off + 8, e.name_len, &e.name[0]);
+               e.name[e.name_len] = 0;
+
+               if (cb(s, &e, cb_arg))
+                       break;
+
+               off += ext2_to_cpu_16(e.rec_len);
+       }
 }
 
 static int ls_ext2 (void)
 {
-    return ext2fs_dir_iterate (fs, inode, DIRENT_FLAG_INCLUDE_EMPTY,
-                                0, ls_ext2_proc, NULL);
+       struct silo_ext2_state *s = sstate;
+
+       iterate_dir(s, inode, ls_callback, 0);
+
+       return 0;
+}
+
+static int ino_size_ext2 (void)
+{
+       struct silo_ext2_state *s = sstate;
+       struct ext2_inode ei = { };
+
+       read_inode(s, inode, &ei);
+
+       return ext2_to_cpu_32(ei.i_size);
+}
+
+struct namei_cb_arg {
+       const char      *name;
+       int             len;
+       ino_t           *ino;
+       int             found;
+};
+
+static int lookup_cb(struct silo_ext2_state *s, struct ext2_dir_entry_2 
*dirent, void *priv_data)
+{
+       struct namei_cb_arg *p = priv_data;
+
+       if (p->len != dirent->name_len)
+               return 0;
+       if (strncmp(p->name, dirent->name, p->len))
+               return 0;
+       p->found = 1;
+       *p->ino = ext2_to_cpu_32(dirent->inode);
+       return 1;
 }
 
-static int ino_size_ext2 (void) {
-    struct ext2_inode ei;
-    int retval;
+static int do_lookup(struct silo_ext2_state *s, __u32 dir_ino, const char 
*name,
+                    int namelen, ino_t *ret_ino)
+{
+       struct namei_cb_arg arg;
+
+       arg.name = name;
+       arg.len = namelen;
+       arg.ino = ret_ino;
+       arg.found = 0;
+
+       iterate_dir(s, dir_ino, lookup_cb, &arg);
 
-    if ((retval = ext2fs_read_inode (fs, inode, &ei))) {
-       printf ("\n");
-       ext2fs_error (retval);
-       printf ("\n");
+       return arg.found ? 0 : -1;
+}
+
+static int open_namei(struct silo_ext2_state *s, const char *name,
+                     int namelen, ino_t root, ino_t base, ino_t *ret_ino);
+
+static int follow_link(struct silo_ext2_state *s, ino_t root, ino_t dir,
+                      ino_t inode, ino_t *res_inode)
+{
+       struct ext2_inode ei = { };
+       char symlink_buf[256];
+       char *sym;
+
+       read_inode(s, inode, &ei);
+       if (!is_symlink(ext2_to_cpu_16(ei.i_mode))) {
+               *res_inode = inode;
+               return 0;
+       }
+       sym = read_symlink(s, &ei, symlink_buf);
+       return open_namei(s, sym, ext2_to_cpu_32(ei.i_size), root, dir, 
res_inode);
+}
+
+static int dir_namei(struct silo_ext2_state *s, ino_t root, ino_t dir,
+                    const char *pathname, int pathlen,
+                    const char **name, int *namelen,
+                    ino_t *res_inode)
+{
+       const char *thisname;
+       int len, retval;
+       ino_t inode;
+       char c;
+
+       if ((c = *pathname) == '/') {
+               dir = root;
+               pathname++;
+               pathlen--;
+       }
+       while (1) {
+               thisname = pathname;
+               for (len = 0; --pathlen >= 0; len++) {
+                       c = *pathname++;
+                       if (c == '/')
+                               break;
+               }
+               if (pathlen < 0)
+                       break;
+               retval = do_lookup(s, dir, thisname, len, &inode);
+               if (retval)
+                       return retval;
+               retval = follow_link(s, root, dir, inode, &dir);
+               if (retval)
+                       return retval;
+       }
+       *name = thisname;
+       *namelen = len;
+       *res_inode = dir;
        return 0;
-    }
-    return ei.i_size;
 }
 
-static int namei_follow_ext2 (const char *filename) {
-    int ret = ext2fs_namei_follow (fs, root, root, filename, &inode);
+static int open_namei(struct silo_ext2_state *s, const char *name,
+                     int namelen, ino_t root, ino_t base, ino_t *ret_ino)
+{
+       const char *base_name;
+       ino_t dir_ino, inode;
+       int ret;
+
+       ret = dir_namei(s, root, base, name, namelen,
+                       &base_name, &namelen, &dir_ino);
+       if (ret)
+               return ret;
+
+       if (!namelen) {
+               *ret_ino = dir_ino;
+               return 0;
+       }
 
-    ext2_fs_ops.have_inode = (inode) ? 1 : 0;
+       ret = do_lookup(s, dir_ino, base_name, namelen, &inode);
+       if (ret)
+               return ret;
+
+       ret = follow_link(s, root, dir_ino, inode, &inode);
+       if (ret)
+               return ret;
 
-    return ret;
+       *ret_ino = inode;
+       return 0;
 }
 
-static void print_error_ext2 (int error_val) {
-    ext2fs_error (error_val);
+static int namei_follow_ext2 (const char *filename)
+{
+       int ret;
+
+       ret = open_namei(sstate, filename, strlen(filename),
+                        root, root, &inode);
+
+       ext2_fs_ops.have_inode = inode ? 1 : 0;
+
+       return ret;
 }
 
-void close_ext2 (void) {
-    ext2fs_close(fs);
+static void print_error_ext2 (int error_val)
+{
+       printf("error: %d", error_val);
 }
 
 struct fs_ops ext2_fs_ops = {
@@ -152,14 +689,3 @@
     .namei_follow      = namei_follow_ext2,
     .have_inode                = 0,
 };
-
-/* These are silly stubs to satisfy libext2fs symbols */
-unsigned long time(void)
-{
-        return 0;
-}
-
-void *realloc(void *p, int size)
-{
-        return NULL;
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/second/main.c new/silo/second/main.c
--- old/silo/second/main.c      2010-06-30 12:21:43.000000000 +0200
+++ new/silo/second/main.c      2013-07-07 21:19:00.000000000 +0200
@@ -64,6 +64,7 @@
     CMD_LS
 } load_cmd;
 enum arch architecture;
+int sun4v_cpu;
 static int timer_status = 0;
 static char *initrd_start;
 static int initrd_size;
@@ -85,6 +86,7 @@
 int tab_ambiguous = 0;
 int other_part = -1;
 int solaris = 0;
+int flash = 0;
 int other = 0;
 char *password = 0;
 int initrd_can_do_64bit_phys = 0;
@@ -536,6 +538,8 @@
                other = 1;
            else if (cfg_get_flag (label, "solaris"))
                solaris = 1;
+           else if (cfg_get_flag (label, "flash"))
+               flash = 1;
            p = cfg_get_strg (label, "literal");
            if (!p && other)
                p = cfg_get_strg (label, "append");
@@ -850,6 +854,11 @@
            }
        }
     }
+    if (!flash) {
+       p = strstr (*params, "flash");
+       if (p)
+           flash = 1;
+    }
     return 0;
 }
 
@@ -918,7 +927,27 @@
                           "ELF image");
                prom_halt ();
            }
-           if (solaris) {
+           if (flash) {
+               int i;
+
+               if (architecture != sun4u) {
+                   silo_fatal("Flash boots only supported on sun4u "
+                              "and later");
+                   prom_halt ();
+               }
+               for (i = 0; i < hp.e->e_phnum; i++, p++) {
+                   printf("SILO: Loading flash segment %d at vaddr[0x%x] 
len[0x%x]\n",
+                          i, p->p_vaddr, p->p_filesz);
+                   memcpy ((char *)p->p_vaddr,
+                           (base + p->p_offset), p->p_filesz);
+                   if (p->p_filesz < p->p_memsz)
+                       memset ((char *)(p->p_vaddr + p->p_filesz), 0,
+                               p->p_memsz - p->p_filesz);
+               }
+               isfile = 1;
+               st = hp.e->e_entry;
+               printf("SILO: Flash image entry is at vaddr[0x%x]\n", st);
+           } else if (solaris) {
                int i;
                unsigned long sa = (unsigned long)&_start;
 
@@ -976,7 +1005,28 @@
                           "ELF image");
                prom_halt ();
            }
-           if (solaris) {
+           if (flash) {
+               int i;
+
+               if (architecture != sun4u) {
+                   silo_fatal("Flash boots only supported on sun4u "
+                              "and later");
+                   prom_halt ();
+               }
+               for (i = 0; i < hp.f->e_phnum; i++, p++) {
+                   printf("SILO: Loading flash segment %d at vaddr[0x%x] 
len[0x%x]\n",
+                          i, (unsigned int) p->p_vaddr, (unsigned int) 
p->p_filesz);
+                   memcpy ((Elf64_Addr *)(long)(p->p_vaddr),
+                           (Elf64_Addr *)(long)(base + p->p_offset),
+                           p->p_filesz);
+                   if (p->p_filesz < p->p_memsz)
+                       memset ((Elf64_Addr *)(long)(p->p_vaddr + p->p_filesz),
+                               0, p->p_memsz - p->p_filesz);
+               }
+               isfile = 1;
+               st = hp.f->e_entry;
+               printf("SILO: Flash image entry is at vaddr[0x%x]\n", st);
+           } else if (solaris) {
                int i;
                unsigned long sa = (unsigned long)&_start;
 
@@ -1256,7 +1306,7 @@
     if (solaris) {
        params = params_device;
        params_device = sol_params;
-    } else if (!other) {
+    } else if (!other && !flash) {
        struct HdrS_struct *hdrs;
 
        params_device = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/second/misc.c new/silo/second/misc.c
--- old/silo/second/misc.c      2010-06-30 12:21:43.000000000 +0200
+++ new/silo/second/misc.c      2012-10-28 02:25:30.000000000 +0200
@@ -501,7 +501,7 @@
         if ((i = prom_searchsiblings(i, "MicroSPARC-IIep")) != 0) {
             return sun4p;
         }
-        return sun4u;
+       buffer[4] = 'u';
     }
     i = prom_getproperty (prom_root_node, "compatability", buffer, 8);
 
@@ -517,8 +517,10 @@
        return sun4d;
     case 'e':
        return sun4e;
-    case 'u':
     case 'v':
+       sun4v_cpu = 1;
+       /* FALLTHRU */
+    case 'u':
        return sun4u;
     default:
        for(i = 0; i < NUM_SUN_MACHINES; i++)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/silo/second/timer.c new/silo/second/timer.c
--- old/silo/second/timer.c     2010-06-30 12:21:43.000000000 +0200
+++ new/silo/second/timer.c     2012-10-28 02:25:30.000000000 +0200
@@ -156,7 +156,7 @@
     }
     if (!foundcpu || !clock_frequency)
         clock_frequency = prom_getint(prom_root_node, "clock-frequency") / 100;
-    if (notimer) {
+    if (notimer && !sun4v_cpu) {
         sun4u_notimer = 1;
         __asm__ __volatile__ ("\t"
                "rd     %%tick_cmpr, %%g1\n\t"

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to