a5bd9f6
From b4ec418af5d77275f3b3cf5e7566eaa4ecd713bd Mon Sep 17 00:00:00 2001
a5bd9f6
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
a5bd9f6
Date: Sat, 8 Dec 2012 20:56:58 +0100
a5bd9f6
Subject: [PATCH 056/364] 	Support big-endian UFS1.
a5bd9f6
a5bd9f6
	* Makefile.util.def (libgrubmods): Add ufs_be.c
a5bd9f6
	* grub-core/Makefile.core.def (ufs1_be): New module.
a5bd9f6
	* grub-core/fs/ufs_be.c: New file.
a5bd9f6
	* grub-core/fs/ufs.c: Declare grub_ufs_to_le* and use them throughout
a5bd9f6
	the file.
a5bd9f6
---
a5bd9f6
 ChangeLog                   | 10 ++++++
a5bd9f6
 Makefile.util.def           |  1 +
a5bd9f6
 grub-core/Makefile.core.def |  5 +++
a5bd9f6
 grub-core/fs/ufs.c          | 83 +++++++++++++++++++++++++++++----------------
a5bd9f6
 grub-core/fs/ufs_be.c       |  2 ++
a5bd9f6
 5 files changed, 72 insertions(+), 29 deletions(-)
a5bd9f6
 create mode 100644 grub-core/fs/ufs_be.c
a5bd9f6
a5bd9f6
diff --git a/ChangeLog b/ChangeLog
a5bd9f6
index b26bfcb..d565547 100644
a5bd9f6
--- a/ChangeLog
a5bd9f6
+++ b/ChangeLog
a5bd9f6
@@ -1,3 +1,13 @@
a5bd9f6
+2012-12-08  Vladimir Serbinenko  <phcoder@gmail.com>
a5bd9f6
+
a5bd9f6
+	Support big-endian UFS1.
a5bd9f6
+
a5bd9f6
+	* Makefile.util.def (libgrubmods): Add ufs_be.c
a5bd9f6
+	* grub-core/Makefile.core.def (ufs1_be): New module.
a5bd9f6
+	* grub-core/fs/ufs_be.c: New file.
a5bd9f6
+	* grub-core/fs/ufs.c: Declare grub_ufs_to_le* and use them throughout
a5bd9f6
+	the file.
a5bd9f6
+
a5bd9f6
 2012-11-28  Leif Lindholm  <leif.lindholm@arm.com>
a5bd9f6
 
a5bd9f6
         * include/grub/types.h: Fix functionality unaffecting typo in
