Index: boot/arch/ia64/Makefile.inc
===================================================================
--- boot/arch/ia64/Makefile.inc	(revision 26fb118ae8c0e8bb11d3a2c886dcda94d6a7435b)
+++ boot/arch/ia64/Makefile.inc	(revision 577fe9b66437c659dd86ce8cb1588daf58b9bae2)
@@ -46,4 +46,5 @@
 	arch/$(BARCH)/src/main.c \
 	arch/$(BARCH)/src/sal.c \
+	arch/$(BARCH)/src/sal_asm.S \
 	arch/$(BARCH)/src/putchar.c \
 	$(COMPS_C) \
Index: boot/arch/ia64/include/sal.h
===================================================================
--- boot/arch/ia64/include/sal.h	(revision 26fb118ae8c0e8bb11d3a2c886dcda94d6a7435b)
+++ boot/arch/ia64/include/sal.h	(revision 577fe9b66437c659dd86ce8cb1588daf58b9bae2)
@@ -32,4 +32,9 @@
 #include <arch/types.h>
 #include <typedefs.h>
+
+/*
+ * Essential SAL procedures' IDs
+ */
+#define SAL_FREQ_BASE	0x1000012
 
 typedef struct {
@@ -103,3 +108,11 @@
 extern void sal_system_table_parse(sal_system_table_header_t *);
 
+extern uint64_t sal_base_clock_frequency(void);
+
+#define sal_call_1_1(id, arg1, ret1) \
+	sal_call((id), (arg1), 0, 0, 0, 0, 0, 0, (ret1), NULL, NULL)
+
+extern uint64_t sal_call(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
+    uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *, uint64_t *);
+
 #endif
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision 26fb118ae8c0e8bb11d3a2c886dcda94d6a7435b)
+++ boot/arch/ia64/src/main.c	(revision 577fe9b66437c659dd86ce8cb1588daf58b9bae2)
@@ -118,21 +118,29 @@
 }
 
-static void read_sal_configuration(void)
-{
-	if (bootpar && bootpar->efi_system_table) {
-		/* TODO: read the real values from SAL */
+static void read_pal_configuration(void)
+{
+	if (bootpar) {
+		/* TODO: read the real value from PAL */
 		bootinfo.freq_scale = DEFAULT_FREQ_SCALE;
-		bootinfo.sys_freq = DEFAULT_SYS_FREQ;
-		
-		efi_guid_t sal_guid = SAL_SYSTEM_TABLE_GUID;
-		sal_system_table_header_t *sal_st;
-		
-		sal_st = efi_vendor_table_find(
-		    (efi_system_table_t *) bootpar->efi_system_table, sal_guid);
-
-		sal_system_table_parse(sal_st);
 	} else {
 		/* Configure default values for simulators. */
 		bootinfo.freq_scale = DEFAULT_FREQ_SCALE;
+	}
+}
+
+static void read_sal_configuration(void)
+{
+	if (bootpar && bootpar->efi_system_table) {
+		efi_guid_t sal_guid = SAL_SYSTEM_TABLE_GUID;
+		sal_system_table_header_t *sal_st;
+		
+		sal_st = efi_vendor_table_find(
+		    (efi_system_table_t *) bootpar->efi_system_table, sal_guid);
+
+		sal_system_table_parse(sal_st);
+		
+		bootinfo.sys_freq = sal_base_clock_frequency();
+	} else {
+		/* Configure default values for simulators. */
 		bootinfo.sys_freq = DEFAULT_SYS_FREQ;
 	}
@@ -198,4 +206,5 @@
 	read_efi_memmap();
 	read_sal_configuration();
+	read_pal_configuration();
 	
 	printf("Booting the kernel ...\n");
Index: boot/arch/ia64/src/sal.c
===================================================================
--- boot/arch/ia64/src/sal.c	(revision 26fb118ae8c0e8bb11d3a2c886dcda94d6a7435b)
+++ boot/arch/ia64/src/sal.c	(revision 577fe9b66437c659dd86ce8cb1588daf58b9bae2)
@@ -30,6 +30,10 @@
 #include <arch/types.h>
 
-static sal_entrypoint_desc_t *sal_entrypoints;
 static sal_ap_wakeup_desc_t *sal_ap_wakeup;
+
+uint64_t pal_proc = 0;
+
+uint64_t sal_proc = 0;
+uint64_t sal_proc_gp = 0;
 
 void sal_system_table_parse(sal_system_table_header_t *sst)
@@ -41,5 +45,7 @@
 		switch ((sal_sst_type_t) *cur) {
 		case SSTT_ENTRYPOINT_DESC:
-			sal_entrypoints = (sal_entrypoint_desc_t *) cur;
+			pal_proc = ((sal_entrypoint_desc_t *) cur)->pal_proc;
+			sal_proc = ((sal_entrypoint_desc_t *) cur)->sal_proc;
+			sal_proc_gp = ((sal_entrypoint_desc_t *) cur)->sal_proc_gp;
 			cur += sizeof(sal_entrypoint_desc_t);
 			break;
@@ -66,2 +72,10 @@
 }
 
+uint64_t sal_base_clock_frequency(void)
+{
+	uint64_t freq;
+	
+	sal_call_1_1(SAL_FREQ_BASE, 0, &freq);
+	
+	return freq;
+}
Index: boot/arch/ia64/src/sal_asm.S
===================================================================
--- boot/arch/ia64/src/sal_asm.S	(revision 577fe9b66437c659dd86ce8cb1588daf58b9bae2)
+++ boot/arch/ia64/src/sal_asm.S	(revision 577fe9b66437c659dd86ce8cb1588daf58b9bae2)
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2011 Jakub Jermar
+# 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.
+#
+
+.explicit
+
+.global sal_call
+
+#
+# Assume the following PSR bits are already 0, as expected by SAL:
+#
+#  be, cpl, is, da, dd, ss, ri, ed, ia
+#
+# Assume PSR.bn is 1, as expected by SAL.
+#
+sal_call:
+	alloc loc0 = ar.pfs, 11, 5, 8, 0
+	
+	mov loc1 = gp
+	mov loc2 = rp
+	
+	addl loc3 = @gprel(sal_proc), gp
+	addl loc4 = @gprel(sal_proc_gp), gp
+	
+	mov out0 = in0
+	mov out1 = in1
+	mov out2 = in2
+	mov out3 = in3
+	mov out4 = in4
+	mov out5 = in5
+	mov out6 = in6
+	mov out7 = in7 ;;
+	
+	ld8 loc3 = [loc3]
+	ld8 gp = [loc4] ;;
+	
+	mov b6 = loc3 ;;
+	br.call.sptk.many rp = b6
+	
+	cmp.ne p7,p0 = 0, in8
+	cmp.ne p8,p0 = 0, in9
+	cmp.ne p9,p0 = 0, in10 ;;
+	
+(p7)	st8 [in8] = r9
+(p8)	st8 [in9] = r10
+(p9)	st8 [in10] = r11
+	
+	mov gp = loc1
+	mov rp = loc2 ;;
+	
+	mov ar.pfs = loc0
+	br.ret.sptk.many rp
