diff -ur arcboot-0.3.6/common/subarch.h arcboot-0.3.6-elf64/common/subarch.h
--- arcboot-0.3.6/common/subarch.h	2003-04-26 16:45:36.000000000 -0700
+++ arcboot-0.3.6-elf64/common/subarch.h	2004-02-01 00:48:30.000000000 -0800
@@ -12,6 +12,7 @@
 
 /* supported subarches */
 #define IP22 	0
+#define IP32 	1
 
 /*
  *  Reserve this memory for loading kernel
@@ -31,6 +32,10 @@
 	.base =   0x88002000,
 	.reserved = 0x800000,
 	},
+	{ /* IP32 */
+	.base     = 0x80002000,
+	.reserved = 0x800000,
+	},
 };
 
 /* we filter these out of the command line */
diff -ur arcboot-0.3.6/ext2load/Makefile arcboot-0.3.6-elf64/ext2load/Makefile
--- arcboot-0.3.6/ext2load/Makefile	2003-04-26 16:39:07.000000000 -0700
+++ arcboot-0.3.6-elf64/ext2load/Makefile	2004-01-31 15:33:00.000000000 -0800
@@ -40,4 +40,4 @@
 	sed -e "s/@@LOADADDR@@/$$LOADADDR/" <$< >$@
 
 clean:
-	rm -f $(TARGETS) *.a *.o tags
+	rm -f $(TARGETS) *.a *.o tags ld.script
diff -ur arcboot-0.3.6/ext2load/loader.c arcboot-0.3.6-elf64/ext2load/loader.c
--- arcboot-0.3.6/ext2load/loader.c	2003-04-26 17:01:00.000000000 -0700
+++ arcboot-0.3.6-elf64/ext2load/loader.c	2004-02-01 00:51:19.000000000 -0800
@@ -27,6 +27,14 @@
 CHAR *OSLoadPartition = NULL;
 CHAR *OSLoadFilename = NULL;
 CHAR *OSLoadOptions = NULL;
+static int is64=0;
+
+
+typedef	union {
+	unsigned char e_ident[EI_NIDENT];
+	Elf32_Ehdr header32;
+	Elf64_Ehdr header64;
+} Elf_Ehdr;
 
 static void Wait(const char *prompt)
 {
@@ -170,23 +178,39 @@
 }
 
 