a5bd9f6
diff --git a/Makefile.util.def b/Makefile.util.def
a5bd9f6
index 8324ede..01f7456 100644
a5bd9f6
--- a/Makefile.util.def
a5bd9f6
+++ b/Makefile.util.def
a5bd9f6
@@ -90,6 +90,7 @@ library = {
a5bd9f6
   common = grub-core/fs/udf.c;
a5bd9f6
   common = grub-core/fs/ufs2.c;
a5bd9f6
   common = grub-core/fs/ufs.c;
a5bd9f6
+  common = grub-core/fs/ufs_be.c;
a5bd9f6
   common = grub-core/fs/xfs.c;
a5bd9f6
   common = grub-core/fs/zfs/zfscrypt.c;
a5bd9f6
   common = grub-core/fs/zfs/zfs.c;
a5bd9f6
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
a5bd9f6
index 7a7b97a..6752429 100644
a5bd9f6
--- a/grub-core/Makefile.core.def
a5bd9f6
+++ b/grub-core/Makefile.core.def
a5bd9f6
@@ -1181,6 +1181,11 @@ module = {
a5bd9f6
 };
a5bd9f6
 
a5bd9f6
 module = {
a5bd9f6
+  name = ufs1_be;
a5bd9f6
+  common = fs/ufs_be.c;
a5bd9f6
+};
a5bd9f6
+
a5bd9f6
+module = {
a5bd9f6
   name = ufs2;
a5bd9f6
   common = fs/ufs2.c;
a5bd9f6
 };
a5bd9f6
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
a5bd9f6
index bd0cd1f..3f2dba1 100644
a5bd9f6
--- a/grub-core/fs/ufs.c
a5bd9f6
+++ b/grub-core/fs/ufs.c
a5bd9f6
@@ -49,18 +49,30 @@ GRUB_MOD_LICENSE ("GPLv3+");
a5bd9f6
 
a5bd9f6
 #define GRUB_UFS_VOLNAME_LEN	32
a5bd9f6
 
a5bd9f6
+#ifdef MODE_BIGENDIAN
a5bd9f6
+#define grub_ufs_to_cpu16 grub_be_to_cpu16
a5bd9f6
+#define grub_ufs_to_cpu32 grub_be_to_cpu32
a5bd9f6
+#define grub_ufs_to_cpu64 grub_be_to_cpu64
a5bd9f6
+#define grub_cpu_to_ufs32_compile_time grub_cpu_to_be32_compile_time
a5bd9f6
+#else
a5bd9f6
+#define grub_ufs_to_cpu16 grub_le_to_cpu16
a5bd9f6
+#define grub_ufs_to_cpu32 grub_le_to_cpu32
a5bd9f6
+#define grub_ufs_to_cpu64 grub_le_to_cpu64
a5bd9f6
+#define grub_cpu_to_ufs32_compile_time grub_cpu_to_le32_compile_time
a5bd9f6
+#endif
a5bd9f6
+
a5bd9f6
 /* Calculate in which group the inode can be found.  */
a5bd9f6
-#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize))
a5bd9f6
+#define UFS_BLKSZ(sblock) (grub_ufs_to_cpu32 (sblock->bsize))
a5bd9f6
 #define UFS_LOG_BLKSZ(sblock) (data->log2_blksz)
a5bd9f6
 
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
-#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits2 (data->inode.field)
a5bd9f6
+#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits2 (data->inode.field)
a5bd9f6
 #else
a5bd9f6
-#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits1 (data->inode.field)
a5bd9f6
+#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits1 (data->inode.field)
a5bd9f6
 #endif
a5bd9f6
 
a5bd9f6
-#define INODE_SIZE(data) grub_le_to_cpu64 (data->inode.size)
a5bd9f6
-#define INODE_MODE(data) grub_le_to_cpu16 (data->inode.mode)
a5bd9f6
+#define INODE_SIZE(data) grub_ufs_to_cpu64 (data->inode.size)
a5bd9f6
+#define INODE_MODE(data) grub_ufs_to_cpu16 (data->inode.mode)
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
 #define LOG_INODE_BLKSZ 3
a5bd9f6
 #else
a5bd9f6
@@ -234,7 +246,7 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk)
a5bd9f6
   if (blk < GRUB_UFS_DIRBLKS)
a5bd9f6
     return INODE_DIRBLOCKS (data, blk);
a5bd9f6
 
a5bd9f6
-  log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
a5bd9f6
+  log2_blksz = grub_ufs_to_cpu32 (data->sblock.log2_blksz);
a5bd9f6
 
a5bd9f6
   blk -= GRUB_UFS_DIRBLKS;
a5bd9f6
 
a5bd9f6
@@ -366,7 +378,7 @@ grub_ufs_read_file (struct grub_ufs_data *data,
a5bd9f6
 	{
a5bd9f6
 	  data->disk->read_hook = read_hook;
a5bd9f6
 	  grub_disk_read (data->disk,
a5bd9f6
-			  blknr << grub_le_to_cpu32 (data->sblock.log2_blksz),
a5bd9f6
+			  blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz),
a5bd9f6
 			  skipfirst, blockend, buf);
a5bd9f6
 	  data->disk->read_hook = 0;
a5bd9f6
 	  if (grub_errno)
a5bd9f6
@@ -389,17 +401,17 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
a5bd9f6
   struct grub_ufs_sblock *sblock = &data->sblock;
a5bd9f6
 
a5bd9f6
   /* Determine the group the inode is in.  */
a5bd9f6
-  int group = ino / grub_le_to_cpu32 (sblock->ino_per_group);
a5bd9f6
+  int group = ino / grub_ufs_to_cpu32 (sblock->ino_per_group);
a5bd9f6
 
a5bd9f6
   /* Determine the inode within the group.  */
a5bd9f6
-  int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group);
a5bd9f6
+  int grpino = ino % grub_ufs_to_cpu32 (sblock->ino_per_group);
a5bd9f6
 
a5bd9f6
   /* The first block of the group.  */
a5bd9f6
-  int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group));
a5bd9f6
+  int grpblk = group * (grub_ufs_to_cpu32 (sblock->frags_per_group));
a5bd9f6
 
a5bd9f6
 #ifndef MODE_UFS2
a5bd9f6
-  grpblk += grub_le_to_cpu32 (sblock->cylg_offset)
a5bd9f6
-    * (group & (~grub_le_to_cpu32 (sblock->cylg_mask)));
a5bd9f6
+  grpblk += grub_ufs_to_cpu32 (sblock->cylg_offset)
a5bd9f6
+    * (group & (~grub_ufs_to_cpu32 (sblock->cylg_mask)));
a5bd9f6
 #endif
