Index: boot/arch/ia64/loader/Makefile
===================================================================
--- boot/arch/ia64/loader/Makefile	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/Makefile	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -89,4 +89,6 @@
 
 COMPONENTS = \
+	$(KERNELDIR)/kernel.bin 
+NOCOMPONENTS = \
 	$(KERNELDIR)/kernel.bin \
 	$(USPACEDIR)/srv/ns/ns \
Index: boot/arch/ia64/loader/asm.S
===================================================================
--- boot/arch/ia64/loader/asm.S	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/asm.S	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -38,6 +38,4 @@
     movl r8 = 0x4404000;;
     mov b1 = r8 ;;
-    mov r1 = in0;
+    mov r1 = in0;               #Save bootinfo prt
     br.call.sptk.many b0 = b1;;
-.global ofw
-ofw:
Index: boot/arch/ia64/loader/boot.S
===================================================================
--- boot/arch/ia64/loader/boot.S	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/boot.S	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -35,4 +35,5 @@
 start:
 
+
 	mov ar.rsc = r0
 #	movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
@@ -58,4 +59,20 @@
 	br.call.sptk.many b0 = b1
 
+.align 512
+ap_start:
+
+
+ap_loop:
+	movl r18=0x4405000;;
+	mov b1 = r18 ;;
+	br.call.sptk.many b0 = b1;;
+
+.align 1024
+
+.align 4096
+.global binfo
+binfo:
+
+
 .bss #on this line is ".bss", it cannot be seen in my mcedit :-(
 
Index: boot/arch/ia64/loader/gefi/HelenOS/Makefile
===================================================================
--- boot/arch/ia64/loader/gefi/HelenOS/Makefile	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/gefi/HelenOS/Makefile	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -29,5 +29,5 @@
 LDSCRIPT	= ../gnuefi/elf_$(ARCH)_efi.lds
 LDFLAGS		+= -T $(LDSCRIPT) -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS)
-LOADLIBES	= -lefi -lgnuefi
+LOADLIBES	= -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
 FORMAT		= efi-app-$(ARCH)
 
@@ -46,13 +46,21 @@
 	$(OBJDUMP) -d hello.efi > hello.disass  
 
-hello.so: hello.o image.o
-	$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES)
+#When selected first lines or second lines, select if image is linked into hello or not - usefull for network boot
+#hello.so: hello.o image.o 
+hello.so: hello.o
+#	$(LD) $(LDFLAGS) -Map hello.map hello.o image.o -o hello.so $(LOADLIBES) #link image inside hello
+	$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES) #dont link image inside hello
 
 hello.o: hello.c
 	$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c hello.c -o hello.o
 
-image.o: ../../image.boot
+image.o: ../../image.boot mkimage
 	$(OBJCOPY) -O binary ../../image.boot image.bin
-	$(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o
+	./mkimage
+	$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c image.c -o image.o
+#	$(OBJCOPY) -I binary -O elf64-ia64-little -B ia64  image.bin image.o
+
+mkimage: mkimage.c
+	gcc -o mkimage mkimage.c
 
 
Index: boot/arch/ia64/loader/gefi/HelenOS/hello.c
===================================================================
--- boot/arch/ia64/loader/gefi/HelenOS/hello.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/gefi/HelenOS/hello.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -2,5 +2,19 @@
 #include <efilib.h>
 
+#include <../../../../../../kernel/arch/ia64/include/bootinfo.h>
+
 #define KERNEL_LOAD_ADDRESS 0x4400000
+
+//Link image as a data array into hello - usefull with network boot
+//#define IMAGE_LINKED
+
+bootinfo_t *bootinfo=(bootinfo_t *)BOOTINFO_ADDRESS;
+
+
+#ifdef IMAGE_LINKED
+extern char HOSimage[];
+extern int HOSimagesize;
+#endif
+
 
 
@@ -16,21 +30,4 @@
 	return mem;
 }
-char HEX[256];
-
-char hexs[]="0123456789ABCDEF";
-/*
-void to_hex(unsigned long long num)
-{
-    int a;
-    for(a=15;a>=0;a--)    
-    {
-	char c=num - (num & 0xfffffffffffffff0LL);
-	num/=16;
-	c=hexs[c];
-	HEX[a]=c;
-    }
-
-}
-*/
 
 EFI_STATUS
