diff --git a/configure b/configure
index 438219b..045a4ef 100755
--- a/configure
+++ b/configure
@@ -1011,6 +1011,7 @@ cris-linux-user \
 m68k-linux-user \
 microblaze-linux-user \
 mips-linux-user \
+mips64-linux-user \
 mipsel-linux-user \
 ppc-linux-user \
 ppc64-linux-user \
diff --git a/default-configs/mips64-linux-user.mak
b/default-configs/mips64-linux-user.mak
new file mode 100644
index 0000000..1598bfc
--- /dev/null
+++ b/default-configs/mips64-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for mips64-linux-user
diff --git a/exec.c b/exec.c
index 49c28b1..ee3f78e 100644
--- a/exec.c
+++ b/exec.c
@@ -2441,6 +2441,7 @@ int page_check_range(target_ulong start, target_ulong
len, int flags)
     for (addr = start, len = end - start;
          len != 0;
          len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
+        addr  &= qemu_host_page_mask;
         p = page_find(addr >> TARGET_PAGE_BITS);
         if( !p )
             return -1;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 33d776d..60fe85e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -16,6 +16,8 @@
 #include "qemu.h"
 #include "disas.h"

+extern int TARGET_OCTEON;
+
 #ifdef _ARCH_PPC64
 #undef ARCH_DLINFO
 #undef ELF_PLATFORM
@@ -25,6 +27,9 @@
 #undef ELF_ARCH
 #endif

+#define EF_MIPS_MARCH 16711680
+#define E_MIPS_MACH_OCTEON 9109504
+
 #define ELF_OSABI   ELFOSABI_SYSV

 /* from personality.h */
@@ -1313,7 +1318,7 @@ static void load_elf_image(const char *image_name, int
image_fd,
             vaddr_po = TARGET_ELF_PAGEOFFSET(vaddr);
             vaddr_ps = TARGET_ELF_PAGESTART(vaddr);

-            error = target_mmap(vaddr_ps, eppnt->p_filesz + vaddr_po,
+            error = target_mmap(vaddr_ps, eppnt->p_memsz + vaddr_po,
                                 elf_prot, MAP_PRIVATE | MAP_FIXED,
                                 image_fd, eppnt->p_offset - vaddr_po);
             if (error == -1) {
@@ -1588,7 +1593,13 @@ int load_elf_binary(struct linux_binprm * bprm,
struct target_pt_regs * regs,
        If we do nothing, we'll have overwritten this when we re-use
bprm->buf
        when we load the interpreter.  */
     elf_ex = *(struct elfhdr *)bprm->buf;
-
+#if defined(TARGET_MIPS64)
+    if ((elf_ex.e_flags & EF_MIPS_MARCH) == E_MIPS_MACH_OCTEON) {
+        TARGET_OCTEON = 1;
+    } else {
+        TARGET_OCTEON = 0;
+    }
+#endif
     bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p);
     bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p);
     bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p);
diff --git a/linux-user/main.c b/linux-user/main.c
index 0d627d6..8b4b90b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1937,10 +1937,16 @@ static int do_store_exclusive(CPUMIPSState *env)
     int d;

     addr = env->lladdr;
+    /* 64 bit address is converted to 32 bit value so that a valid
+    * l1_map value can be accessed. This thing is needed for target
+    * mips64 and host 32 bit x86
+    */
+    addr &= qemu_host_page_mask;
     page_addr = addr & TARGET_PAGE_MASK;
     start_exclusive();
     mmap_lock();
     flags = page_get_flags(page_addr);
+    addr = env->lladdr;
     if ((flags & PAGE_READ) == 0) {
         segv = 1;
     } else {
@@ -1978,7 +1984,8 @@ static int do_store_exclusive(CPUMIPSState *env)
 void cpu_loop(CPUMIPSState *env)
 {
     target_siginfo_t info;
-    int trapnr, ret;
+    int trapnr;
+    abi_long ret;
     unsigned int syscall_num;

     for(;;) {
@@ -1987,7 +1994,11 @@ void cpu_loop(CPUMIPSState *env)
         cpu_exec_end(env);
         switch(trapnr) {
         case EXCP_SYSCALL:
+#if defined(TARGET_MIPS64)
+            syscall_num = env->active_tc.gpr[2] - 5000;
+#else
             syscall_num = env->active_tc.gpr[2] - 4000;
+#endif
             env->active_tc.PC += 4;
             if (syscall_num >= sizeof(mips_syscall_args)) {
                 ret = -ENOSYS;
@@ -2013,7 +2024,8 @@ void cpu_loop(CPUMIPSState *env)
                                  env->active_tc.gpr[5],
                                  env->active_tc.gpr[6],
                                  env->active_tc.gpr[7],
-                                 arg5, arg6/*, arg7, arg8*/);
+                                 env->active_tc.gpr[8],
+                                 env->active_tc.gpr[9]/*, arg7, arg8*/);
             }
             if (ret == -TARGET_QEMU_ESIGRETURN) {
                 /* Returning from a successful sigreturn syscall.
@@ -2926,7 +2938,9 @@ int main(int argc, char **argv, char **envp)
 #endif
 #elif defined(TARGET_MIPS)
 #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
-        cpu_model = "20Kc";
+        /* we use this model so that we can decode MIPS64r2
+           reserved instruction */
+        cpu_model = "MIPS64R2-generic";
 #else
         cpu_model = "24Kf";
 #endif
diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h
index 668a2b9..1395e61 100644
--- a/linux-user/mips64/syscall.h
+++ b/linux-user/mips64/syscall.h
@@ -217,5 +217,7 @@ struct target_pt_regs {
 #define TARGET_ENOTRECOVERABLE 166     /* State not recoverable */


+/* Nasty hack: define a fake errno value for use by sigreturn.  */
+#define TARGET_QEMU_ESIGRETURN 255

 #define UNAME_MACHINE "mips64"
diff --git a/linux-user/signal.c b/linux-user/signal.c
index c846b8c..114116c 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2410,7 +2410,8 @@ void sparc64_get_context(CPUSPARCState *env)
 #endif
 #elif defined(TARGET_ABI_MIPSN64)

-# warning signal handling not implemented
+/*this line is commented out to avoid compile time error*/
+/*# warning signal handling not implemented*/

 static void setup_frame(int sig, struct target_sigaction *ka,
  target_sigset_t *set, CPUState *env)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 499c4d7..47fef05 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7195,6 +7195,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long
arg1,
     case TARGET_NR_set_thread_area:
 #if defined(TARGET_MIPS)
       ((CPUMIPSState *) cpu_env)->tls_value = arg1;
+       /*tls entry is moved to k0 so that this can be used later*/
+      ((CPUMIPSState *) cpu_env)->active_tc.gpr[26] = arg1;
       ret = 0;
       break;
 #elif defined(TARGET_CRIS)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 2419aa9..59bcc0f 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -140,6 +140,20 @@ typedef struct mips_def_t mips_def_t;
 #define MIPS_FPU_MAX 1
 #define MIPS_DSP_ACC 4

+typedef struct cavium_mul cavium_mul;
+struct cavium_mul {
+ target_ulong MPL0;
+ target_ulong MPL1;
+ target_ulong MPL2;
+ target_ulong P0;
+ target_ulong P1;
+ target_ulong P2;
+};
+typedef struct cvmctl_register cvmctl_register;
+struct cvmctl_register {
+ target_ulong cvmctl;
+};
+
 typedef struct TCState TCState;
 struct TCState {
     target_ulong gpr[32];
@@ -178,6 +192,8 @@ struct CPUMIPSState {
     TCState active_tc;
     CPUMIPSFPUContext active_fpu;

+    cavium_mul Reg;
+    cvmctl_register CvmCtlRegister;
     uint32_t current_tc;
     uint32_t current_fpu;

diff --git a/target-mips/translate.c b/target-mips/translate.c
index cce77be..9c3d772 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -36,6 +36,15 @@
 #define GEN_HELPER 1
 #include "helper.h"

+int TARGET_OCTEON;
+#if defined(TARGET_MIPS64)
+/*Macros for setting values of cvmctl registers*/
+#define FUSE_START_BIT(cvmctl)(cvmctl | 0x80000000)
+#define KASUMI(cvmctl)(cvmctl | 0x20000000)
+#define IPPCI(cvmctl)(cvmctl | 0x380)
+#define IPTI(cvmctl)(cvmctl | 0x70)
+#endif
+
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS

@@ -70,6 +79,11 @@ enum {
     OPC_JAL      = (0x03 << 26),
     OPC_JALS     = OPC_JAL | 0x5,
     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
+    /* Cavium Specific */
+    OPC_BBIT1    = (0x3a << 26),  /*jump on bit set, cavium specific*/
+    OPC_BBIT132  = (0x3e << 26),  /*jump on bit set(one of the upper 32
bits)*/
+    OPC_BBIT0    = (0x32 << 26),  /*jump on bit clear, cavium specific*/
+    OPC_BBIT032  = (0x36 << 26),  /*jump on bit set(one of the upper 32
bits)*/
     OPC_BEQL     = (0x14 << 26),