a5bd9f6
 
a5bd9f6
   if (!inode)
a5bd9f6
@@ -409,8 +421,8 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
a5bd9f6
     }
a5bd9f6
 
a5bd9f6
   grub_disk_read (data->disk,
a5bd9f6
-		  ((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk)
a5bd9f6
-		   << grub_le_to_cpu32 (data->sblock.log2_blksz))
a5bd9f6
+		  ((grub_ufs_to_cpu32 (sblock->inoblk_offs) + grpblk)
a5bd9f6
+		   << grub_ufs_to_cpu32 (data->sblock.log2_blksz))
a5bd9f6
 		  + grpino / UFS_INODE_PER_BLOCK,
a5bd9f6
 		  (grpino % UFS_INODE_PER_BLOCK)
a5bd9f6
 		  * sizeof (struct grub_ufs_inode),
a5bd9f6
@@ -501,7 +513,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
       namelen = dirent.namelen_bsd;
a5bd9f6
 #else
a5bd9f6
-      namelen = grub_le_to_cpu16 (dirent.namelen);
a5bd9f6
+      namelen = grub_ufs_to_cpu16 (dirent.namelen);
a5bd9f6
 #endif
a5bd9f6
       {
a5bd9f6
 	char filename[namelen + 1];
a5bd9f6
@@ -515,7 +527,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
a5bd9f6
 	if (!grub_strcmp (name, filename))
a5bd9f6
 	  {
a5bd9f6
 	    dirino = data->ino;
a5bd9f6
-	    grub_ufs_read_inode (data, grub_le_to_cpu32 (dirent.ino), 0);
a5bd9f6
+	    grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino), 0);
a5bd9f6
 
a5bd9f6
 	    if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE)
a5bd9f6
 		== GRUB_UFS_ATTR_LNK)
a5bd9f6
@@ -547,7 +559,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path)
a5bd9f6
 	  }
a5bd9f6
       }
a5bd9f6
 
a5bd9f6
-      pos += grub_le_to_cpu16 (dirent.direntlen);
a5bd9f6
+      pos += grub_ufs_to_cpu16 (dirent.direntlen);
a5bd9f6
     } while (pos < INODE_SIZE (data));
a5bd9f6
 
a5bd9f6
   grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
a5bd9f6
@@ -576,12 +588,12 @@ grub_ufs_mount (grub_disk_t disk)
a5bd9f6
 
a5bd9f6
       /* No need to byteswap bsize in this check. It works the same on both
a5bd9f6
 	 endiannesses.  */
a5bd9f6
-      if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC
a5bd9f6
+      if (data->sblock.magic == grub_cpu_to_ufs32_compile_time (GRUB_UFS_MAGIC)
a5bd9f6
 	  && data->sblock.bsize != 0
a5bd9f6
 	  && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0))
a5bd9f6
 	{
a5bd9f6
 	  for (data->log2_blksz = 0; 
a5bd9f6
-	       (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sblock.bsize);
a5bd9f6
+	       (1U << data->log2_blksz) < grub_ufs_to_cpu32 (data->sblock.bsize);
a5bd9f6
 	       data->log2_blksz++);
a5bd9f6
 
a5bd9f6
 	  data->disk = disk;
a5bd9f6
@@ -652,7 +664,7 @@ grub_ufs_dir (grub_device_t device, const char *path,
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
       namelen = dirent.namelen_bsd;
a5bd9f6
 #else
a5bd9f6
-      namelen = grub_le_to_cpu16 (dirent.namelen);
a5bd9f6
+      namelen = grub_ufs_to_cpu16 (dirent.namelen);
a5bd9f6
 #endif
a5bd9f6
 
a5bd9f6
       {
a5bd9f6
@@ -667,18 +679,19 @@ grub_ufs_dir (grub_device_t device, const char *path,
a5bd9f6
 	  break;
a5bd9f6
 
a5bd9f6
 	filename[namelen] = '\0';
a5bd9f6
-	grub_ufs_read_inode (data, dirent.ino, (char *) &inode;;
a5bd9f6
+	grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino),
a5bd9f6
+			     (char *) &inode;;
a5bd9f6
 
a5bd9f6
-	info.dir = ((grub_le_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE)
a5bd9f6
+	info.dir = ((grub_ufs_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE)
a5bd9f6
 		    == GRUB_UFS_ATTR_DIR);
a5bd9f6
-	info.mtime = grub_le_to_cpu64 (inode.mtime);
a5bd9f6
+	info.mtime = grub_ufs_to_cpu64 (inode.mtime);
a5bd9f6
 	info.mtimeset = 1;
a5bd9f6
 
a5bd9f6
 	if (hook (filename, &info))
a5bd9f6
 	  break;
a5bd9f6
       }
a5bd9f6
 
a5bd9f6
-      pos += grub_le_to_cpu16 (dirent.direntlen);
a5bd9f6
+      pos += grub_ufs_to_cpu16 (dirent.direntlen);
a5bd9f6
     }
a5bd9f6
 
a5bd9f6
  fail:
a5bd9f6
@@ -773,8 +786,8 @@ grub_ufs_uuid (grub_device_t device, char **uuid)
a5bd9f6
   data = grub_ufs_mount (disk);
a5bd9f6
   if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0))
a5bd9f6
     *uuid = grub_xasprintf ("%08x%08x",
a5bd9f6
-			   (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi),
a5bd9f6
-			   (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow));
a5bd9f6
+			   (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidhi),
a5bd9f6
+			   (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidlow));
a5bd9f6
   else