@@ -73,9 +70,10 @@
 
 	BS->HandleProtocol(LoadedImage->DeviceHandle, &FileSystemProtocol, &Vol);
-	Vol->OpenVolume (Vol, &CurDir);
 
 	char FileName[1024];
 	char *OsKernelBuffer;
 	int i;
+	int defaultLoad;
+	int imageLoad;
 	UINTN Size;
 
@@ -98,6 +96,8 @@
 	while(LoadOptions[i]==L' ') if(LoadOptions[i++]==0) break;
 	
-	if(LoadOptions[i++]==0)
+	if(LoadOptions[i++]==0){
 		StrCat(FileName,L"\\image.bin");
+		defaultLoad=1;
+	}	
 	else{
 		CHAR16 buf[1024];
@@ -109,24 +109,67 @@
 		buf[j+1]=0;
 		StrCat(FileName,buf);
-	}
-	
-	//Print(L"%s\n",FileName);
-
-	EFI_STATUS stat;
-	stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
-	if(EFI_ERROR(stat)){
-		Print(L"Error Opening Image %s\n",FileName);
-		return 0;
+		defaultLoad=0;
+	}
+
+	imageLoad=1;
+#ifdef IMAGE_LINKED
+	if(defaultLoad) {
+	    Print(L"Using Linked Image\n");
+	    imageLoad=0;
 	}    
-	Size = 0x00400000;
-	BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
-	FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
-	FileHandle->Close(FileHandle);
-
-	if(Size<1) return 0;
-
-
-	char *  HOS = OsKernelBuffer;  
+#endif	
+	
+
+	char *  HOS;
+	if(imageLoad)
+	{
+		Size = 0x00400000;
+
+    		Vol->OpenVolume (Vol, &CurDir);
+
+		EFI_STATUS stat;
+		stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0);
+		if(EFI_ERROR(stat)){
+			Print(L"Error Opening Image %s\n",FileName);
+			return 0;
+		}
+	        BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer);
+		FileHandle->Read(FileHandle, &Size, OsKernelBuffer);
+		FileHandle->Close(FileHandle);
+		HOS = OsKernelBuffer;  
+	    	if(Size<1) return 0;
+
+	}	    
+#ifdef IMAGE_LINKED
+	else {
+	    HOS = HOSimage;  
+	    Size = HOSimagesize;
+	    Print(L"Image start %llX\n",(long long)HOS);
+	    Print(L"Image size %llX\n",(long long)Size);
+	    Print(L"Image &size %llX\n",(long long)&Size);
+	}
+#endif	
 	int HOSSize = Size;  
+
+
+	rArg rSAL;
+	//Setup AP's wake up address
+
+	LibSalProc(0x01000000,2,0x4400200,0,0,0,0,0,&rSAL);
+
+
+        UINT64 sapic;
+        LibGetSalIpiBlock(&sapic);
+        Print (L"SAPIC:%X\n", sapic);
+	bootinfo->sapic=sapic;
+
+
+        int wakeup_intno;
+        wakeup_intno=0xf0;
+        Print (L"WAKEUP INTNO:%X\n", wakeup_intno);
+	bootinfo->wakeup_intno=wakeup_intno;
+
+
+
 
 
@@ -168,4 +211,6 @@
 	    ((char *)(0x4400000))[a]=HOS[a];
 	}
+	bootinfo->sapic=(unsigned long *)sapic;
+	bootinfo->wakeup_intno=wakeup_intno;
 	
 	//Run Kernel
@@ -178,7 +223,5 @@
 	   
 	
-	while(1){
-	    ((volatile int *)(0x80000000000b8000))[0]++;
-	}
+	//Not reached	   
 	return EFI_SUCCESS;
 }
Index: boot/arch/ia64/loader/gefi/apps/Makefile
===================================================================
--- boot/arch/ia64/loader/gefi/apps/Makefile	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/gefi/apps/Makefile	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -29,5 +29,5 @@
 LDSCRIPT	= ../gnuefi/elf_$(ARCH)_efi.lds
 LDFLAGS		+= -T $(LDSCRIPT) -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS)
-LOADLIBES	= -lefi -lgnuefi
+LOADLIBES	= -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name)
 FORMAT		= efi-app-$(ARCH)
 