-void LoadProgramSegments(ext2_file_t file, Elf32_Ehdr * header)
+void LoadProgramSegments(ext2_file_t file, Elf_Ehdr * header)
 {
 	int idx;
 	Boolean loaded = False;
-	Elf32_Phdr *segment, *segments;
-	size_t size = header->e_phentsize * header->e_phnum;
+	void *segments;
+	size_t size;
 	errcode_t status;
 
+	if (header->e_ident[EI_CLASS] == ELFCLASS32)
+		size = (size_t) (header->header32.e_phentsize *
+				 header->header32.e_phnum);
+	else
+		size = (size_t) (header->header64.e_phentsize *
+				 header->header64.e_phnum);
+
 	if (size <= 0)
 		Fatal("No program segments\n\r");
 
 	segments = malloc(size);
 	if (segments == NULL)
 		Fatal("Cannot allocate memory for segment headers\n\r");
+	else
+		printf("Allocated 0x%x bytes for segments\n\r",size);
 
-	status =
-	    ext2fs_file_lseek(file, header->e_phoff, EXT2_SEEK_SET, NULL);
+	if (header->e_ident[EI_CLASS] == ELFCLASS32) {
+		status = ext2fs_file_lseek(file,
+				(ext2_off_t) header->header32.e_phoff,
+				EXT2_SEEK_SET, NULL);
+	} else {
+		status = ext2fs_file_lseek(file,
+				(ext2_off_t) header->header64.e_phoff,
+				EXT2_SEEK_SET, NULL);
+	}
 	if (status != 0) {
 		print_ext2fs_error(status);
 		Fatal("Cannot seek to program segment headers\n\r");
@@ -198,48 +222,98 @@
 		Fatal("Cannot read program segment headers\n\r");
 	}
 
-	segment = segments;
-	for (idx = 0; idx < header->e_phnum; idx++) {
-		if (segment->p_type == PT_LOAD) {
-			printf
-			    ("Loading program segment %u at 0x%x, size = 0x%x\n\r",
-			     idx + 1, KSEG0ADDR(segment->p_vaddr),
-			     segment->p_filesz);
-
-			status =
-			    ext2fs_file_lseek(file, segment->p_offset,
-					      EXT2_SEEK_SET, NULL);
-			if (status != 0) {
+	if(header->e_ident[EI_CLASS] == ELFCLASS32) {
+	    Elf32_Phdr* segment=(Elf32_Phdr*)segments;
+	    printf("Loading 32-bit executable\n\r");
+	    for (idx = 0; idx < header->header32.e_phnum; idx++) {
+		    if (segment->p_type == PT_LOAD) {
+			    printf
+				("Loading program segment %u at 0x%x, offset=0x%x, size = 0x%x\n\r",
+			        idx + 1, KSEG0ADDR(segment->p_vaddr),
+			        segment->p_offset, segment->p_filesz);
+
+			    status =
+				ext2fs_file_lseek(file, segment->p_offset,
+					        EXT2_SEEK_SET, NULL);
+			    if (status != 0) {
+				    print_ext2fs_error(status);
+				    Fatal("Cannot seek to program segment\n\r");
+			    }
+
+			    status = ext2fs_file_read(file,
+						  (void *) (KSEG0ADDR(
+						            segment->p_vaddr)),
+						  segment->p_filesz, NULL);
+			    if (status != 0) {
 				print_ext2fs_error(status);
-				Fatal("Cannot seek to program segment\n\r");
-			}
+				Fatal("Cannot read program segment\n\r");
+			    }
+
+			    size = segment->p_memsz - segment->p_filesz;
+			    if (size > 0) {
+				    printf
+					("Zeroing memory at 0x%x, size = 0x%x\n\r",
+				        (KSEG0ADDR(segment->p_vaddr +
+				        segment->p_filesz)), size);
+				    memset((void *)
+				       (KSEG0ADDR(segment->
+					 p_vaddr + segment->p_filesz)), 0, size);
+			    }
+
+			    loaded = True;
+		    }
+
+		    segment =
+			(Elf32_Phdr *) (((char *) segment) +
+				    header->header32.e_phentsize);
+	    }
+	} else {
+	    Elf64_Phdr* segment=(Elf64_Phdr*)segments;
+	    is64=1;
+	    printf("Loading 64-bit executable\n\r");
+	    for (idx = 0; idx < header->header64.e_phnum; idx++) {
+		    if (segment->p_type == PT_LOAD) {
+			    printf
+				("Loading program segment %u at 0x%x, offset=0x%lx %lx, size = 0x%lx %lx\n\r",
+			        idx + 1, KSEG0ADDR(segment->p_vaddr),
+			        (long)(segment->p_offset>>32),(long)(segment->p_offset&0xffffffff),
+				 (long)(segment->p_filesz>>32),(long)(segment->p_filesz&0xffffffff));
+
+			    status =
+				ext2fs_file_lseek(file, segment->p_offset,
+					        EXT2_SEEK_SET, NULL);
+			    if (status != 0) {
+				    print_ext2fs_error(status);
+				    Fatal("Cannot seek to program segment\n\r");
+			    }
 
-			status = ext2fs_file_read(file,
+			    status = ext2fs_file_read(file,
 						  (void *) (KSEG0ADDR(
 						            segment->p_vaddr)),
 						  segment->p_filesz, NULL);
-			if (status != 0) {
+			    if (status != 0) {
 				print_ext2fs_error(status);
 				Fatal("Cannot read program segment\n\r");
-			}
+			    }
 
-			size = segment->p_memsz - segment->p_filesz;
-			if (size > 0) {
-				printf
-				    ("Zeroing memory at 0x%x, size = 0x%x\n\r",
-				     (KSEG0ADDR(segment->p_vaddr +
-				      segment->p_filesz)), size);
-				memset((void *)
+			    size = segment->p_memsz - segment->p_filesz;
+			    if (size > 0) {
+				    printf
+					("Zeroing memory at 0x%x, size = 0x%x\n\r",
+				        (KSEG0ADDR(segment->p_vaddr +
+				        segment->p_filesz)), size);
+				    memset((void *)
 				       (KSEG0ADDR(segment->
 					 p_vaddr + segment->p_filesz)), 0, size);
-			}
+			    }
 
-			loaded = True;
-		}
+			    loaded = True;
+		    }
 
-		segment =
-		    (Elf32_Phdr *) (((char *) segment) +
-				    header->e_phentsize);
+		    segment =
+			(Elf64_Phdr *) (((char *) segment) +
+				    header->header64.e_phentsize);
+	    }
 	}
 
 	if (!loaded)
@@ -249,9 +323,10 @@
 }
 
 
-ULONG LoadKernelFile(ext2_file_t file)
+Elf64_Addr LoadKernelFile(ext2_file_t file)
 {
-	Elf32_Ehdr header;
+	Elf_Ehdr header;
+	Elf64_Addr entry;
 	errcode_t status;
 
 	status =
@@ -264,8 +339,9 @@
 	if (memcmp(&(header.e_ident[EI_MAG0]), ELFMAG, SELFMAG) != 0)
 		Fatal("Not an ELF file\n\r");
 
-	if (header.e_ident[EI_CLASS] != ELFCLASS32)
-		Fatal("Not a 32-bit file\n\r");
+	if (header.e_ident[EI_CLASS] != ELFCLASS32 &&
+	    header.e_ident[EI_CLASS] != ELFCLASS64)
+		Fatal("Not a 32-bit or 64-bit file\n\r");
 
 	if (header.e_ident[EI_DATA] != ELFDATA2MSB)
 		Fatal("Not a big-endian file\n\r");
@@ -273,20 +349,33 @@
 	if (header.e_ident[EI_VERSION] != EV_CURRENT)
 		Fatal("Wrong ELF version\n\r");
 
-	if (header.e_type != ET_EXEC)
+	if (header.e_ident[EI_CLASS]==ELFCLASS32) {
+	    if (header.header32.e_type != ET_EXEC)
+		Fatal("Not an executable file\n\r");
+
+	    if (header.header32.e_machine != EM_MIPS)
+		Fatal("Unsupported machine type\n\r");
+
+	    if (header.header32.e_version != EV_CURRENT)
+		Fatal("Wrong ELF version\n\r");
+
+ 	    entry = (Elf64_Addr) header.header32.e_entry;
+	} else {
+	    if (header.header64.e_type != ET_EXEC)
 		Fatal("Not an executable file\n\r");
 
-	if (header.e_machine != EM_MIPS)
+	    if (header.header64.e_machine != EM_MIPS)
 		Fatal("Unsupported machine type\n\r");
 
-	if (header.e_version != EV_CURRENT)
+	    if (header.header64.e_version != EV_CURRENT)
 		Fatal("Wrong ELF version\n\r");
 
+ 	    entry = header.header64.e_entry;
+	}
+
 	LoadProgramSegments(file, &header);
 
-	printf("Starting kernel; entry point = 0x%lx\n\r",
-	       ((ULONG) KSEG0ADDR(header.e_entry)));
-	return KSEG0ADDR(header.e_entry);
+	return entry;
 }
 
 
@@ -320,7 +409,7 @@
 	return True;
 }
 
-ULONG LoadKernel(const char *partition, const char *filename)
+Elf64_Addr LoadKernel(const char *partition, const char *filename)
 {
 	ext2_file_t file;
 
@@ -337,12 +426,26 @@
 	printf("%u: %s\n\r", i, argv[i]);
 }
 
+void _start64(LONG argc, CHAR * argv[], CHAR * envp[],
+	      unsigned long long *addr)
+{
+	asm volatile (".set mips4\n"
+		      "\t.set noreorder\n"
+		      "\tld $2, 0($7)\n"
+		      "\tj $2\n"
+		      "\tnop\n"
+		      "\t.set noreorder\n"
+		      "\t.set mips0");
+}
+
 void _start(LONG argc, CHAR *argv[], CHAR *envp[])
 {
 	CHAR** nargv;
 	CHAR** params;
 	int nargc, nopt;
-	void (*kernel_entry)(int argc, CHAR * argv[], CHAR * envp[]);
+
+	Elf32_Addr kernel_entry32;
+	Elf64_Addr kernel_entry64;
 
 	/* Print identification */
 	printf(ANSI_CLEAR "\n\rarcsboot: ARCS Linux ext2fs loader "
@@ -393,17 +496,29 @@
 		}
 	}
 	printf("Loading %s from %s\n\r",(params) ? params[0] : OSLoadFilename, OSLoadPartition);
-	kernel_entry = LoadKernel(OSLoadPartition, OSLoadFilename);
+	kernel_entry64 = LoadKernel(OSLoadPartition, OSLoadFilename);
+	kernel_entry32 = (Elf32_Addr) kernel_entry64;
 #if DEBUG
 	printf("Command line after config file: \n\r");
 	printCmdLine(nargc, nargv);
+	printf("Kernel entry: 0x%lx %lx\n\r",
+		(long)(kernel_entry64>>32),(long)(kernel_entry64&0xffffffff));
 	Wait("\n\r--- Debug: press <spacebar> to boot kernel ---");
 #endif
-	ArcFlushAllCaches();
-	if( kernel_entry )
-		(*kernel_entry)(nargc ,nargv, envp);
-	else
+	if( kernel_entry64 ) {
+	    if(is64==0){
+		printf("Starting 32-bit kernel\n\r");
+		ArcFlushAllCaches();
+		((void (*)(int argc, CHAR * argv[], CHAR * envp[]))
+		    kernel_entry32)(nargc ,nargv, envp);
+	    } else {
+		printf("Starting 64-bit kernel\n\r");
+		ArcFlushAllCaches();
+		_start64(nargc ,nargv, envp, &kernel_entry64);
+	    }
+	} else {
 		printf("Invalid kernel entry NULL\n\r");
+	}
 
 	/* Not likely to get back here in a functional state, but what the heck */
 	Wait("\n\r--- Press <spacebar> to restart ---");