a5bd9f6
     *uuid = NULL;
a5bd9f6
 
a5bd9f6
@@ -799,10 +812,10 @@ grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
a5bd9f6
     *tm = 0;
a5bd9f6
   else
a5bd9f6
     {
a5bd9f6
-      *tm = grub_le_to_cpu32 (data->sblock.mtime);
a5bd9f6
+      *tm = grub_ufs_to_cpu32 (data->sblock.mtime);
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
-      if (*tm < (grub_int64_t) grub_le_to_cpu64 (data->sblock.mtime2))
a5bd9f6
-	*tm = grub_le_to_cpu64 (data->sblock.mtime2);
a5bd9f6
+      if (*tm < (grub_int64_t) grub_ufs_to_cpu64 (data->sblock.mtime2))
a5bd9f6
+	*tm = grub_ufs_to_cpu64 (data->sblock.mtime2);
a5bd9f6
 #endif
a5bd9f6
     }
a5bd9f6
 
a5bd9f6
@@ -820,8 +833,12 @@ static struct grub_fs grub_ufs_fs =
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
     .name = "ufs2",
a5bd9f6
 #else
a5bd9f6
+#ifdef MODE_BIGENDIAN
a5bd9f6
+    .name = "ufs1_be",
a5bd9f6
+#else
a5bd9f6
     .name = "ufs1",
a5bd9f6
 #endif
a5bd9f6
+#endif
a5bd9f6
     .dir = grub_ufs_dir,
a5bd9f6
     .open = grub_ufs_open,
a5bd9f6
     .read = grub_ufs_read,
a5bd9f6
@@ -839,8 +856,12 @@ static struct grub_fs grub_ufs_fs =
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
 GRUB_MOD_INIT(ufs2)
a5bd9f6
 #else
a5bd9f6
+#ifdef MODE_BIGENDIAN
a5bd9f6
+GRUB_MOD_INIT(ufs1_be)
a5bd9f6
+#else
a5bd9f6
 GRUB_MOD_INIT(ufs1)
a5bd9f6
 #endif
a5bd9f6
+#endif
a5bd9f6
 {
a5bd9f6
   grub_fs_register (&grub_ufs_fs);
a5bd9f6
   my_mod = mod;
a5bd9f6
@@ -849,8 +870,12 @@ GRUB_MOD_INIT(ufs1)
a5bd9f6
 #ifdef MODE_UFS2
a5bd9f6
 GRUB_MOD_FINI(ufs2)
a5bd9f6
 #else
a5bd9f6
+#ifdef MODE_BIGENDIAN
a5bd9f6
+GRUB_MOD_FINI(ufs1_be)
a5bd9f6
+#else
a5bd9f6
 GRUB_MOD_FINI(ufs1)
a5bd9f6
 #endif
a5bd9f6
+#endif
a5bd9f6
 {
a5bd9f6
   grub_fs_unregister (&grub_ufs_fs);
a5bd9f6
 }
a5bd9f6
diff --git a/grub-core/fs/ufs_be.c b/grub-core/fs/ufs_be.c
a5bd9f6
new file mode 100644
a5bd9f6
index 0000000..a58f75a
a5bd9f6
--- /dev/null
a5bd9f6
+++ b/grub-core/fs/ufs_be.c
a5bd9f6
@@ -0,0 +1,2 @@
a5bd9f6
+#define MODE_BIGENDIAN 1
a5bd9f6
+#include "ufs.c"
a5bd9f6
-- 
a5bd9f6
1.8.1.4
a5bd9f6