Index: boot/arch/ia64/loader/main.c
===================================================================
--- boot/arch/ia64/loader/main.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/main.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -35,5 +35,5 @@
 #include <balloc.h>
 
-bootinfo_t bootinfo;
+extern bootinfo_t binfo;
 component_t components[COMPONENTS];
 
@@ -70,4 +70,6 @@
 	
 	
+	bootinfo_t *bootinfo=&binfo;
+	
 	//for(ii=0;ii<KERNEL_SIZE;ii++) ((char *)(0x100000))[ii] = ((char *)KERNEL_START)[ii+1];
 	
@@ -93,16 +95,15 @@
 
 
-	bootinfo.taskmap.count = 0;
+	bootinfo->taskmap.count = 0;
 	for (i = 0; i < COMPONENTS; i++) {
 
 		if (i > 0) {
-			bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = components[i].start;
-			bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size;
-			bootinfo.taskmap.count++;
+			bootinfo->taskmap.tasks[bootinfo->taskmap.count].addr = components[i].start;
+			bootinfo->taskmap.tasks[bootinfo->taskmap.count].size = components[i].size;
+			bootinfo->taskmap.count++;
 		}
 	}
 
-
-	jump_to_kernel(&bootinfo);
+	jump_to_kernel(bootinfo);
 
 
Index: boot/arch/ia64/loader/main.h
===================================================================
--- boot/arch/ia64/loader/main.h	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ boot/arch/ia64/loader/main.h	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -30,26 +30,11 @@
 #define BOOT_ia64_MAIN_H_
 
-#include <ofw.h>
-#include <ofw_tree.h>
 #include <types.h>
+#include <../../../../kernel/arch/ia64/include/bootinfo.h> 
 
 
 #define CONFIG_INIT_TASKS	32
 
-typedef struct {
-	void *addr; 
-	size_t size;
-} init_task_t;
-	
-typedef struct {
-	count_t count;
-	init_task_t tasks[CONFIG_INIT_TASKS];
-} init_t;
 
-typedef struct {
-	init_t taskmap;
-} bootinfo_t;
-
-extern bootinfo_t bootinfo;
 
 extern void start(void);
Index: kernel/arch/ia64/Makefile.inc
===================================================================
--- kernel/arch/ia64/Makefile.inc	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/Makefile.inc	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -83,4 +83,5 @@
 	arch/$(ARCH)/src/proc/scheduler.c \
 	arch/$(ARCH)/src/ddi/ddi.c \
+	arch/$(ARCH)/src/smp/smp.c \
 	arch/$(ARCH)/src/drivers/it.c
 
@@ -99,2 +100,6 @@
 endif
 
+ifeq ($(CONFIG_SMP),y)
+	DEFS += -DCONFIG_SMP
+endif
+
Index: kernel/arch/ia64/include/atomic.h
===================================================================
--- kernel/arch/ia64/include/atomic.h	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/include/atomic.h	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -52,4 +52,18 @@
 }
 
+
+static inline uint64_t test_and_set(atomic_t *val) {
+	uint64_t v;
+		
+	asm volatile (
+		"movl %0=0x01;;\n"
+		"xchg8 %0=%1,%0;;\n"
+		: "=r" (v),"+m" (val->count)
+	);
+	
+	return v;
+}
+
+
 static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
 static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
Index: kernel/arch/ia64/include/bootinfo.h
===================================================================
--- kernel/arch/ia64/include/bootinfo.h	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/include/bootinfo.h	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -30,5 +30,5 @@
 #define KERN_ia64_BOOTINFO_H_
 
-
+#define BOOTINFO_ADDRESS 0x4401000
 
 #define CONFIG_INIT_TASKS	32
@@ -47,4 +47,8 @@
 typedef struct {
 	binit_t taskmap;
+
+	unsigned long * sapic;
+	unsigned int wakeup_intno;
+
 } bootinfo_t;
 
Index: kernel/arch/ia64/include/cpu.h
===================================================================
--- kernel/arch/ia64/include/cpu.h	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/include/cpu.h	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -39,4 +39,5 @@
 #include <arch/register.h>
 #include <arch/asm.h>
+#include <arch/bootinfo.h>
 
 #define FAMILY_ITANIUM	0x7
@@ -64,4 +65,31 @@
 }
 
+
+#define CR64_ID_SHIFT 24
+#define CR64_ID_MASK 0xff000000
+#define CR64_EID_SHIFT 16
+#define CR64_EID_MASK 0xff0000
+
+static inline int ia64_get_cpu_id(void)
+{
+	uint64_t cr64=cr64_read();
+	return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT;
+}
+
+static inline int ia64_get_cpu_eid(void)
+{
+	uint64_t cr64=cr64_read();
+	return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT;
+}
+
+
+
+static inline void ipi_send_ipi(int id,int eid,int intno)
+{
+	(bootinfo->sapic)[2*(id*256+eid)]=intno;
+}
+
+
+
 #endif
 
Index: kernel/arch/ia64/include/mm/page.h
===================================================================
--- kernel/arch/ia64/include/mm/page.h	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/include/mm/page.h	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -47,4 +47,16 @@
 #define KERNEL_PAGE_WIDTH		28	/* 256M */
 #define IO_PAGE_WIDTH			26	/* 64M */
+#define FW_PAGE_WIDTH			28	/* 256M */
+
+/** Staticly mapped IO spaces */
+
+/* Firmware area (bellow 4GB in phys mem) */
+#define FW_OFFSET             0x00000000F0000000
+/* Legacy IO space */
+#define IO_OFFSET             0x0001000000000000
+/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000*/
+#define VIO_OFFSET            0x0002000000000000
+
+
 
 
Index: kernel/arch/ia64/src/drivers/it.c
===================================================================
--- kernel/arch/ia64/src/drivers/it.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/src/drivers/it.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -56,12 +56,15 @@
 {
 	cr_itv_t itv;
-
-	irq_initialize(&it_irq);
-	it_irq.inr = INTERRUPT_TIMER;
-	it_irq.devno = device_assign_devno();
-	it_irq.claim = it_claim;
-	it_irq.handler = it_interrupt;
-	irq_register(&it_irq);
-
+	
+	if(config.cpu_active==1)
+	{
+		irq_initialize(&it_irq);
+		it_irq.inr = INTERRUPT_TIMER;
+		it_irq.devno = device_assign_devno();
+		it_irq.claim = it_claim;
+		it_irq.handler = it_interrupt;
+		irq_register(&it_irq);
+	}
+	
 	/* initialize Interval Timer external interrupt vector */
 	itv.value = itv_read();
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/src/ia64.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -55,4 +55,14 @@
 #include <arch/bootinfo.h>
 #include <genarch/kbd/i8042.h>
+#include <genarch/kbd/ns16550.h>
+#include <smp/smp.h>
+#include <smp/ipi.h>
+#include <arch/atomic.h>
+#include <panic.h>
+#include <print.h>
+
+/*NS16550 as a COM 1*/
+#define NS16550_IRQ 4
+#define NS16550_PORT 0x3f8
 
 bootinfo_t *bootinfo;
@@ -103,10 +113,13 @@
 void arch_post_mm_init(void)
 {
-	irq_init(INR_COUNT, INR_COUNT);
-#ifdef SKI
-	ski_init_console();
+	if(config.cpu_active==1)
+	{
+		irq_init(INR_COUNT, INR_COUNT);
+#ifdef SKI
+		ski_init_console();
 #else	
-	ega_init();
+		ega_init();
 #endif	
+	}
 	it_init();	
 }
@@ -128,4 +141,7 @@
 	while (1) {
 		i8042_poll();
+#ifdef CONFIG_NS16550
+		ns16550_poll();
+#endif
 		thread_usleep(POLL_INTERVAL);
 	}
@@ -136,5 +152,5 @@
 {
 
-	if (config.cpu_active == 1) {
+	{
 		/*
 		 * Create thread that polls keyboard.
@@ -154,4 +170,8 @@
 		i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
 
+#ifdef CONFIG_NS16550
+		ns16550_init(kbd, NS16550_IRQ, NS16550_PORT); // as a COM 1
+#else
+#endif
 		thread_t *t;
 		t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
@@ -164,4 +184,5 @@
 	}
 }
+
 
 /** Enter userspace and never return. */
@@ -225,5 +246,5 @@
 void arch_reboot(void)
 {
-	// TODO
+	outb(0x64,0xfe);
 	while (1);
 }
Index: kernel/arch/ia64/src/mm/frame.c
===================================================================
--- kernel/arch/ia64/src/mm/frame.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/src/mm/frame.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -43,18 +43,29 @@
  */
 #define MEMORY_SIZE	(64 * 1024 * 1024)
-#define MEMORY_BASE	(64 * 1024 * 1024)
+#define MEMORY_BASE	(0 * 64 * 1024 * 1024)
+
+#define ONE_TO_ONE_MAPPING_SIZE (256*1048576) // Mapped at start
 
 #define ROM_BASE	0xa0000               //For ski
 #define ROM_SIZE	(384 * 1024)          //For ski
 void poke_char(int x,int y,char ch, char c);
+
+uintptr_t last_frame;
+
 void frame_arch_init(void)
 {
-	zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
+
+	if(config.cpu_active==1)
+	{
+		zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
 	
-	/*
-	 * Blacklist ROM regions.
-	 */
-	frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE));
-	
+		/*
+		* Blacklist ROM regions.
+		*/
+		//frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE));
+
+		frame_mark_unavailable(ADDR2PFN(0), SIZE2FRAMES(1048576));
+		last_frame=SIZE2FRAMES((VRN_KERNEL<<VRN_SHIFT)+ONE_TO_ONE_MAPPING_SIZE);	
+	}	
 }
 
Index: kernel/arch/ia64/src/mm/page.c
===================================================================
--- kernel/arch/ia64/src/mm/page.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/src/mm/page.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -48,4 +48,5 @@
 #include <arch/barrier.h>
 #include <memstr.h>
+#include <align.h>
 
 static void set_environment(void);
@@ -263,4 +264,26 @@
 }
 
+extern uintptr_t last_frame;
+
+
+uintptr_t hw_map(uintptr_t physaddr, size_t size)
+{
+	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
+		panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
+	
+	uintptr_t virtaddr = PA2KA(last_frame);
+	pfn_t i;
+	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
+		uintptr_t addr = PFN2ADDR(i);
+		page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr, PAGE_NOT_CACHEABLE | PAGE_WRITE);
+	}
+	
+	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
+	
+	return virtaddr;
+}
+
+
+
 /** @}
  */
Index: kernel/arch/ia64/src/smp/smp.c
===================================================================
--- kernel/arch/ia64/src/smp/smp.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
+++ kernel/arch/ia64/src/smp/smp.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup ia64
+ * @{
+ */
+/** @file
+ */
+
+#include <arch.h>
+#include <arch/ski/ski.h>
+#include <arch/drivers/it.h>
+#include <arch/interrupt.h>
+#include <arch/barrier.h>
+#include <arch/asm.h>
+#include <arch/register.h>
+#include <arch/types.h>
+#include <arch/context.h>
+#include <arch/stack.h>
+#include <arch/mm/page.h>
+#include <mm/as.h>
+#include <config.h>
+#include <userspace.h>
+#include <console/console.h>
+#include <proc/uarg.h>
+#include <syscall/syscall.h>
+#include <ddi/irq.h>
+#include <ddi/device.h>
+#include <arch/drivers/ega.h>
+#include <arch/bootinfo.h>
+#include <genarch/kbd/i8042.h>
+#include <genarch/kbd/ns16550.h>
+#include <smp/smp.h>
+#include <smp/ipi.h>
+#include <arch/atomic.h>
+#include <panic.h>
+#include <print.h>
+
+
+
+
+
+
+#ifdef CONFIG_SMP
+
+
+extern char cpu_by_id_eid_list[256][256];
+
+
+static void sapic_init(void)
+{
+	bootinfo->sapic=(unative_t *)(PA2KA((unative_t)(bootinfo->sapic))|FW_OFFSET);
+}
+
+
+
+static void ipi_broadcast_arch_all(int ipi )
+{
+	int id,eid;
+	int myid,myeid;
+	
+	myid=ia64_get_cpu_id();
+	myeid=ia64_get_cpu_eid();
+
+	printf("Not sending to ID:%d,EID:%d",myid,myeid);
+	
+	for(id=0;id<256;id++)
+		for(eid=0;eid<256;eid++)
+			if((id!=myid) || (eid!=myeid))
+				ipi_send_ipi(id,eid,ipi);
+}
+
+void ipi_broadcast_arch(int ipi )
+{
+	ipi_broadcast_arch_all(ipi);
+}
+
+
+void smp_init(void)
+{
+	sapic_init();
+	ipi_broadcast_arch_all(bootinfo->wakeup_intno);	
+	volatile long long brk;
+        for(brk=0;brk<100LL*1024LL*1024LL;brk++); //wait a while before CPUs starts
+
+	config.cpu_count=0;
+	int id,eid;
+	
+	for(id=0;id<256;id++)
+		for(eid=0;eid<256;eid++)
+		        if(cpu_by_id_eid_list[id][eid]==1){
+		    		config.cpu_count++;
+		    		printf("Found CPU ID:%d EDI:%d\n",id,eid);
+		    		cpu_by_id_eid_list[id][eid]=2;
+
+			}
+}
+
+
+void kmp(void *arg __attribute__((unused)))
+{
+	int id,eid;
+	int myid,myeid;
+	
+	myid=ia64_get_cpu_id();
+	myeid=ia64_get_cpu_eid();
+
+	for(id=0;id<256;id++)
+		for(eid=0;eid<256;eid++)
+		        if((id!=myid) || (eid!=myeid))
+		        	if(cpu_by_id_eid_list[id][eid]!=0){
+		    			if(cpu_by_id_eid_list[id][eid]==1){
+		    		
+			    			//config.cpu_count++;
+				    		//cpu_by_id_eid_list[id][eid]=2;
+				    		printf("Found Late CPU ID:%d EDI:%d Not added to system!!!\n",id,eid);
+				    		continue;
+			    			}
+					cpu_by_id_eid_list[id][eid]=3;
+					/*
+					 * There may be just one AP being initialized at
+					 * the time. After it comes completely up, it is
+					 * supposed to wake us up.
+					 */
+					if (waitq_sleep_timeout(&ap_completion_wq, 1000000,
+					    SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
+						printf("%s: waiting for cpu ID:%d EID:%d"
+						    "timed out\n", __FUNCTION__, 
+						    id, eid);
+					    }    
+		
+				}
+}
+#endif
+
+
+/*This is just a hack for linking with assembler - may be removed in future*/
+#ifndef CONFIG_SMP
+void main_ap(void);
+void main_ap(void)
+{
+	while(1);
+}
+
+#endif
+
+/** @}
+ */
+
Index: kernel/arch/ia64/src/start.S
===================================================================
--- kernel/arch/ia64/src/start.S	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/arch/ia64/src/start.S	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -40,7 +40,5 @@
 #define KERNEL_TRANSLATION_VIO 0x0010000000000671
 #define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 
-#define VIO_OFFSET            0x0002000000000000
-
-#define IO_OFFSET             0x0001000000000000
+#define KERNEL_TRANSLATION_FW 0x00100000F0000671 
 
 
@@ -53,4 +51,16 @@
 kernel_image_start:
 	.auto
+
+#identifi self(CPU) in OS structures by ID / EID
+	mov r9=cr64
+	mov r10=1
+	movl r12=0xffffffff
+	movl r8=cpu_by_id_eid_list
+	and r8=r8,r12
+	shr r9=r9,16
+	add r8=r8,r9
+	st1 [r8]=r10
+
+
 
 	mov psr.l = r0
@@ -113,4 +123,21 @@
 	movl r10 = (KERNEL_TRANSLATION_IO)
 	itr.d dtr[r7] = r10
+
+
+#setup mapping for fimware arrea (also SAPIC)
+	mov r11 = cr.itir ;;
+	movl r10 = ~0xfc;;
+	and r10 =r10 , r11  ;;
+	movl r11 = (FW_PAGE_WIDTH << PS_SHIFT);;
+	or r10 =r10 , r11  ;;
+	mov cr.itir = r10;;
+
+
+	movl r7 = 3
+	movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET
+	mov cr.ifa = r8
+	movl r10 = (KERNEL_TRANSLATION_FW)
+	itr.d dtr[r7] = r10
+
 
 
@@ -143,4 +170,10 @@
 	# switch to register bank 1
 	bsw.1
+
+#Am'I BSP or AP
+	movl r20=bsp_started;;
+	ld8 r20=[r20];;
+	cmp.eq p3,p2=r20,r0;;
+
 	
 	# initialize register stack
@@ -161,18 +194,18 @@
 	
 	/*
-	 * Initialize hardcoded_* variables.
+	 * Initialize hardcoded_* variables. Do only BSP
 	 */
-	movl r14 = _hardcoded_ktext_size
-	movl r15 = _hardcoded_kdata_size
-	movl r16 = _hardcoded_load_address ;;
-	addl r17 = @gprel(hardcoded_ktext_size), gp
-	addl r18 = @gprel(hardcoded_kdata_size), gp
-	addl r19 = @gprel(hardcoded_load_address), gp
-	addl r21 = @gprel(bootinfo), gp
+(p3)	movl r14 = _hardcoded_ktext_size
+(p3)	movl r15 = _hardcoded_kdata_size
+(p3)	movl r16 = _hardcoded_load_address ;;
+(p3)	addl r17 = @gprel(hardcoded_ktext_size), gp
+(p3)	addl r18 = @gprel(hardcoded_kdata_size), gp
+(p3)	addl r19 = @gprel(hardcoded_load_address), gp
+(p3)	addl r21 = @gprel(bootinfo), gp
 	;;
-	st8 [r17] = r14
-	st8 [r18] = r15
-	st8 [r19] = r16
-	st8 [r21] = r20
+(p3)	st8 [r17] = r14
+(p3)	st8 [r18] = r15
+(p3)	st8 [r19] = r16
+(p3)	st8 [r21] = r20
 
 	ssm (1 << 19) ;; /* Disable f32 - f127 */
@@ -180,4 +213,14 @@
 	srlz.d ;;
 
+(p2)	movl r18 = main_ap ;;
+(p2)   	mov b1 = r18 ;;
+(p2)	br.call.sptk.many b0 = b1
+
+#Mark that BSP is on
+	mov r20=1;;
+	movl r21=bsp_started;;
+	st8 [r21]=r20;;
+
+
 	br.call.sptk.many b0 = arch_pre_main
 
@@ -189,2 +232,45 @@
 0:
 	br 0b
+.align 4096
+
+kernel_image_ap_start:
+	.auto
+#identifi self(CPU) in OS structures by ID / EID
+	mov r9=cr64
+	mov r10=1
+	movl r12=0xffffffff
+	movl r8=cpu_by_id_eid_list
+	and r8=r8,r12
+	shr r9=r9,16
+	add r8=r8,r9
+	st1 [r8]=r10
+	
+#wait for wakeup sychro signal (#3 in cpu_by_id_eid_list)
+kernel_image_ap_start_loop:
+	movl r11=kernel_image_ap_start_loop
+	and r11=r11,r12
+   	mov b1 = r11 
+
+	ld1 r20=[r8];;
+	movl r21=3;;
+	cmp.eq p2,p3=r20,r21;;
+(p3)br.call.sptk.many b0 = b1
+
+	movl r11=kernel_image_start
+	and r11=r11,r12
+    mov b1 = r11 
+	br.call.sptk.many b0 = b1
+
+
+.align 16
+.global bsp_started
+bsp_started:
+.space 8
+
+
+.align 4096
+.global cpu_by_id_eid_list
+cpu_by_id_eid_list:
+.space 65536
+
+
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/generic/include/synch/spinlock.h	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -37,4 +37,5 @@
 
 #include <arch/types.h>
+#include <arch/barrier.h>
 #include <preemption.h>
 #include <atomic.h>
Index: kernel/generic/src/mm/tlb.c
===================================================================
--- kernel/generic/src/mm/tlb.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/generic/src/mm/tlb.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -135,5 +135,7 @@
 void tlb_shootdown_ipi_send(void)
 {
+#ifndef ia64
 	ipi_broadcast(VECTOR_TLB_SHOOTDOWN_IPI);
+#endif	
 }
 
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision a2a552922110e12b1296ecc23f36d826e7fc4040)
+++ kernel/generic/src/proc/thread.c	(revision 59e4864a51a79cbe1c491a3c86539b884e9005e6)
@@ -296,5 +296,4 @@
 	if (!t)
 		return NULL;
-	
 	/* Not needed, but good for debugging */
 	memsetb(t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
