http://lia64.bkbits.net/linux-ia64-test-2.6.9
aegl@agluck-lia64.sc.intel.com|ChangeSet|20040825231636|45360 aegl

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/08/25 19:43:45-07:00 akpm@bix.(none) 
#   Merge http://lia64.bkbits.net/linux-ia64-test-2.6.9
#   into bix.(none):/usr/src/bk-ia64
# 
# arch/ia64/mm/contig.c
#   2004/08/25 19:43:40-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/25 23:16:36+00:00 aegl@agluck-lia64.sc.intel.com 
#   Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1
#   into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9
# 
# arch/ia64/configs/generic_defconfig
#   2004/08/25 23:16:31+00:00 aegl@agluck-lia64.sc.intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/25 18:27:33+00:00 dcn@sgi.com 
#   [IA64] allow OEM written modules to make calls to ia64 OEM SAL functions.
#   
#   Add wrapper functions for SAL_CALL(), SAL_CALL_NOLOCK(), and
#   SAL_CALL_REENTRANT() that allow OEM written modules to make
#   calls to ia64 OEM SAL functions.
#   
#   Signed-off-by: Dean Nelson <dcn@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/sal.h
#   2004/08/25 18:25:25+00:00 aegl@agluck-lia64.sc.intel.com +10 -0
#   allow OEM written modules to make calls to ia64 OEM SAL functions.
# 
# arch/ia64/kernel/sal.c
#   2004/08/25 18:24:59+00:00 aegl@agluck-lia64.sc.intel.com +38 -0
#   allow OEM written modules to make calls to ia64 OEM SAL functions.
# 
# ChangeSet
#   2004/08/25 18:21:19+00:00 ianw@gelato.unsw.edu.au 
#   [IA64] Remove extraneous MMU_TRACE debugging macros
#   
#   Patch created by Ian Wienand.
#   
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/tlbflush.h
#   2004/08/25 18:16:41+00:00 aegl@agluck-lia64.sc.intel.com +2 -5
#   Remove extraneous MMU_TRACE debugging macros
# 
# include/asm-ia64/mmu_context.h
#   2004/08/25 18:16:03+00:00 aegl@agluck-lia64.sc.intel.com +1 -38
#   Remove extraneous MMU_TRACE debugging macros
# 
# ChangeSet
#   2004/08/25 18:03:28+00:00 yanmin.zhang@intel.com 
#   [IA64] contig.c: Function find_bootmap_location has 2 bugs.
#   
#   Firstly, if it's done successfully, it should return -1 instead of 1
#   because its caller, efi_memmap_walk, will end when find_bootmap_location
#   returns a value smaller than 0.
#   
#   Secondly, statement "free_start = PAGE_ALIGN(rsvd_region[i].end)" should
#   been moved forward. free_start needs to be initialized for every loop
#   iteration.  Current implementation is buggy where initialization is
#   skipped if range_end <= range_start.  Skipping initializing will leads
#   to overlapping bootmap with one of the rsvd_regions and subsequently
#   kernel hang at boot time.
#   
#   Singed-off-by:(sic) Zhang Yanmin <yanmin.zhang@intel.com>
#   Signed-off-by:      Yao Jun      <junx.yao@intel.com>
#   Signed-off-by:      Tony Luck    <tony.luck@intel.com>
# 
# arch/ia64/mm/contig.c
#   2004/08/25 17:56:35+00:00 aegl@agluck-lia64.sc.intel.com +4 -4
#   Function find_bootmap_location has 2 bugs.
# 
# ChangeSet
#   2004/08/25 17:54:46+00:00 yanmin.zhang@intel.com 
#   [IA64] Fix boot problems when using "mem=" boot parameter.
#   
#   My tiger-4 machine has 16GB memory. Kernel 2.6.8 fails to boot on it
#   when command line parameter mem=8G, and it also fails when mem being
#   set to other value, such as 7G, 10G.
#   
#   Basically, in function efi_memmap_walk, md->num_pages might be decreased
#   if mem_limit is set, and then at the next time when efi_memmap_walk is
#   called, trim_top might trim the md again because of IA64_GRANULE_SIZE
#   alignment, then another md which is beyond mem_limit at the beginning
#   will be chosen, and its physical page number is larger than max_pfn. Then,
#   a BUG check is triggered.
#   
#   Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>
#   Signed-off-by: Yao Jun      <junx.yao@intel.com>
#   Signed-off-by: Tony Luck    <tony.luck@intel.com>
# 
# arch/ia64/kernel/efi.c
#   2004/08/25 17:50:37+00:00 aegl@agluck-lia64.sc.intel.com +3 -1
#   Fix boot problems when using "mem=" boot parameter.
# 
# ChangeSet
#   2004/08/25 17:45:09+00:00 jbarnes@sgi.com 
#   [IA64] generic_defconfig: Enable codepage/iocharset for VFAT filesystems.
#   
#   VFAT filesystems need to have codepages and iocharsets specified these days,
#   so build some into the kernel to make it easier to mount /boot/efi on ia64
#   systems.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/configs/generic_defconfig
#   2004/08/25 17:43:06+00:00 aegl@agluck-lia64.sc.intel.com +19 -9
#   Enable codepage/iocharset for VFAT filesystems.
# 
# ChangeSet
#   2004/08/25 17:39:35+00:00 jbarnes@sgi.com 
#   [IA64] Add include pagemap.h to tlb.h to fix warnings when CONFIG_SWAP=n.
#   
#   I noticed when building with CONFIG_SWAP=n that tlb.h gave a warning about
#   some undefined symbols.  This is because it was pulling them in through
#   swap.h, but when CONFIG_SWAP=n, they're no longer pulled in.  Adding
#   pagemap.h to tlb.h fixes the problem.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/tlb.h
#   2004/08/25 17:35:10+00:00 aegl@agluck-lia64.sc.intel.com +1 -0
#   Add pagemap.h to fix warnings when CONFIG_SWAP=n.
# 
# ChangeSet
#   2004/08/25 17:30:26+00:00 bjohnson@sgi.com 
#   [IA64-SGI] Add full PROM version banner to /proc/sgi_prominfo/nodeXX/version.
#   
#   Signed-off-by: Brian J. Johnson <bjohnson@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/sn/kernel/sn2/prominfo_proc.c
#   2004/08/25 17:27:31+00:00 aegl@agluck-lia64.sc.intel.com +61 -13
#   Add full PROM version banner to /proc/sgi_prominfo/nodeXX/version.
# 
# ChangeSet
#   2004/08/24 17:53:02-07:00 akpm@bix.(none) 
#   Merge http://lia64.bkbits.net/linux-ia64-test-2.6.9
#   into bix.(none):/usr/src/bk-ia64
# 
# include/asm-ia64/acpi.h
#   2004/08/24 17:52:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/ia64/kernel/asm-offsets.c
#   2004/08/24 17:52:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/24 22:21:59+00:00 aegl@agluck-lia64.sc.intel.com 
#   Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1
#   into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9
# 
# kernel/timer.c
#   2004/08/24 22:21:54+00:00 aegl@agluck-lia64.sc.intel.com +0 -0
#   Auto merged
# 
# kernel/posix-timers.c
#   2004/08/24 22:21:53+00:00 aegl@agluck-lia64.sc.intel.com +0 -0
#   Auto merged
# 
# include/asm-ia64/acpi.h
#   2004/08/24 22:21:53+00:00 aegl@agluck-lia64.sc.intel.com +0 -1
#   Auto merged
# 
# ChangeSet
#   2004/08/24 21:26:27+00:00 clameter@sgi.com 
#   scalability & performance improvements for timers
#   
#   Signed-off-by: Christoph Lameter <clameter@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
#   
#   - Include corrected test data since the test program had a bad
#     influence on the outcome. Scalability is better than the
#     test program indicated.
#   - Correctly setup the timer accuracy.
#   - Consistently increases performance over existing codebase
#   - Make the IA64 fastcall work for all clock sources and not only
#     for ITC based clocking.
#   - Add fastcall for clock_gettime(REALTIME and MONOTONIC)
#     (the fastcall also returns nanoseconds instead of usecs*1000)
#   - Scalability improvements in particular for the use of global clocks
#     by avoiding the use of a cmpxchg. For applications
#     that continually "live" in gettimeofday on an SMP system this
#     will be a significant improvement.
#   - Ability to switch off the cmpxchg for ITC based systems through
#     a "nojitter" option on the kernel command line. This increases
#     scalability of the time functions significantly. The ITC tuning code
#     that runs during bootup typically insures that ITC offsets are less
#     than a few cycles which are longer than the delay caused by the gettime
#     functions and therefore the cmpxchg is not necessary on most systems.
#   - Self tuning interpolator limiting the jumps forward to 10-20 usecs
#     on each occurrence and increasing accuracy as well as robustness.
#     There is no danger anymore that the interpolator is configured to
#     be running too fast.
#   - Report the increased accuracy via clock_getres() to userspace.
#   - Generic interface. An interpolator can be easily setup by simply
#     setting up a time_interpolator structure with some values.
#     No coding of special functions needed.
#   - Supports the HPET timer.
# 
# kernel/timer.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +10 -5
#   scalability & performance improvements for timers
# 
# kernel/posix-timers.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +5 -0
#   scalability & performance improvements for timers
# 
# include/linux/timex.h
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +123 -52
#   scalability & performance improvements for timers
# 
# drivers/char/hpet.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +3 -33
#   scalability & performance improvements for timers
# 
# arch/ia64/sn/kernel/sn2/timer.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +4 -45
#   scalability & performance improvements for timers
# 
# arch/ia64/kernel/time.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +35 -84
#   scalability & performance improvements for timers
# 
# arch/ia64/kernel/fsys.S
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +185 -172
#   scalability & performance improvements for timers
# 
# arch/ia64/kernel/cyclone.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +4 -55
#   scalability & performance improvements for timers
# 
# arch/ia64/kernel/asm-offsets.c
#   2004/08/24 21:20:31+00:00 aegl@agluck-lia64.sc.intel.com +16 -3
#   scalability & performance improvements for timers
# 
# ChangeSet
#   2004/08/24 16:16:47+00:00 aegl@agluck-lia64.sc.intel.com 
#   Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/Linus
#   into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9
# 
# include/asm-ia64/acpi.h
#   2004/08/24 16:16:42+00:00 aegl@agluck-lia64.sc.intel.com +0 -1
#   Auto merged
# 
# ChangeSet
#   2004/08/23 18:06:07+00:00 aegl@agluck-lia64.sc.intel.com 
#   Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1
#   into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-release-2.6.8.1
# 
# include/asm-ia64/acpi.h
#   2004/08/23 18:06:02+00:00 aegl@agluck-lia64.sc.intel.com +0 -1
#   Auto merged
# 
# ChangeSet
#   2004/08/22 21:19:29-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-ia64
# 
# include/asm-ia64/acpi.h
#   2004/08/22 21:19:25-07:00 akpm@bix.(none) +0 -1
#   Auto merged
# 
# ChangeSet
#   2004/08/18 21:50:56+00:00 jbarnes@sgi.com 
#   [ACPI] ia64 build fix
#   
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/acpi.h
#   2004/08/17 22:17:10+00:00 jbarnes@sgi.com +1 -0
#   ia64 ACPI build fix
# 
# ChangeSet
#   2004/08/18 18:18:02+00:00 kenneth.w.chen@intel.com 
#   [IA64] head.S: update comments to match code
#   
#   Update comments in function ia64_switch_mode_virt() to reflect actual
#   implementation from recent region 5 init_task bug fix.
#   
#   Signed-off-by: Ken Chen <kenneth.w.chen@intel.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/kernel/head.S
#   2004/08/18 18:17:23+00:00 kenneth.w.chen@intel.com +1 -2
#   update comments to match code
# 
# ChangeSet
#   2004/08/18 18:11:06+00:00 jbarnes@sgi.com 
#   [IA64] cyclone.c: Add includes for build on uni-processor.
#   
#   Small patch to fix the includes for the cyclone timer.  We just happen to be
#   getting these if CONFIG_SMP is on, but if it's turned off the build breaks.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/kernel/cyclone.c
#   2004/08/18 18:10:33+00:00 jbarnes@sgi.com +2 -0
#   Add includes for build on uni-processor.
# 
# ChangeSet
#   2004/08/18 18:01:20+00:00 roe@sgi.com 
#   [IA64-SGI] report coherence id in /proc/sgi_sn/coherence_id
#   
#   Current SGI Altix systems have a NUMAlink domain size of 1024
#   compute nodes and are fully cache coherent up to 256 compute
#   nodes (compute nodes are even-numbered).  Systems larger than
#   256 nodes are partitioned into multiple cache coherent systems.
#   This patch exports a partition's coherence id to users via the
#   /proc/sgi_sn/coherence_id file.
#    
#   Signed-off-by: Dean Roe <roe@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/sn/sn_cpuid.h
#   2004/08/18 18:00:37+00:00 roe@sgi.com +7 -1
#   add macros to get coherence id from cpuid
# 
# arch/ia64/sn/kernel/sn2/sn_proc_fs.c
#   2004/08/18 18:00:37+00:00 roe@sgi.com +23 -1
#   report coherence id in /proc/sgi_sn/coherence_id
# 
# ChangeSet
#   2004/08/18 17:52:20+00:00 jbarnes@sgi.com 
#   [IA64] time.c: Downgrade printk of cpu speed to KERN_DEBUG
#   
#   This patch turns the per-CPU frequency printk into a KERN_DEBUG instead of a
#   KERN_INFO so it'll show up in the system log but won't be printed at boot,
#   since it's a big pain on system with a lot of CPUs.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/kernel/time.c
#   2004/08/18 17:51:42+00:00 jbarnes@sgi.com +1 -1
#   Downgrade printk of cpu speed to KERN_DEBUG
# 
# ChangeSet
#   2004/08/18 17:26:05+00:00 edwardsg@sgi.com 
#   [IA64] ia32_support.c: Check whether page_alloc failed.
#   
#   It's pretty unlikely these page allocations would fail, but we should
#   still check them.
#   
#   Signed-off-by: Greg Edwards <edwardsg@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/ia32/ia32_support.c
#   2004/08/18 17:25:15+00:00 edwardsg@sgi.com +6 -0
#   Check whether page_alloc failed.
# 
# ChangeSet
#   2004/08/18 17:19:08+00:00 steiner@sgi.com 
#   [IA64-SGI] The SN2 fakeprom directories/files should be deleted.
#   
#   Signed-off-by: Jack Steiner <steiner@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# BitKeeper/deleted/.del-runsim~a711a1ab0af1705
#   2004/08/18 17:19:00+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/runsim
# 
# BitKeeper/deleted/.del-make_textsym~7e01e13217d2f336
#   2004/08/18 17:19:00+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/make_textsym
# 
# BitKeeper/deleted/.del-main.c~cb94011d199676d
#   2004/08/18 17:19:00+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/main.c
# 
# BitKeeper/deleted/.del-klgraph_init.c~aa95cde7a9f378ff
#   2004/08/18 17:19:00+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/klgraph_init.c
# 
# BitKeeper/deleted/.del-fw-emu.c~839acab86f841ae8
#   2004/08/18 17:19:00+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/fw-emu.c
# 
# BitKeeper/deleted/.del-fpromasm.S~b1ba88b8fc042b23
#   2004/08/18 17:18:59+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/fpromasm.S
# 
# BitKeeper/deleted/.del-fprom.lds~85f66545e097fe3c
#   2004/08/18 17:18:59+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/fprom.lds
# 
# BitKeeper/deleted/.del-fpmem.h~1d6c9758daedaaf0
#   2004/08/18 17:18:59+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/fpmem.h
# 
# BitKeeper/deleted/.del-fpmem.c~3f099c89df871d43
#   2004/08/18 17:18:59+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/fpmem.c
# 
# BitKeeper/deleted/.del-README~bd48db925e04952
#   2004/08/18 17:18:59+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/README
# 
# BitKeeper/deleted/.del-Makefile~d85515a659a74329
#   2004/08/18 17:18:59+00:00 steiner@sgi.com +0 -0
#   Delete: arch/ia64/sn/fakeprom/Makefile
# 
# ChangeSet
#   2004/08/18 17:01:08+00:00 jbarnes@sgi.com 
#   [IA64-SGI] bte.c: kill expression as lvalue warning
#   
#   A recent patch caused a warning about not using expressions as lvalues
#   to crop up in bte.c (or maybe it's just that I'm using gcc-3.4.1 now).
#   This patch fixes it by creating a temporary to store the register whose
#   address we want to get and stuff into the per-bte info structure.
#   
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/sn/kernel/bte.c
#   2004/08/18 17:00:28+00:00 jbarnes@sgi.com +4 -3
#   kill expression as lvalue warning
# 
# ChangeSet
#   2004/08/18 16:40:05+00:00 jbarnes@sgi.com 
#   [IA64-SGI] Assign parent to PCI devices.
#   
#   In working on the patch to export PCI ROM space via sysfs, I found that the
#   sn2 PCI code doesn't assign a parent resource to any of the PCI device
#   resources as it builds them.  This provides a simple fix for that problem.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/sn/io/machvec/pci_bus_cvlink.c
#   2004/08/18 16:38:41+00:00 jbarnes@sgi.com +3 -0
#   provide parent resources for PCI devices
# 
# ChangeSet
#   2004/08/17 23:50:42+00:00 aegl@agluck-lia64.sc.intel.com 
#   Merge agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.8.1
#   into agluck-lia64.sc.intel.com:/data/home/aegl/BK/linux-ia64-test-2.6.9
# 
# include/asm-ia64/acpi.h
#   2004/08/17 23:50:37+00:00 aegl@agluck-lia64.sc.intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/17 23:45:26+00:00 schwab@suse.de 
#   [IA64] <asm-ia64/acpi.h> still declares deleted acpi_register_irq.
#   
#   Signed-off-by: Andreas Schwab <schwab@suse.de>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/acpi.h
#   2004/08/17 23:44:28+00:00 schwab@suse.de +0 -1
#   acpi_register_irq() no longer exists
# 
# ChangeSet
#   2004/08/17 23:31:45+00:00 seto.hidetoshi@jp.fujitsu.com 
#   [IA64] floating point regs are not 16-byte aligned inside SAL error record
#   
#   Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/sal.h
#   2004/08/17 23:29:55+00:00 seto.hidetoshi@jp.fujitsu.com +1 -1
#   floating point regs are not 16-byte aligned inside SAL error record
# 
# ChangeSet
#   2004/08/17 22:56:10+00:00 ak@suse.de 
#   [IA64] various issues in the IA64 swiotlb code
#   
#   The biggest change is better overflow handling, partly ported from the AMD64 
#   IOMMU  code.  This is important for some 3d drivers who make use of this and can 
#   map a lot of memory.
#   
#   First it increases the default memory usage of swiotlb to 64MB.
#   This was the value used in production systems in 2.4 (e.g. in SLES8) and the default
#   was far too small.  Note this is only allocated when the swiotlb is needed.
#   
#   pci_map_single will not panic anymore on an overflow. Instead it returns
#   a pointer to a scratch area and allows the caller to check using 
#   dma_mapping_error(). It still panics when the overflow buffer is exceeded.
#   
#   dma_mapping_error support is implemented.
#   
#   pci_map_sg will never panic now, but just return 0. Near all callers 
#   of it seem to have proper error checking for this (IDE will even handle
#   it without erroring out) 
#   
#   The handling of passing a NULL device is improved, previously it would 
#   never map in this case. i386 and other architectures assume NULL means a 4GB
#   limit instead.   This code does this now too.
#   
#   I added support for swiotlb=force for easier testing.
#   
#   Patch supplied by Andi Kleen & Suresh Siddha
#   
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/lib/swiotlb.c
#   2004/08/17 22:52:39+00:00 ak@suse.de +88 -26
#   various issues in the IA64 swiotlb code
# 
# ChangeSet
#   2004/08/17 22:20:48+00:00 jbarnes@sgi.com 
#   [ACPI] ia64 build fix
#   
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/acpi.h
#   2004/08/17 22:17:10+00:00 jbarnes@sgi.com +1 -0
#   ia64 ACPI build fix
# 
diff -Nru a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig
--- a/arch/ia64/configs/generic_defconfig	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/configs/generic_defconfig	2004-08-25 19:44:40 -07:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.9-rc1
+# Tue Aug 24 15:08:24 2004
 #
 
 #
@@ -126,6 +128,7 @@
 CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_FAKE is not set
 CONFIG_HOTPLUG_PCI_ACPI=m
+# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
 # CONFIG_HOTPLUG_PCI_PCIE is not set
 # CONFIG_HOTPLUG_PCI_SHPC is not set
@@ -172,6 +175,7 @@
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=m
 CONFIG_BLK_DEV_RAM_SIZE=4096
 
@@ -313,6 +317,7 @@
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
+# CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID5=m
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
@@ -365,6 +370,7 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -767,6 +773,7 @@
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 
 #
 # USB Host Controller Drivers
@@ -919,6 +926,8 @@
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_NTFS_FS=m
 # CONFIG_NTFS_DEBUG is not set
 # CONFIG_NTFS_RW is not set
@@ -946,7 +955,6 @@
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -971,6 +979,7 @@
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
@@ -1007,7 +1016,7 @@
 #
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_737=m
 CONFIG_NLS_CODEPAGE_775=m
 CONFIG_NLS_CODEPAGE_850=m
@@ -1031,7 +1040,7 @@
 CONFIG_NLS_CODEPAGE_1250=m
 CONFIG_NLS_CODEPAGE_1251=m
 # CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_ISO8859_2=m
 CONFIG_NLS_ISO8859_3=m
 CONFIG_NLS_ISO8859_4=m
@@ -1068,18 +1077,18 @@
 #
 # Kernel hacking
 #
-CONFIG_IA64_GRANULE_16MB=y
-# CONFIG_IA64_GRANULE_64MB is not set
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_IA64_GRANULE_16MB=y
+# CONFIG_IA64_GRANULE_64MB is not set
+# CONFIG_IA64_PRINT_HAZARDS is not set
+# CONFIG_DISABLE_VHPT is not set
 # CONFIG_IA64_DEBUG_CMPXCHG is not set
 # CONFIG_IA64_DEBUG_IRQ is not set
-# CONFIG_DEBUG_INFO is not set
 CONFIG_SYSVIPC_COMPAT=y
 
 #
@@ -1102,11 +1111,12 @@
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES_GENERIC is not set
+# CONFIG_CRYPTO_AES is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
diff -Nru a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c
--- a/arch/ia64/ia32/ia32_support.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/ia32/ia32_support.c	2004-08-25 19:44:40 -07:00
@@ -145,6 +145,9 @@
 	int cpu = smp_processor_id();
 
 	ia32_shared_page[cpu] = alloc_page(GFP_KERNEL);
+	if (!ia32_shared_page[cpu])
+		panic("failed to allocate ia32_shared_page[%d]\n", cpu);
+
 	cpu_gdt_table[cpu] = page_address(ia32_shared_page[cpu]);
 
 	/* Copy from the boot cpu's GDT */
@@ -161,6 +164,9 @@
 	unsigned long ldt_size;
 
 	ia32_shared_page[0] = alloc_page(GFP_KERNEL);
+	if (!ia32_shared_page[0])
+		panic("failed to allocate ia32_shared_page[0]\n");
+
 	ia32_boot_gdt = page_address(ia32_shared_page[0]);
 	cpu_gdt_table[0] = ia32_boot_gdt;
 
diff -Nru a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
--- a/arch/ia64/kernel/asm-offsets.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/asm-offsets.c	2004-08-25 19:44:40 -07:00
@@ -188,9 +188,6 @@
 	DEFINE(IA64_CLONE_VM, CLONE_VM);
 
 	BLANK();
-    /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
-	DEFINE(IA64_CPUINFO_ITM_DELTA_OFFSET, offsetof (struct cpuinfo_ia64, itm_delta));
-	DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next));
 	DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc));
 	DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec));
 
@@ -202,5 +199,21 @@
 
 	BLANK();
 	DEFINE(IA64_MCA_TLB_INFO_SIZE, sizeof (struct ia64_mca_tlb_info));
+	/* used by head.S */
+	DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc));
 
+	BLANK();
+	/* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
+	DEFINE(IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET, offsetof (struct time_interpolator, addr));
+	DEFINE(IA64_TIME_INTERPOLATOR_SOURCE_OFFSET, offsetof (struct time_interpolator, source));
+	DEFINE(IA64_TIME_INTERPOLATOR_SHIFT_OFFSET, offsetof (struct time_interpolator, shift));
+	DEFINE(IA64_TIME_INTERPOLATOR_NSEC_OFFSET, offsetof (struct time_interpolator, nsec_per_cyc));
+	DEFINE(IA64_TIME_INTERPOLATOR_OFFSET_OFFSET, offsetof (struct time_interpolator, offset));
+	DEFINE(IA64_TIME_INTERPOLATOR_LAST_CYCLE_OFFSET, offsetof (struct time_interpolator, last_cycle));
+	DEFINE(IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET, offsetof (struct time_interpolator, last_counter));
+	DEFINE(IA64_TIME_INTERPOLATOR_JITTER_OFFSET, offsetof (struct time_interpolator, jitter));
+	DEFINE(IA64_TIME_SOURCE_CPU, TIME_SOURCE_CPU);
+	DEFINE(IA64_TIME_SOURCE_MMIO64, TIME_SOURCE_MMIO64);
+	DEFINE(IA64_TIME_SOURCE_MMIO32, TIME_SOURCE_MMIO32);
+	DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec));
 }
diff -Nru a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
--- a/arch/ia64/kernel/cyclone.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/cyclone.c	2004-08-25 19:44:40 -07:00
@@ -1,6 +1,8 @@
+#include <linux/module.h>
 #include <linux/smp.h>
 #include <linux/time.h>
 #include <linux/errno.h>
+#include <asm/io.h>
 
 /* IBM Summit (EXA) Cyclone counter code*/
 #define CYCLONE_CBAR_ADDR 0xFEB00CD0
@@ -15,62 +17,10 @@
 	use_cyclone = 1;
 }
 
-static u32* volatile cyclone_timer;	/* Cyclone MPMC0 register */
-static u32 last_update_cyclone;
-
-static unsigned long offset_base;
-
-static unsigned long get_offset_cyclone(void)
-{
-	u32 now;
-	unsigned long offset;
-
-	/* Read the cyclone timer */
-	now = readl(cyclone_timer);
-	/* .. relative to previous update*/
-	offset = now - last_update_cyclone;
-
-	/* convert cyclone ticks to nanoseconds */
-	offset = (offset*NSEC_PER_SEC)/CYCLONE_TIMER_FREQ;
-
-	/* our adjusted time in nanoseconds */
-	return offset_base + offset;
-}
-
-static void update_cyclone(long delta_nsec)
-{
-	u32 now;
-	unsigned long offset;
-
-	/* Read the cyclone timer */
-	now = readl(cyclone_timer);
-	/* .. relative to previous update*/
-	offset = now - last_update_cyclone;
-
-	/* convert cyclone ticks to nanoseconds */
-	offset = (offset*NSEC_PER_SEC)/CYCLONE_TIMER_FREQ;
-
-	offset += offset_base;
-
-	/* Be careful about signed/unsigned comparisons here: */
-	if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
-		offset_base = offset - delta_nsec;
-	else
-		offset_base = 0;
-
-	last_update_cyclone = now;
-}
-
-static void reset_cyclone(void)
-{
-	offset_base = 0;
-	last_update_cyclone = readl(cyclone_timer);
-}
 
 struct time_interpolator cyclone_interpolator = {
-	.get_offset =	get_offset_cyclone,
-	.update =	update_cyclone,
-	.reset =	reset_cyclone,
+	.source =	TIME_SOURCE_MMIO32,
+	.shift =	32,
 	.frequency =	CYCLONE_TIMER_FREQ,
 	.drift =	-100,
 };
@@ -81,6 +31,7 @@
 	u64 base;	/* saved cyclone base address */
 	u64 offset;	/* offset from pageaddr to cyclone_timer register */
 	int i;
+	u32* volatile cyclone_timer;	/* Cyclone MPMC0 register */
 
 	if (!use_cyclone)
 		return -ENODEV;
@@ -148,7 +99,7 @@
 		}
 	}
 	/* initialize last tick */
-	last_update_cyclone = readl(cyclone_timer);
+	cyclone_interpolator.addr = cyclone_timer;
 	register_time_interpolator(&cyclone_interpolator);
 
 	return 0;
diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
--- a/arch/ia64/kernel/efi.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/efi.c	2004-08-25 19:44:40 -07:00
@@ -357,8 +357,10 @@
 			if (total_mem >= mem_limit)
 				continue;
 			total_mem += (md->num_pages << EFI_PAGE_SHIFT);
-			if (total_mem > mem_limit)
+			if (total_mem > mem_limit) {
 				md->num_pages -= ((total_mem - mem_limit) >> EFI_PAGE_SHIFT);
+				max_addr = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+			}
 
 			if (md->num_pages == 0)
 				continue;
diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
--- a/arch/ia64/kernel/fsys.S	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/fsys.S	2004-08-25 19:44:40 -07:00
@@ -8,6 +8,8 @@
  * 18-Feb-03 louisk	Implement fsys_gettimeofday().
  * 28-Feb-03 davidm	Fixed several bugs in fsys_gettimeofday().  Tuned it some more,
  *			probably broke it along the way... ;-)
+ * 13-Jul-04 clameter   Implement fsys_clock_gettime and revise fsys_gettimeofday to make
+ *                      it capable of using memory based clocks without falling back to C code.
  */
 
 #include <asm/asmmacro.h>
@@ -144,195 +146,206 @@
 END(fsys_set_tid_address)
 
 /*
- * Note 1: This routine uses floating-point registers, but only with registers that
- *	   operate on integers.  Because of that, we don't need to set ar.fpsr to the
- *	   kernel default value.
- *
- * Note 2: For now, we will assume that all CPUs run at the same clock-frequency.
- *	   If that wasn't the case, we would have to disable preemption (e.g.,
- *	   by disabling interrupts) between reading the ITC and reading
- *	   local_cpu_data->nsec_per_cyc.
- *
- * Note 3: On platforms where the ITC-drift bit is set in the SAL feature vector,
- *	   we ought to either skip the ITC-based interpolation or run an ntp-like
- *	   daemon to keep the ITCs from drifting too far apart.
+ * Ensure that the time interpolator structure is compatible with the asm code
  */
+#if IA64_TIME_INTERPOLATOR_SOURCE_OFFSET !=0 || IA64_TIME_INTERPOLATOR_SHIFT_OFFSET != 2 \
+	|| IA64_TIME_INTERPOLATOR_JITTER_OFFSET != 3 || IA64_TIME_INTERPOLATOR_NSEC_OFFSET != 4
+#error fsys_gettimeofday incompatible with changes to struct time_interpolator
+#endif
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_DIVIDE_BY_1000 0x4000
+#define CLOCK_ADD_MONOTONIC 0x8000
 
 ENTRY(fsys_gettimeofday)
 	.prologue
 	.altrp b6
 	.body
-	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
-	addl r3=THIS_CPU(cpu_info),r0
-
-#ifdef CONFIG_SMP
-	movl r10=__per_cpu_offset
-	movl r2=sal_platform_features
-	;;
-
-	ld8 r2=[r2]
-	movl r19=xtime			// xtime is a timespec struct
-
-	ld8 r10=[r10]			// r10 <- __per_cpu_offset[0]
-	addl r21=THIS_CPU(cpu_info),r0
-	;;
-	add r10=r21, r10		// r10 <- &cpu_data(time_keeper_id)
-	tbit.nz p8,p0 = r2, IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT
-(p8)	br.spnt.many fsys_fallback_syscall
-#else
-	;;
-	mov r10=r3
-	movl r19=xtime			// xtime is a timespec struct
-#endif
-	ld4 r9=[r9]
-	movl r17=xtime_lock
-	;;
-
-	// r32, r33 should contain the 2 args of gettimeofday
-	adds r21=IA64_CPUINFO_ITM_NEXT_OFFSET, r10
-	mov r2=-1
-	tnat.nz p6,p7=r32		// guard against NaT args
-	;;
-
-	adds r10=IA64_CPUINFO_ITM_DELTA_OFFSET, r10
-(p7)	tnat.nz p6,p0=r33
-(p6)	br.cond.spnt.few .fail_einval
-
-	adds r8=IA64_CPUINFO_NSEC_PER_CYC_OFFSET, r3
-	movl r24=2361183241434822607	// for division hack (only for / 1000)
-	;;
-
-	ldf8 f7=[r10]			// f7 now contains itm_delta
-	setf.sig f11=r2
-	adds r10=8, r32
-
-	adds r20=IA64_TIMESPEC_TV_NSEC_OFFSET, r19	// r20 = &xtime->tv_nsec
-	movl r26=jiffies
-
-	setf.sig f9=r24			// f9 is used for division hack
-	movl r27=wall_jiffies
-
-	and r9=TIF_ALLWORK_MASK,r9
-	movl r25=last_nsec_offset
-	;;
-
-	/*
-	 * Verify that we have permission to write to struct timeval.  Note:
-	 * Another thread might unmap the mapping before we actually get
-	 * to store the result.  That's OK as long as the stores are also
-	 * protect by EX().
-	 */
-EX(.fail_efault, probe.w.fault r32, 3)		// this must come _after_ NaT-check
-EX(.fail_efault, probe.w.fault r10, 3)		// this must come _after_ NaT-check
-	nop 0
-
-	ldf8 f10=[r8]			// f10 <- local_cpu_data->nsec_per_cyc value
-	cmp.ne p8, p0=0, r9
-(p8)	br.spnt.many fsys_fallback_syscall
-	;;
-.retry:	// *** seq = read_seqbegin(&xtime_lock); ***
-	ld4.acq r23=[r17]		// since &xtime_lock == &xtime_lock->sequence
-	ld8 r14=[r25]			// r14 (old) = last_nsec_offset
-
-	ld8 r28=[r26]			// r28 = jiffies
-	ld8 r29=[r27]			// r29 = wall_jiffies
-	;;
-
-	ldf8 f8=[r21]			// f8 now contains itm_next
-	mov.m r31=ar.itc		// put time stamp into r31 (ITC) == now
-	sub r28=r29, r28, 1		// r28 now contains "-(lost + 1)"
-	;;
-
-	ld8 r2=[r19]			// r2 = sec = xtime.tv_sec
-	ld8 r29=[r20]			// r29 = nsec = xtime.tv_nsec
-	tbit.nz p9, p10=r23, 0		// p9 <- is_odd(r23), p10 <- is_even(r23)
-
-	setf.sig f6=r28			// f6 <- -(lost + 1)				(6 cyc)
-	;;
-
+	mov r31 = r32
+	tnat.nz p6,p0 = r33		// guard against NaT argument
+(p6)    br.cond.spnt.few .fail_einval
+	mov r30 = CLOCK_DIVIDE_BY_1000
+	;;
+.gettime:
+	// Register map
+	// Incoming r31 = pointer to address where to place result
+	//          r30 = flags determining how time is processed
+	// r2,r3 = temp r4-r7 preserved
+	// r8 = result nanoseconds
+	// r9 = result seconds
+	// r10 = temporary storage for clock difference
+	// r11 = preserved: saved ar.pfs
+	// r12 = preserved: memory stack
+	// r13 = preserved: thread pointer
+	// r14 = debug pointer / usable
+	// r15 = preserved: system call number
+	// r16 = preserved: current task pointer
+	// r17 = wall to monotonic use
+	// r18 = time_interpolator->offset
+	// r19 = address of wall_to_monotonic
+	// r20 = pointer to struct time_interpolator / pointer to time_interpolator->address
+	// r21 = shift factor
+	// r22 = address of time interpolator->last_counter
+	// r23 = address of time_interpolator->last_cycle
+	// r24 = adress of time_interpolator->offset
+	// r25 = last_cycle value
+	// r26 = last_counter value
+	// r27 = pointer to xtime
+	// r28 = sequence number at the beginning of critcal section
+	// r29 = address of seqlock
+	// r30 = time processing flags / memory address
+	// r31 = pointer to result
+	// Predicates
+	// p6,p7 short term use
+	// p8 = timesource ar.itc
+	// p9 = timesource mmio64
+	// p10 = timesource mmio32
+	// p11 = timesource not to be handled by asm code
+	// p12 = memory time source ( = p9 | p10)
+	// p13 = do cmpxchg with time_interpolator_last_cycle
+	// p14 = Divide by 1000
+	// p15 = Add monotonic
+	//
+	// Note that instructions are optimized for McKinley. McKinley can process two
+	// bundles simultaneously and therefore we continuously try to feed the CPU
+	// two bundles and then a stop.
+	tnat.nz p6,p0 = r31	// branch deferred since it does not fit into bundle structure
+	mov pr = r30,0xc000	// Set predicates according to function
+	add r2 = TI_FLAGS+IA64_TASK_SIZE,r16
+	movl r20 = time_interpolator
+	;;
+	ld8 r20 = [r20]		// get pointer to time_interpolator structure
+	movl r29 = xtime_lock
+	ld4 r2 = [r2]		// process work pending flags
+	movl r27 = xtime
+	;;	// only one bundle here
+	ld8 r21 = [r20]		// first quad with control information
+	and r2 = TIF_ALLWORK_MASK,r2
+(p6)    br.cond.spnt.few .fail_einval	// deferred branch
+	;;
+	add r10 = IA64_TIME_INTERPOLATOR_ADDRESS_OFFSET,r20
+	extr r3 = r21,32,32	// time_interpolator->nsec_per_cyc
+	extr r8 = r21,0,16	// time_interpolator->source
+	nop.i 123
+	cmp.ne p6, p0 = 0, r2	// Fallback if work is scheduled
+(p6)    br.cond.spnt.many fsys_fallback_syscall
+	;;
+	cmp.eq p8,p12 = 0,r8	// Check for cpu timer
+	cmp.eq p9,p0 = 1,r8	// MMIO64 ?
+	extr r2 = r21,24,8	// time_interpolator->jitter
+	cmp.eq p10,p0 = 2,r8	// MMIO32 ?
+	cmp.lt p11,p0 = 2,r8	// function?
+(p11)	br.cond.spnt.many fsys_fallback_syscall
+	;;
+	setf.sig f7 = r3	// Setup for scaling of counter
+(p15)	movl r19 = wall_to_monotonic
+(p12)	ld8 r30 = [r10]
+	cmp.ne p13,p0 = r2,r0	// need jitter compensation?
+	extr r21 = r21,16,8	// shift factor
+	;;
+.time_redo:
+	.pred.rel.mutex p8,p9,p10
+	ld4.acq r28 = [r29]	// xtime_lock.sequence. Must come first for locking purposes
+(p8)	mov r2 = ar.itc		// CPU_TIMER. 36 clocks latency!!!
+	add r22 = IA64_TIME_INTERPOLATOR_LAST_COUNTER_OFFSET,r20
+(p9)	ld8 r2 = [r30]		// readq(ti->address). Could also have latency issues..
+(p10)	ld4 r2 = [r30]		// readw(ti->address)
+(p13)	add r23 = IA64_TIME_INTERPOLATOR_LAST_CYCLE_OFFSET,r20
+	;;			// could be removed by moving the last add upward
+	ld8 r26 = [r22]		// time_interpolator->last_counter
+(p13)	ld8 r25 = [r23]		// time interpolator->last_cycle
+	add r24 = IA64_TIME_INTERPOLATOR_OFFSET_OFFSET,r20
+(p15)	ld8 r17 = [r19],IA64_TIMESPEC_TV_NSEC_OFFSET
+ 	ld8 r9 = [r27],IA64_TIMESPEC_TV_NSEC_OFFSET
+	nop.i 123
+	;;
+	ld8 r18 = [r24]		// time_interpolator->offset
+	ld8 r8 = [r27],-IA64_TIMESPEC_TV_NSEC_OFFSET	// xtime.tv_nsec
+(p13)	sub r3 = r25,r2	// Diff needed before comparison (thanks davidm)
+	;;
+(p13)	cmp.gt.unc p6,p7 = r3,r0	// check if it is less than last. p6,p7 cleared
+	sub r10 = r2,r26	// current_counter - last_counter
+	;;
+(p6)	sub r10 = r25,r26	// time we got was less than last_cycle
+(p7)	mov ar.ccv = r25	// more than last_cycle. Prep for cmpxchg
+	;;
+	setf.sig f8 = r10
+	nop.i 123
+	;;
+(p7)	cmpxchg8.rel r3 = [r23],r2,ar.ccv
+EX(.fail_efault, probe.w.fault r31, 3)	// This takes 5 cycles and we have spare time
+	xmpy.l f8 = f8,f7	// nsec_per_cyc*(counter-last_counter)
+(p15)	add r9 = r9,r17		// Add wall to monotonic.secs to result secs
+	;;
+(p15)	ld8 r17 = [r19],-IA64_TIMESPEC_TV_NSEC_OFFSET
+(p7)	cmp.ne p7,p0 = r25,r3	// if cmpxchg not successful redo
+	// simulate tbit.nz.or p7,p0 = r28,0
+	and r28 = ~1,r28	// Make sequence even to force retry if odd
+	getf.sig r2 = f8
 	mf
-	xma.l f8=f6, f7, f8	// f8 (last_tick) <- -(lost + 1)*itm_delta + itm_next	(5 cyc)
-	nop 0
-
-	setf.sig f12=r31		// f12 <- ITC					(6 cyc)
-	// *** if (unlikely(read_seqretry(&xtime_lock, seq))) continue; ***
-	ld4 r24=[r17]			// r24 = xtime_lock->sequence (re-read)
-	nop 0
-	;;
-
-	xma.l f8=f11, f8, f12	// f8 (elapsed_cycles) <- (-1*last_tick + now) = (now - last_tick)
-	nop 0
-	;;
-
-	getf.sig r18=f8			// r18 <- (now - last_tick)
-	xmpy.l f8=f8, f10		// f8 <- elapsed_cycles*nsec_per_cyc (5 cyc)
-	add r3=r29, r14			// r3 = (nsec + old)
-	;;
-
-	cmp.lt p7, p8=r18, r0		// if now < last_tick, set p7 = 1, p8 = 0
-	getf.sig r18=f8			// r18 = elapsed_cycles*nsec_per_cyc		(6 cyc)
-	nop 0
-	;;
-
-(p10)	cmp.ne p9, p0=r23, r24		// if xtime_lock->sequence != seq, set p9
-	shr.u r18=r18, IA64_NSEC_PER_CYC_SHIFT	// r18 <- offset
-(p9)	br.spnt.many .retry
-	;;
-
-	mov ar.ccv=r14			// ar.ccv = old					(1 cyc)
-	cmp.leu p7, p8=r18, r14		// if (offset <= old), set p7 = 1, p8 = 0
+	add r8 = r8,r18		// Add time interpolator offset
 	;;
-
-(p8)	cmpxchg8.rel r24=[r25], r18, ar.ccv	// compare-and-exchange (atomic!)
-(p8)	add r3=r29, r18			// r3 = (nsec + offset)
-	;;
-	shr.u r3=r3, 3			// initiate dividing r3 by 1000
-	;;
-	setf.sig f8=r3			//						(6 cyc)
-	mov r10=1000000			// r10 = 1000000
+	ld4 r10 = [r29]		// xtime_lock.sequence
+(p15)	add r8 = r8, r17	// Add monotonic.nsecs to nsecs
+	shr.u r2 = r2,r21
+	;;		// overloaded 3 bundles!
+	// End critical section.
+	add r8 = r8,r2		// Add xtime.nsecs
+	cmp4.ne.or p7,p0 = r28,r10
+(p7)	br.cond.dpnt.few .time_redo	// sequence number changed ?
+	// Now r8=tv->tv_nsec and r9=tv->tv_sec
+	mov r10 = r0
+	movl r2 = 1000000000
+	add r23 = IA64_TIMESPEC_TV_NSEC_OFFSET, r31
+(p14)	movl r3 = 2361183241434822607	// Prep for / 1000 hack
+	;;
+.time_normalize:
+	mov r21 = r8
+	cmp.ge p6,p0 = r8,r2
+(p14)	shr.u r20 = r8, 3		// We can repeat this if necessary just wasting some time
+	;;
+(p14)	setf.sig f8 = r20
+(p6)	sub r8 = r8,r2
+(p6)	add r9 = 1,r9			// two nops before the branch.
+(p14)	setf.sig f7 = r3		// Chances for repeats are 1 in 10000 for gettod
+(p6)	br.cond.dpnt.few .time_normalize
+	;;
+	// Divided by 8 though shift. Now divide by 125
+	// The compiler was able to do that with a multiply
+	// and a shift and we do the same
+EX(.fail_efault, probe.w.fault r23, 3)		// This also costs 5 cycles
+(p14)	xmpy.hu f8 = f8, f7			// xmpy has 5 cycles latency so use it...
 	;;
-(p8)	cmp.ne.unc p9, p0=r24, r14
-	xmpy.hu f6=f8, f9		//						(5 cyc)
-(p9)	br.spnt.many .retry
-	;;
-
-	getf.sig r3=f6			//						(6 cyc)
+	mov r8 = r0
+(p14)	getf.sig r2 = f8
 	;;
-	shr.u r3=r3, 4			// end of division, r3 is divided by 1000 (=usec)
-	;;
-
-1:	cmp.geu p7, p0=r3, r10		// while (usec >= 1000000)
-	;;
-(p7)	sub r3=r3, r10			// usec -= 1000000
-(p7)	adds r2=1, r2			// ++sec
-(p7)	br.spnt.many 1b
-
-	// finally: r2 = sec, r3 = usec
-EX(.fail_efault, st8 [r32]=r2)
-	adds r9=8, r32
-	mov r8=r0			// success
+(p14)	shr.u r21 = r2, 4
 	;;
-EX(.fail_efault, st8 [r9]=r3)		// store them in the timeval struct
-	mov r10=0
+EX(.fail_efault, st8 [r31] = r9)
+EX(.fail_efault, st8 [r23] = r21)
 	FSYS_RETURN
-	/*
-	 * Note: We are NOT clearing the scratch registers here.  Since the only things
-	 *	 in those registers are time-related variables and some addresses (which
-	 *	 can be obtained from System.map), none of this should be security-sensitive
-	 *	 and we should be fine.
-	 */
-
 .fail_einval:
-	mov r8=EINVAL			// r8 = EINVAL
-	mov r10=-1			// r10 = -1
+	mov r8 = EINVAL
+	mov r10 = -1
 	FSYS_RETURN
-
 .fail_efault:
-	mov r8=EFAULT			// r8 = EFAULT
-	mov r10=-1			// r10 = -1
+	mov r8 = EFAULT
+	mov r10 = -1
 	FSYS_RETURN
 END(fsys_gettimeofday)
 
+ENTRY(fsys_clock_gettime)
+	.prologue
+	.altrp b6
+	.body
+	cmp4.lt p6, p0 = CLOCK_MONOTONIC, r32
+	// Fallback if this is not CLOCK_REALTIME or CLOCK_MONOTONIC
+(p6)	br.spnt.few fsys_fallback_syscall
+	mov r31 = r33
+	shl r30 = r32,15
+	br.many .gettime
+END(fsys_clock_gettime)
+
 /*
  * long fsys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset, size_t sigsetsize).
  */
@@ -838,7 +851,7 @@
 	data8 0				// timer_getoverrun
 	data8 0				// timer_delete
 	data8 0				// clock_settime
-	data8 0				// clock_gettime
+	data8 fsys_clock_gettime	// clock_gettime
 	data8 0				// clock_getres		// 1255
 	data8 0				// clock_nanosleep
 	data8 0				// fstatfs64
diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
--- a/arch/ia64/kernel/head.S	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/head.S	2004-08-25 19:44:40 -07:00
@@ -781,8 +781,7 @@
 
 	// going to virtual
 	//   - for code addresses, set upper bits of addr to KERNEL_START
-	//   - for stack addresses, set upper 3 bits to 0xe.... Dont change any of the
-	//     lower bits since we want it to stay identity mapped
+	//   - for stack addresses, copy from input argument
 	movl r18=KERNEL_START
 	dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
 	dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
diff -Nru a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
--- a/arch/ia64/kernel/sal.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/sal.c	2004-08-25 19:44:40 -07:00
@@ -10,6 +10,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
@@ -262,3 +263,40 @@
 		p += SAL_DESC_SIZE(*p);
 	}
 }
+
+int
+ia64_sal_oemcall(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1,
+		 u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7)
+{
+	if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
+		return -1;
+	SAL_CALL(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+	return 0;
+}
+EXPORT_SYMBOL(ia64_sal_oemcall);
+
+int
+ia64_sal_oemcall_nolock(struct ia64_sal_retval *isrvp, u64 oemfunc, u64 arg1,
+			u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
+			u64 arg7)
+{
+	if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
+		return -1;
+	SAL_CALL_NOLOCK(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6,
+			arg7);
+	return 0;
+}
+EXPORT_SYMBOL(ia64_sal_oemcall_nolock);
+
+int
+ia64_sal_oemcall_reentrant(struct ia64_sal_retval *isrvp, u64 oemfunc,
+			   u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5,
+			   u64 arg6, u64 arg7)
+{
+	if (oemfunc < IA64_SAL_OEMFUNC_MIN || oemfunc > IA64_SAL_OEMFUNC_MAX)
+		return -1;
+	SAL_CALL_REENTRANT(*isrvp, oemfunc, arg1, arg2, arg3, arg4, arg5, arg6,
+			   arg7);
+	return 0;
+}
+EXPORT_SYMBOL(ia64_sal_oemcall_reentrant);
diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
--- a/arch/ia64/kernel/time.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/kernel/time.c	2004-08-25 19:44:40 -07:00
@@ -45,46 +45,7 @@
 
 #endif
 
-static void
-itc_reset (void)
-{
-}
-
-/*
- * Adjust for the fact that xtime has been advanced by delta_nsec (may be negative and/or
- * larger than NSEC_PER_SEC.
- */
-static void
-itc_update (long delta_nsec)
-{
-}
-
-/*
- * Return the number of nano-seconds that elapsed since the last
- * update to jiffy.  It is quite possible that the timer interrupt
- * will interrupt this and result in a race for any of jiffies,
- * wall_jiffies or itm_next.  Thus, the xtime_lock must be at least
- * read synchronised when calling this routine (see do_gettimeofday()
- * below for an example).
- */
-unsigned long
-itc_get_offset (void)
-{
-	unsigned long elapsed_cycles, lost = jiffies - wall_jiffies;
-	unsigned long now = ia64_get_itc(), last_tick;
-
-	last_tick = (cpu_data(TIME_KEEPER_ID)->itm_next
-		     - (lost + 1)*cpu_data(TIME_KEEPER_ID)->itm_delta);
-
-	elapsed_cycles = now - last_tick;
-	return (elapsed_cycles*local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
-}
-
-static struct time_interpolator itc_interpolator = {
-	.get_offset =	itc_get_offset,
-	.update =	itc_update,
-	.reset =	itc_reset
-};
+static struct time_interpolator itc_interpolator;
 
 int
 do_settimeofday (struct timespec *tv)
@@ -127,51 +88,13 @@
 void
 do_gettimeofday (struct timeval *tv)
 {
-	unsigned long seq, nsec, usec, sec, old, offset;
-
-	while (1) {
+	unsigned long seq, nsec, usec, sec, offset;
+	do {
 		seq = read_seqbegin(&xtime_lock);
-		{
-			old = last_nsec_offset;
-			offset = time_interpolator_get_offset();
-			sec = xtime.tv_sec;
-			nsec = xtime.tv_nsec;
-		}
-		if (unlikely(read_seqretry(&xtime_lock, seq)))
-			continue;
-		/*
-		 * Ensure that for any pair of causally ordered gettimeofday() calls, time
-		 * never goes backwards (even when ITC on different CPUs are not perfectly
-		 * synchronized).  (A pair of concurrent calls to gettimeofday() is by
-		 * definition non-causal and hence it makes no sense to talk about
-		 * time-continuity for such calls.)
-		 *
-		 * Doing this in a lock-free and race-free manner is tricky.  Here is why
-		 * it works (most of the time): read_seqretry() just succeeded, which
-		 * implies we calculated a consistent (valid) value for "offset".  If the
-		 * cmpxchg() below succeeds, we further know that last_nsec_offset still
-		 * has the same value as at the beginning of the loop, so there was
-		 * presumably no timer-tick or other updates to last_nsec_offset in the
-		 * meantime.  This isn't 100% true though: there _is_ a possibility of a
-		 * timer-tick occurring right right after read_seqretry() and then getting
-		 * zero or more other readers which will set last_nsec_offset to the same
-		 * value as the one we read at the beginning of the loop.  If this
-		 * happens, we'll end up returning a slightly newer time than we ought to
-		 * (the jump forward is at most "offset" nano-seconds).  There is no
-		 * danger of causing time to go backwards, though, so we are safe in that
-		 * sense.  We could make the probability of this unlucky case occurring
-		 * arbitrarily small by encoding a version number in last_nsec_offset, but
-		 * even without versioning, the probability of this unlucky case should be
-		 * so small that we won't worry about it.
-		 */
-		if (offset <= old) {
-			offset = old;
-			break;
-		} else if (likely(cmpxchg(&last_nsec_offset, old, offset) == old))
-			break;
-
-		/* someone else beat us to updating last_nsec_offset; try again */
-	}
+		offset = time_interpolator_get_offset();
+		sec = xtime.tv_sec;
+		nsec = xtime.tv_nsec;
+	} while (unlikely(read_seqretry(&xtime_lock, seq)));
 
 	usec = (nsec + offset) / 1000;
 
@@ -323,6 +246,18 @@
 	ia64_set_itm(local_cpu_data->itm_next);
 }
 
+static int nojitter;
+
+static int __init nojitter_setup(char *str)
+{
+	nojitter = 1;
+	printk("Jitter checking for ITC timers disabled\n");
+	return 1;
+}
+
+__setup("nojitter", nojitter_setup);
+
+
 void __devinit
 ia64_init_itm (void)
 {
@@ -371,7 +306,7 @@
 		itc_drift = -1;
 
 	local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
-	printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
+	printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
 	       "ITC freq=%lu.%03luMHz+/-%ldppm\n", smp_processor_id(),
 	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
 	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000,
@@ -385,7 +320,23 @@
 
 	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
 		itc_interpolator.frequency = local_cpu_data->itc_freq;
+		itc_interpolator.shift = 16;
 		itc_interpolator.drift = itc_drift;
+		itc_interpolator.source = TIME_SOURCE_CPU;
+#ifdef CONFIG_SMP
+		/* On IA64 in an SMP configuration ITCs are never accurately synchronized.
+		 * Jitter compensation requires a cmpxchg which may limit
+		 * the scalability of the syscalls for retrieving time.
+		 * The ITC synchronization is usually successful to within a few
+		 * ITC ticks but this is not a sure thing. If you need to improve
+		 * timer performance in SMP situations then boot the kernel with the
+		 * "nojitter" option. However, doing so may result in time fluctuating (maybe
+		 * even going backward) if the ITC offsets between the individual CPUs
+		 * are too large.
+		 */
+		if (!nojitter) itc_interpolator.jitter = 1;
+#endif
+		itc_interpolator.addr = NULL;
 		register_time_interpolator(&itc_interpolator);
 	}
 
diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
--- a/arch/ia64/lib/swiotlb.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/lib/swiotlb.c	2004-08-25 19:44:40 -07:00
@@ -11,6 +11,7 @@
  * 03/05/07 davidm	Switch from PCI-DMA to generic device DMA API.
  * 00/12/13 davidm	Rename to swiotlb.c and add mark_clean() to avoid
  *			unnecessary i-cache flushing.
+ * 04/07/.. ak          Better overflow handling. Assorted fixes.
  */
 
 #include <linux/cache.h>
@@ -20,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
 
 #include <asm/io.h>
 #include <asm/pci.h>
@@ -46,6 +48,8 @@
  */
 #define IO_TLB_SHIFT 11
 
+int swiotlb_force;
+
 /*
  * Used to do a quick range check in swiotlb_unmap_single and swiotlb_sync_single_*, to see
  * if the memory was in fact allocated by this API.
@@ -55,8 +59,16 @@
 /*
  * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and io_tlb_end.
  * This is command line adjustable via setup_io_tlb_npages.
+ * Default to 64MB.
+ */
+static unsigned long io_tlb_nslabs = 32768;
+
+/* 
+ * When the IOMMU overflows we return a fallback buffer. This sets the size.
  */
-static unsigned long io_tlb_nslabs = 1024;
+static unsigned long io_tlb_overflow = 32*1024;
+
+void *io_tlb_overflow_buffer; 
 
 /*
  * This is a free list describing the number of free entries available from each index
@@ -78,15 +90,19 @@
 static int __init
 setup_io_tlb_npages (char *str)
 {
-	io_tlb_nslabs = simple_strtoul(str, NULL, 0) << (PAGE_SHIFT - IO_TLB_SHIFT);
-
-	/* avoid tail segment of size < IO_TLB_SEGSIZE */
-	io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
-
+	if (isdigit(*str)) { 
+		io_tlb_nslabs = simple_strtoul(str, &str, 0) << (PAGE_SHIFT - IO_TLB_SHIFT);
+		/* avoid tail segment of size < IO_TLB_SEGSIZE */
+		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
+	}
+	if (*str == ',')
+		++str;
+	if (!strcmp(str, "force"))
+		swiotlb_force = 1;
 	return 1;
 }
 __setup("swiotlb=", setup_io_tlb_npages);
-
+/* make io_tlb_overflow tunable too? */
 
 /*
  * Statically reserve bounce buffer space and initialize bounce buffer data structures for
@@ -102,7 +118,7 @@
 	 */
 	io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
 	if (!io_tlb_start)
-		BUG();
+		panic("Cannot allocate SWIOTLB buffer");
 	io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
 
 	/*
@@ -115,10 +131,22 @@
  		io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
 	io_tlb_index = 0;
 	io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
-
-	printk(KERN_INFO "Placing software IO TLB between 0x%p - 0x%p\n",
-	       (void *) io_tlb_start, (void *) io_tlb_end);
-}
+	
+	/* 
+	 * Get the overflow emergency buffer 
+	 */
+	io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow); 
+	printk(KERN_INFO "Placing software IO TLB between 0x%lx - 0x%lx\n",
+	       virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
+}
+
+static inline int address_needs_mapping(struct device *hwdev, dma_addr_t addr)
+{ 
+	dma_addr_t mask = 0xffffffff; 
+	if (hwdev && hwdev->dma_mask) 
+		mask = *hwdev->dma_mask; 
+	return (addr & ~mask) != 0; 		
+} 
 
 /*
  * Allocates bounce buffer and returns its kernel virtual address.
@@ -184,11 +212,8 @@
 				index = 0;
 		} while (index != wrap);
 
-		/*
-		 * XXX What is a suitable recovery mechanism here?  We cannot
-		 * sleep because we are called from with in interrupts!
-		 */
-		panic("map_single: could not allocate software IO TLB (%ld bytes)", size);
+		spin_unlock_irqrestore(&io_tlb_lock, flags);
+		return NULL;
 	}
   found:
 	spin_unlock_irqrestore(&io_tlb_lock, flags);
@@ -285,7 +310,7 @@
 
 	memset(ret, 0, size);
 	dev_addr = virt_to_phys(ret);
-	if (hwdev && hwdev->dma_mask && (dev_addr & ~*hwdev->dma_mask) != 0)
+	if (address_needs_mapping(hwdev,dev_addr))
 		panic("swiotlb_alloc_consistent: allocated memory is out of range for device");
 	*dma_handle = dev_addr;
 	return ret;
@@ -297,6 +322,28 @@
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
+static void swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
+{
+	/* 
+	 * Ran out of IOMMU space for this operation. This is very bad.
+	 * Unfortunately the drivers cannot handle this operation properly.
+	 * unless they check for pci_dma_mapping_error (most don't)
+	 * When the mapping is small enough return a static buffer to limit
+	 * the damage, or panic when the transfer is too big. 
+	 */ 
+	
+	printk(KERN_ERR 
+  "PCI-DMA: Out of SW-IOMMU space for %lu bytes at device %s\n",
+	       size, dev ? dev->bus_id : "?");
+
+	if (size > io_tlb_overflow && do_panic) {
+		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
+			panic("PCI-DMA: Memory would be corrupted\n");
+		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) 
+			panic("PCI-DMA: Random memory would be DMAed\n"); 
+	} 
+} 
+
 /*
  * Map a single buffer of the indicated size for DMA in streaming mode.  The PCI address
  * to use is returned.
@@ -308,13 +355,14 @@
 swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, int dir)
 {
 	unsigned long dev_addr = virt_to_phys(ptr);
+	void *map; 
 
 	if (dir == DMA_NONE)
 		BUG();
 	/*
 	 * Check if the PCI device can DMA to ptr... if so, just return ptr
 	 */
-	if (hwdev && hwdev->dma_mask && (dev_addr & ~*hwdev->dma_mask) == 0)
+	if (!address_needs_mapping(hwdev, dev_addr) && !swiotlb_force) 
 		/*
 		 * Device is bit capable of DMA'ing to the buffer... just return the PCI
 		 * address of ptr
@@ -324,12 +372,18 @@
 	/*
 	 * get a bounce buffer:
 	 */
-	dev_addr = virt_to_phys(map_single(hwdev, ptr, size, dir));
+	map = map_single(hwdev, ptr, size, dir);
+	if (!map) { 
+		swiotlb_full(hwdev, size, dir, 1);		
+		map = io_tlb_overflow_buffer; 
+	}
+
+	dev_addr = virt_to_phys(map);
 
 	/*
 	 * Ensure that the address returned is DMA'ble:
 	 */
-	if (hwdev && hwdev->dma_mask && (dev_addr & ~*hwdev->dma_mask) != 0)
+	if (address_needs_mapping(hwdev, dev_addr))
 		panic("map_single: bounce buffer is not DMA'ble");
 
 	return dev_addr;
@@ -437,9 +491,17 @@
 	for (i = 0; i < nelems; i++, sg++) {
 		addr = SG_ENT_VIRT_ADDRESS(sg);
 		dev_addr = virt_to_phys(addr);
-		if (hwdev && hwdev->dma_mask && (dev_addr & ~*hwdev->dma_mask) != 0)
-			sg->dma_address = (dma_addr_t) map_single(hwdev, addr, sg->length, dir);
-		else
+		if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
+			sg->dma_address = (dma_addr_t) virt_to_phys(map_single(hwdev, addr, sg->length, dir));
+			if (!sg->dma_address) {
+				/* Don't panic here, we expect pci_map_sg users
+				   to do proper error handling. */
+				swiotlb_full(hwdev, sg->length, dir, 0); 
+				swiotlb_unmap_sg(hwdev, sg - i, i, dir);
+				sg[0].dma_length = 0;
+				return 0;
+			}
+		} else
 			sg->dma_address = dev_addr;
 		sg->dma_length = sg->length;
 	}
@@ -460,7 +522,7 @@
 
 	for (i = 0; i < nelems; i++, sg++)
 		if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
-			unmap_single(hwdev, (void *) sg->dma_address, sg->dma_length, dir);
+			unmap_single(hwdev, (void *) phys_to_virt(sg->dma_address), sg->dma_length, dir);
 		else if (dir == DMA_FROM_DEVICE)
 			mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
 }
@@ -501,7 +563,7 @@
 int
 swiotlb_dma_mapping_error (dma_addr_t dma_addr)
 {
-	return 0;
+	return (dma_addr == virt_to_phys(io_tlb_overflow_buffer));
 }
 
 /*
diff -Nru a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
--- a/arch/ia64/mm/contig.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/mm/contig.c	2004-08-25 19:44:40 -07:00
@@ -116,19 +116,19 @@
 		range_start = max(start, free_start);
 		range_end   = min(end, rsvd_region[i].start & PAGE_MASK);
 
+		free_start = PAGE_ALIGN(rsvd_region[i].end);
+
 		if (range_end <= range_start)
 			continue; /* skip over empty range */
 
-	       	if (range_end - range_start >= needed) {
+		if (range_end - range_start >= needed) {
 			bootmap_start = __pa(range_start);
-			return 1;	/* done */
+			return -1;	/* done */
 		}
 
 		/* nothing more available in this segment */
 		if (range_end == end)
 			return 0;
-
-		free_start = PAGE_ALIGN(rsvd_region[i].end);
 	}
 	return 0;
 }
diff -Nru a/arch/ia64/sn/fakeprom/Makefile b/arch/ia64/sn/fakeprom/Makefile
--- a/arch/ia64/sn/fakeprom/Makefile	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,29 +0,0 @@
-# arch/ia64/sn/fakeprom/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-#  Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
-#
-# Medusa fake PROM support
-#
-
-EXTRA_TARGETS := fpromasm.o main.o fw-emu.o fpmem.o klgraph_init.o \
-		 fprom vmlinux.sym
-
-OBJS := $(obj)/fpromasm.o $(obj)/main.o $(obj)/fw-emu.o $(obj)/fpmem.o \
-	$(obj)/klgraph_init.o
-
-LDFLAGS_fprom = -static -T
-
-.PHONY: fprom
-
-fprom: $(obj)/fprom
-
-$(obj)/fprom: $(src)/fprom.lds $(OBJS) arch/ia64/lib/lib.a FORCE
-	$(call if_changed,ld)
-
-$(obj)/vmlinux.sym: $(src)/make_textsym System.map
-	$(src)/make_textsym vmlinux > vmlinux.sym
-	$(call cmd,cptotop)
diff -Nru a/arch/ia64/sn/fakeprom/README b/arch/ia64/sn/fakeprom/README
--- a/arch/ia64/sn/fakeprom/README	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,93 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-This directory contains the files required to build
-the fake PROM image that is currently being used to
-boot IA64 kernels running under the SGI Medusa kernel.
-
-The FPROM currently provides the following functions:
-
-	- PAL emulation for all PAL calls we've made so far.
-	- SAL emulation for all SAL calls we've made so far.
-	- EFI emulation for all EFI calls we've made so far.
-	- builds the "ia64_bootparam" structure that is
-	  passed to the kernel from SAL. This structure 
-	  shows the cpu & memory configurations.
-	- supports medusa boottime options for changing
-	  the number of cpus present
-	- supports medusa boottime options for changing
-	  the memory configuration.
-
-
-
-At some point, this fake PROM will be replaced by the
-real PROM.
-
-
-
-
-To build a fake PROM, cd to this directory & type:
-
-	make
-
-This will (or should) build a fake PROM named "fprom".
-
-
-
-
-Use this fprom image when booting the Medusa simulator. The
-control file used to boot Medusa should include the 
-following lines:
-
-	load fprom
-	load vmlinux
-	sr pc 0x100000
-	sr g 9 <address of kernel _start function> #(currently 0xe000000000520000)
-
-NOTE: There is a script "runsim" in this directory that can be used to
-simplify setting up an environment for running under Medusa.
-
-
-
-
-The following parameters may be passed to the fake PROM to
-control the PAL/SAL/EFI parameters passed to the kernel:
-
-	GR[8] = # of cpus
-	GR[9] = address of primary entry point into the kernel
-	GR[20] = memory configuration for node 0
-	GR[21] = memory configuration for node 1
-	GR[22] = memory configuration for node 2
-	GR[23] = memory configuration for node 3
-
-
-Registers GR[20] - GR[23] contain information to specify the
-amount of memory present on nodes 0-3.
-
-  - if nothing is specified (all registers are 0), the configuration
-    defaults to 8 MB on node 0.
-
-  - a mem config entry for node N is passed in GR[20+N]
-
-  - a mem config entry consists of 8 hex digits. Each digit gives the
-    amount of physical memory available on the node starting at
-    1GB*<dn>, where dn is the digit number. The amount of memory
-    is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
-
-    SN1 doesn't support dimms this small but small memory systems 
-    boot faster on Medusa.
-
-
-
-An example helps a lot. The following specifies that node 0 has
-physical memory 0 to 8MB and 1GB to 1GB+32MB, and that node 1 has
-64MB starting at address 0 of the node which is 8GB.
-
-      gr[20] = 0x21           # 0 to 8MB, 1GB to 1GB+32MB
-      gr[21] = 0x4            # 8GB to 8GB+64MB
-
diff -Nru a/arch/ia64/sn/fakeprom/fpmem.c b/arch/ia64/sn/fakeprom/fpmem.c
--- a/arch/ia64/sn/fakeprom/fpmem.c	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,252 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
- */
-
-
-
-/*
- * FPROM EFI memory descriptor build routines
- *
- * 	- Routines to build the EFI memory descriptor map
- * 	- Should also be usable by the SGI prom to convert
- * 	  klconfig to efi_memmap
- */
-
-#include <linux/config.h>
-#include <linux/efi.h>
-#include "fpmem.h"
-
-/*
- * args points to a layout in memory like this
- *
- *		32 bit		32 bit
- *
- * 		numnodes	numcpus
- *
- *		16 bit   16 bit		   32 bit
- *		nasid0	cpuconf		membankdesc0
- *		nasid1	cpuconf		membankdesc1
- *			   .
- *			   .
- *			   .
- *			   .
- *			   .
- */
-
-sn_memmap_t	*sn_memmap ;
-sn_config_t	*sn_config ;
-
-/*
- * There is a hole in the node 0 address space. Dont put it
- * in the memory map
- */
-#define NODE0_HOLE_SIZE         (20*MB)
-#define NODE0_HOLE_END          (4UL*GB)
-
-#define	MB			(1024*1024)
-#define GB			(1024*MB)
-#define KERNEL_SIZE		(4*MB)
-#define PROMRESERVED_SIZE	(1*MB)
-
-#ifdef SGI_SN2
-#define PHYS_ADDRESS(_n, _x)		(((long)_n<<38) | (long)_x | 0x3000000000UL)
-#define MD_BANK_SHFT 34
-#endif
-
-/*
- * For SN, this may not take an arg and gets the numnodes from 
- * the prom variable or by traversing klcfg or promcfg
- */
-int
-GetNumNodes(void)
-{
-	return sn_config->nodes;
-}
-
-int
-GetNumCpus(void)
-{
-	return sn_config->cpus;
-}
-
-/* For SN, get the index th nasid */
-
-int
-GetNasid(int index)
-{
-	return sn_memmap[index].nasid ;
-}
-
-node_memmap_t
-GetMemBankInfo(int index)
-{
-	return sn_memmap[index].node_memmap ;
-}
-
-int
-IsCpuPresent(int cnode, int cpu)
-{
-	return  sn_memmap[cnode].cpuconfig & (1UL<<cpu);
-}
-
-
-/*
- * Made this into an explicit case statement so that
- * we can assign specific properties to banks like bank0
- * actually disabled etc.
- */
-
-#ifdef SGI_SN2
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return BankPresent(nmemmap.b0size);
-		case 1:return BankPresent(nmemmap.b1size);
-		case 2:return BankPresent(nmemmap.b2size);
-		case 3:return BankPresent(nmemmap.b3size);
-		default:return -1 ;
-	}
-}
-
-int
-GetBankSize(int index, node_memmap_t nmemmap)
-{
-	/*
-	 * Add 2 because there are 4 dimms per bank.
-	 */
-        switch (index) {
-                case 0:return 2 + ((long)nmemmap.b0size + nmemmap.b0dou);
-                case 1:return 2 + ((long)nmemmap.b1size + nmemmap.b1dou);
-                case 2:return 2 + ((long)nmemmap.b2size + nmemmap.b2dou);
-                case 3:return 2 + ((long)nmemmap.b3size + nmemmap.b3dou);
-                default:return -1 ;
-        }
-}
-
-#endif
-
-void
-build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes, long attr)
-{
-        md->type = type;
-        md->phys_addr = paddr;
-        md->virt_addr = 0;
-        md->num_pages = numbytes >> 12;
-        md->attribute = attr;
-}
-
-int
-build_efi_memmap(void *md, int mdsize)
-{
-	int		numnodes = GetNumNodes() ;
-	int		cnode,bank ;
-	int		nasid ;
-	node_memmap_t	membank_info ;
-	int		bsize;
-	int		count = 0 ;
-	long		paddr, hole, numbytes;
-
-
-	for (cnode=0;cnode<numnodes;cnode++) {
-		nasid = GetNasid(cnode) ;
-		membank_info = GetMemBankInfo(cnode) ;
-		for (bank=0;bank<MD_BANKS_PER_NODE;bank++) {
-			if (IsBankPresent(bank, membank_info)) {
-				bsize = GetBankSize(bank, membank_info) ;
-                                paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
-                                numbytes = BankSizeBytes(bsize);
-#ifdef SGI_SN2
-				/* 
-				 * Ignore directory.
-				 * Shorten memory chunk by 1 page - makes a better
-				 * testcase & is more like the real PROM.
-				 */
-				numbytes = numbytes * 31 / 32;
-#endif
-				/*
-				 * Only emulate the memory prom grabs
-				 * if we have lots of memory, to allow
-				 * us to simulate smaller memory configs than
-				 * we can actually run on h/w.  Otherwise,
-				 * linux throws away a whole "granule".
-				 */
-				if (cnode == 0 && bank == 0 &&
-				    numbytes > 128*1024*1024) {
-					numbytes -= 1000;
-				}
-
-                                /*
-                                 * Check for the node 0 hole. Since banks cant
-                                 * span the hole, we only need to check if the end of
-                                 * the range is the end of the hole.
-                                 */
-                                if (paddr+numbytes == NODE0_HOLE_END)
-                                        numbytes -= NODE0_HOLE_SIZE;
-                                /*
-                                 * UGLY hack - we must skip overr the kernel and
-                                 * PROM runtime services but we dont exactly where it is.
-                                 * So lets just reserve:
-				 *	node 0
-				 *		0-1MB for PAL
-				 *		1-4MB for SAL
-				 *	node 1-N
-				 *		0-1 for SAL
-                                 */
-                                if (bank == 0) {
-					if (cnode == 0) {
-						hole = 2*1024*1024;
-						build_mem_desc(md, EFI_PAL_CODE, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
-						numbytes -= hole;
-                                        	paddr += hole;
-			        		count++ ;
-                                        	md += mdsize;
-						hole = 1*1024*1024;
-						build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, hole, EFI_MEMORY_UC);
-						numbytes -= hole;
-                                        	paddr += hole;
-			        		count++ ;
-                                        	md += mdsize;
-						hole = 1*1024*1024;
-						build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
-						numbytes -= hole;
-                                        	paddr += hole;
-			        		count++ ;
-                                        	md += mdsize;
-					} else {
-						hole = 2*1024*1024;
-                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
-						numbytes -= hole;
-                                        	paddr += hole;
-			        		count++ ;
-                                        	md += mdsize;
-						hole = 2*1024*1024;
-                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_UC);
-						numbytes -= hole;
-                                        	paddr += hole;
-			        		count++ ;
-                                        	md += mdsize;
-					}
-                                }
-                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes, EFI_MEMORY_WB|EFI_MEMORY_WB);
-
-			        md += mdsize ;
-			        count++ ;
-			}
-		}
-	}
-	return count ;
-}
-
-void
-build_init(unsigned long args)
-{
-	sn_config = (sn_config_t *) (args);	
-	sn_memmap = (sn_memmap_t *)(args + 8) ; /* SN equiv for this is */
-						/* init to klconfig start */
-}
diff -Nru a/arch/ia64/sn/fakeprom/fpmem.h b/arch/ia64/sn/fakeprom/fpmem.h
--- a/arch/ia64/sn/fakeprom/fpmem.h	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,76 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-
-/*
- * Structure of the mem config of the node as a SN MI reg
- * Medusa supports this reg config.
- *
- * BankSize nibble to bank size mapping
- *
- *      1 - 64 MB
- *      2 - 128 MB
- *      3 - 256 MB
- *      4 - 512 MB
- *      5 - 1024 MB (1GB)
- */
-
-#define MBSHIFT				20
-
-#ifdef SGI_SN2
-typedef struct node_memmap_s
-{
-        unsigned int    b0size  :3,     /* 0-2   bank 0 size */
-                        b0dou   :1,     /* 3     bank 0 is 2-sided */
-                        ena0    :1,     /* 4     bank 0 enabled */
-                        r0      :3,     /* 5-7   reserved */
-        		b1size  :3,     /* 8-10  bank 1 size */
-                        b1dou   :1,     /* 11    bank 1 is 2-sided */
-                        ena1    :1,     /* 12    bank 1 enabled */
-                        r1      :3,     /* 13-15 reserved */
-        		b2size  :3,     /* 16-18 bank 2 size */
-                        b2dou   :1,     /* 19    bank 1 is 2-sided */
-                        ena2    :1,     /* 20    bank 2 enabled */
-                        r2      :3,     /* 21-23 reserved */
-        		b3size  :3,     /* 24-26 bank 3 size */
-                        b3dou   :1,     /* 27    bank 3 is 2-sided */
-                        ena3    :1,     /* 28    bank 3 enabled */
-                        r3      :3;     /* 29-31 reserved */
-} node_memmap_t ;
-
-#define SN2_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
-#define BankPresent(bsize)		(bsize<6)
-#define BankSizeBytes(bsize)            (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
-#define MD_BANKS_PER_NODE 4
-#define MD_BANKSIZE			(1UL << 34)
-#endif
-
-typedef struct sn_memmap_s
-{
-	short		nasid ;
-	short		cpuconfig;
-	node_memmap_t 	node_memmap ;
-} sn_memmap_t ;
-
-typedef struct sn_config_s
-{
-	int		cpus;
-	int		nodes;
-	sn_memmap_t	memmap[1];		/* start of array */
-} sn_config_t;
-
-
-
-extern void build_init(unsigned long);
-extern int build_efi_memmap(void *, int);
-extern int GetNumNodes(void);
-extern int GetNumCpus(void);
-extern int IsCpuPresent(int, int);
-extern int GetNasid(int);
diff -Nru a/arch/ia64/sn/fakeprom/fprom.lds b/arch/ia64/sn/fakeprom/fprom.lds
--- a/arch/ia64/sn/fakeprom/fprom.lds	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,103 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-OUTPUT_FORMAT("elf64-ia64-little")
-OUTPUT_ARCH(ia64)
-ENTRY(_start)
-SECTIONS
-{
-  v = 0x0000000000000000 ;	/* this symbol is here to make debugging with kdb easier... */
-
-  . = (0x000000000000000  + 0x100000) ;
-
-  _text = .;
-  .text : AT(ADDR(.text) - 0x0000000000000000 )
-    {
-	*(__ivt_section)
-	/* these are not really text pages, but the zero page needs to be in a fixed location: */
-	*(__special_page_section)
-	__start_gate_section = .;
-	*(__gate_section)
-	__stop_gate_section = .;
-	*(.text)
-    }
-
-  /* Global data */
-  _data = .;
-
-  .rodata : AT(ADDR(.rodata) - 0x0000000000000000 )
-	{ *(.rodata) *(.rodata.*) }
-  .opd : AT(ADDR(.opd) - 0x0000000000000000 )
-	{ *(.opd) }
-  .data : AT(ADDR(.data) - 0x0000000000000000 )
-	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
-
-  __gp = ALIGN (8) + 0x200000;
-
-  .got : AT(ADDR(.got) - 0x0000000000000000 )
-	{ *(.got.plt) *(.got) }
-  /* We want the small data sections together, so single-instruction offsets
-     can access them all, and initialized data all before uninitialized, so
-     we can shorten the on-disk segment size.  */
-  .sdata : AT(ADDR(.sdata) - 0x0000000000000000 )
-	{ *(.sdata) }
-  _edata  =  .;
-  _bss = .;
-  .sbss : AT(ADDR(.sbss) - 0x0000000000000000 )
-	{ *(.sbss) *(.scommon) }
-  .bss : AT(ADDR(.bss) - 0x0000000000000000 )
-	{ *(.bss) *(COMMON) }
-  . = ALIGN(64 / 8);
-  _end = .;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	*(.text.exit)
-	*(.data.exit)
-	}
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  /* DWARF debug sections.
-     Symbols in the DWARF debugging sections are relative to the beginning
-     of the section so we begin them at 0.  */
-  /* DWARF 1 */
-  .debug          0 : { *(.debug) }
-  .line           0 : { *(.line) }
-  /* GNU DWARF 1 extensions */
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  /* DWARF 1.1 and DWARF 2 */
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  /* DWARF 2 */
-  .debug_info     0 : { *(.debug_info) }
-  .debug_abbrev   0 : { *(.debug_abbrev) }
-  .debug_line     0 : { *(.debug_line) }
-  .debug_frame    0 : { *(.debug_frame) }
-  .debug_str      0 : { *(.debug_str) }
-  .debug_loc      0 : { *(.debug_loc) }
-  .debug_macinfo  0 : { *(.debug_macinfo) }
-  /* SGI/MIPS DWARF 2 extensions */
-  .debug_weaknames 0 : { *(.debug_weaknames) }
-  .debug_funcnames 0 : { *(.debug_funcnames) }
-  .debug_typenames 0 : { *(.debug_typenames) }
-  .debug_varnames  0 : { *(.debug_varnames) }
-  /* These must appear regardless of  .  */
-  /* Discard them for now since Intel SoftSDV cannot handle them.
-  .comment 0 : { *(.comment) }
-  .note 0 : { *(.note) }
-  */
-  /DISCARD/ : { *(.comment) }
-  /DISCARD/ : { *(.note) }
-}
diff -Nru a/arch/ia64/sn/fakeprom/fpromasm.S b/arch/ia64/sn/fakeprom/fpromasm.S
--- a/arch/ia64/sn/fakeprom/fpromasm.S	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,395 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *   (Code copied from or=ther files)
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-
-#define __ASSEMBLY__ 1
-#include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn2/shub_mmr.h>
-
-/*
- * This file contains additional set up code that is needed to get going on
- * Medusa.  This code should disappear once real hw is available.
- *
- * On entry to this routine, the following register values are assumed:
- *
- *	gr[8]	- BSP cpu
- *	pr[9]	- kernel entry address
- *	pr[10]	- cpu number on the node
- *
- * NOTE:
- *   This FPROM may be loaded/executed at an address different from the
- *   address that it was linked at. The FPROM is linked to run on node 0
- *   at address 0x100000. If the code in loaded into another node, it
- *   must be loaded at offset 0x100000 of the node. In addition, the
- *   FPROM does the following things:
- *		- determine the base address of the node it is loaded on
- *		- add the node base to _gp.
- *		- add the node base to all addresses derived from "movl" 
- *		  instructions. (I couldnt get GPREL addressing to work)
- *		  (maybe newer versions of the tools will support this)
- *		- scan the .got section and add the node base to all
- *		  pointers in this section.
- *		- add the node base to all physical addresses in the
- *		  SAL/PAL/EFI table built by the C code. (This is done
- *		  in the C code - not here)
- *		- add the node base to the TLB entries for vmlinux
- */
-
-#define KERNEL_BASE	0xe000000000000000
-#define BOOT_PARAM_ADDR 0x40000
-
-
-/* 
- * ar.k0 gets set to IOPB_PA value, on 460gx chipset it should 
- * be 0x00000ffffc000000, but on snia we use the (inverse swizzled)
- * IOSPEC_BASE value
- */
-#ifdef SGI_SN2
-#define IOPB_PA		0xc000000fcc000000
-#endif
-
-#define RR_RID		8
-
-
-
-// ====================================================================================	
-        .text
-        .align 16
-	.global _start
-	.proc _start
-_start:
-
-// Setup psr and rse for system init
-	mov		psr.l = r0;;
-	srlz.d;;
-	invala
-	mov		ar.rsc = r0;;
-	loadrs
-	;;
-
-// Isolate node number we are running on.
-	mov		r6 = ip;;
-#ifdef SGI_SN2
-	shr		r5 = r6,38			// r5 = node number
-	dep		r6 = 0,r6,0,36			// r6 = base memory address of node
-
-#endif
-
-
-// Set & relocate gp.
-	movl		r1= __gp;;			// Add base memory address
-	or 		r1 = r1,r6			// Relocate to boot node
-
-// Lets figure out who we are & put it in the LID register.
-#ifdef SGI_SN2
-// On SN2, we (currently) pass the cpu number in r10 at boot
-	and		r25=3,r10;;
-	movl		r16=0x8000008110000400		// Allow IPIs
-	mov		r17=-1;;
-	st8		[r16]=r17
-	movl		r16=0x8000008110060580;;	// SHUB_ID
-	ld8		r27=[r16];;
-	extr.u		r27=r27,32,11;;
-	shl 		r26=r25,28;;			// Align local cpu# to lid.eid
-	shl 		r27=r27,16;;			// Align NASID to lid.id
-	or  		r26=r26,r27;;			// build the LID
-#else
-// The BR_PI_SELF_CPU_NUM register gives us a value of 0-3.
-// This identifies the cpu on the node. 
-// Merge the cpu number with the NASID to generate the LID.
-	movl		r24=0x80000a0001000020;;	// BR_PI_SELF_CPU_NUM
-	ld8 		r25=[r24]			// Fetch PI_SELF
-	movl		r27=0x80000a0001600000;;	// Fetch REVID to get local NASID
-	ld8 		r27=[r27];;
-	extr.u		r27=r27,32,8;;
-	shl 		r26=r25,16;;			// Align local cpu# to lid.eid
-	shl 		r27=r27,24;;			// Align NASID to lid.id
-	or  		r26=r26,r27;;			// build the LID
-#endif
-	mov 		cr.lid=r26			// Now put in in the LID register
-
-	movl		r2=FPSR_DEFAULT;;
-	mov 		ar.fpsr=r2
-	movl		sp = bootstacke-16;;
-	or 		sp = sp,r6			// Relocate to boot node			
-
-// Save the NASID that we are loaded on.
-	movl		r2=base_nasid;;			// Save base_nasid for C code
-	or 		r2 = r2,r6;;			// Relocate to boot node
-  	st8 		[r2]=r5				// Uncond st8 - same on all cpus
-
-// Save the kernel entry address. It is passed in r9 on one of
-// the cpus.
-	movl		r2=bsp_entry_pc
-	cmp.ne		p6,p0=r9,r0;;
-	or 		r2 = r2,r6;;			// Relocate to boot node
-(p6)  	st8 		[r2]=r9				// Uncond st8 - same on all cpus
-
-
-// The following can ONLY be done by 1 cpu. Lets set a lock - the
-// cpu that gets it does the initilization. The rest just spin waiting
-// til initilization is complete.
-	movl		r22 = initlock;;
-	or		r22 = r22,r6			// Relocate to boot node
-	mov		r23 = 1;;
-	xchg8		r23 = [r22],r23;;
-	cmp.eq 		p6,p0 = 0,r23
-(p6)	br.cond.spnt.few init
-1:	ld4		r23 = [r22];;
-	cmp.eq		p6,p0 = 1,r23
-(p6)	br.cond.sptk	1b
-	br		initx
-
-// Add base address of node memory to each pointer in the .got section.
-init:	movl		r16 = _GLOBAL_OFFSET_TABLE_;;
-	or		r16 = r16,r6;;			// Relocate to boot node
-1: 	ld8		r17 = [r16];;
-	cmp.eq		p6,p7=0,r17
-(p6)	br.cond.sptk.few.clr 2f;;
-	or		r17 = r17,r6;;			// Relocate to boot node
-	st8		[r16] = r17,8
-	br		1b
-2:
-	mov		r23 = 2;;			// All done, release the spinning cpus
-	st4		[r22] = r23
-initx:
-
-//
-//	I/O-port space base address:
-//
-	movl		r2 = IOPB_PA;;
-	mov		ar.k0 = r2
-
-
-// Now call main & pass it the current LID value.
-	alloc 		r2=ar.pfs,0,0,2,0
-	mov    		r32=r26
-	mov   		r33=r8;;
-	br.call.sptk.few rp=fmain
-	
-// Initialize Region Registers
-//
-        mov             r10 = r0
-        mov             r2 = (13<<2)
-        mov             r3 = r0;;
-1:      cmp4.gtu        p6,p7 = 7, r3
-        dep             r10 = r3, r10, 61, 3
-        dep             r2 = r3, r2, RR_RID, 4;;
-(p7)    dep             r2 = 0, r2, 0, 1;;
-(p6)    dep             r2 = -1, r2, 0, 1;;
-        mov             rr[r10] = r2
-        add             r3 = 1, r3;;
-        srlz.d;;
-        cmp4.gtu        p6,p0 = 8, r3
-(p6)    br.cond.sptk.few.clr 1b
-
-//
-// Return value indicates if we are the BSP or AP.
-// 	   1 = BSP, 0 = AP
-	mov             cr.tpr=r0;;
-	cmp.eq		p6,p0=r8,r0
-(p6)	br.cond.spnt	slave
-
-//
-// Go to kernel C startup routines
-//	Need to do a "rfi" in order set "it" and "ed" bits in the PSR.
-//	This is the only way to set them.
-
-	movl		r28=BOOT_PARAM_ADDR
-	movl		r2=bsp_entry_pc;;
-	or 		r28 = r28,r6;;			// Relocate to boot node
-	or 		r2 = r2,r6;;			// Relocate to boot node
-	ld8		r2=[r2];;
-	or		r2=r2,r6;;
-	dep		r2=0,r2,61,3;;			// convert to phys mode
-
-//
-// Turn on address translation, interrupt collection, psr.ed, protection key.
-// Interrupts (PSR.i) are still off here.
-//
-
-        movl            r3 = (  IA64_PSR_BN | \
-                                IA64_PSR_AC | \
-                                IA64_PSR_DB | \
-                                IA64_PSR_DA | \
-                                IA64_PSR_IC   \
-                             )
-        ;;
-        mov             cr.ipsr = r3
-
-//
-// Go to kernel C startup routines
-//      Need to do a "rfi" in order set "it" and "ed" bits in the PSR.
-//      This is the only way to set them.
-
-	mov		r8=r28;;
-	bsw.1		;;
-	mov		r28=r8;;
-	bsw.0		;;
-        mov             cr.iip = r2
-        srlz.d;;
-        rfi;;
-
-	.endp		_start
-
-
-
-// Slave processors come here to spin til they get an interrupt. Then they launch themselves to
-// the place ap_entry points. No initialization is necessary - the kernel makes no
-// assumptions about state on this entry.
-//	Note: should verify that the interrupt we got was really the ap_wakeup
-//	      interrupt but this should not be an issue on medusa
-slave:
-	nop.i		0x8beef				// Medusa - put cpu to sleep til interrupt occurs
-	mov		r8=cr.irr0;;			// Check for interrupt pending.
-	cmp.eq		p6,p0=r8,r0
-(p6)	br.cond.sptk	slave;;
-
-	mov		r8=cr.ivr;;			// Got one. Must read ivr to accept it
-	srlz.d;;
-	mov		cr.eoi=r0;;			// must write eoi to clear
-	movl		r8=ap_entry;;			// now jump to kernel entry
-	or 		r8 = r8,r6;;			// Relocate to boot node
-	ld8		r9=[r8],8;;
-	ld8		r1=[r8]
-	mov		b0=r9;;
-	br		b0
-
-// Here is the kernel stack used for the fake PROM
-	.bss
-	.align		16384
-bootstack:
-	.skip		16384
-bootstacke:
-initlock:
-	data4
-
-
-
-//////////////////////////////////////////////////////////////////////////////////////////////////////////
-// This code emulates the PAL. Only essential interfaces are emulated.
-
-
-	.text
-	.global	pal_emulator
-	.proc	pal_emulator
-pal_emulator:
-	mov	r8=-1
-
-	mov	r9=256
-	;;
-	cmp.gtu p6,p7=r9,r28		/* r28 <= 255? */
-(p6)	br.cond.sptk.few static
-	;;
-	mov	r9=512
-	;;
-	cmp.gtu p6,p7=r9,r28
-(p6)	br.cond.sptk.few stacked
-	;;
-
-static:	cmp.eq	p6,p7=6,r28		/* PAL_PTCE_INFO */
-(p7)	br.cond.sptk.few 1f
-	movl	r8=0				/* status = 0 */
-	movl	r9=0x100000000			/* tc.base */
-	movl	r10=0x0000000200000003		/* count[0], count[1] */
-	movl	r11=0x1000000000002000		/* stride[0], stride[1] */
-	;;
-
-1:	cmp.eq	p6,p7=14,r28		/* PAL_FREQ_RATIOS */
-(p7)	br.cond.sptk.few 1f
-	movl	r8=0				/* status = 0 */
-	movl	r9 =0x100000064			/* proc_ratio (1/100) */
-	movl	r10=0x100000100			/* bus_ratio<<32 (1/256) */
-	movl	r11=0x10000000a			/* itc_ratio<<32 (1/100) */
-	;;
-
-1:	cmp.eq	p6,p7=8,r28		/* PAL_VM_SUMMARY */
-(p7)	br.cond.sptk.few 1f
-	movl	r8=0
-#ifdef SGI_SN2
-	movl	r9=0x0203083001151065
-	movl	r10=0x183f
-#endif
-	movl	r11=0
-	;;
-
-1:	cmp.eq	p6,p7=19,r28		/* PAL_RSE_INFO */
-(p7)	br.cond.sptk.few 1f
-	movl	r8=0
-	movl	r9=0x60
-	movl	r10=0x0
-	movl	r11=0
-	;;
-
-1:	cmp.eq	p6,p7=15,r28		/* PAL_PERF_MON_INFO */
-(p7)	br.cond.sptk.few 1f
-	movl	r8=0
-	movl	r9=0x08122004
-	movl	r10=0x0
-	movl	r11=0
-	mov	r2=ar.lc
-	mov	r3=16;;
-	mov	ar.lc=r3
-	mov	r3=r29;;
-5:	st8	[r3]=r0,8
-	br.cloop.sptk.few 5b;;
-	mov	ar.lc=r2
-	mov	r3=r29
-	movl	r2=0x1fff;;			/* PMC regs */
-	st8	[r3]=r2
-	add	r3=32,r3
-	movl	r2=0x3ffff;;			/* PMD regs */
-	st8	[r3]=r2
-	add	r3=32,r3
-	movl	r2=0xf0;;			/* cycle regs */
-	st8	[r3]=r2
-	add	r3=32,r3
-	movl	r2=0x10;;			/* retired regs */
-	st8	[r3]=r2
-	;;
-
-1:	cmp.eq	p6,p7=19,r28		/* PAL_RSE_INFO */
-(p7)	br.cond.sptk.few 1f
-	movl	r8=0				/* status = 0 */
-	movl	r9=96				/* num phys stacked */
-	movl	r10=0				/* hints */
-	movl	r11=0
-	;;
-
-1:	cmp.eq	p6,p7=1,r28		/* PAL_CACHE_FLUSH */
-(p7)	br.cond.sptk.few 1f
-	mov	r9=ar.lc
-	movl	r8=524288				/* flush 512k million cache lines (16MB) */
-	;;
-	mov	ar.lc=r8
-	movl	r8=0xe000000000000000
-	;;
-.loop:	fc	r8
-	add	r8=32,r8
-	br.cloop.sptk.few .loop
-	sync.i
-	;;
-	srlz.i
-	;;
-	mov	ar.lc=r9
-	mov	r8=r0
-1:	br.cond.sptk.few rp
-
-stacked:
-	br.ret.sptk.few rp
-
-	.endp pal_emulator
-
diff -Nru a/arch/ia64/sn/fakeprom/fw-emu.c b/arch/ia64/sn/fakeprom/fw-emu.c
--- a/arch/ia64/sn/fakeprom/fw-emu.c	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,775 +0,0 @@
-/*
- * PAL & SAL emulation.
- *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-#include <linux/config.h>
-#include <linux/efi.h>
-#include <linux/kernel.h>
-#include <asm/pal.h>
-#include <asm/sal.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/processor.h>
-#include <asm/sn/sn_cpuid.h>
-#ifdef SGI_SN2
-#include <asm/sn/sn2/addrs.h>
-#include <asm/sn/sn2/shub_mmr.h>
-#endif
-#include <linux/acpi.h>
-#include "fpmem.h"
-
-#define RSDP_NAME               "RSDP"
-#define RSDP_SIG                "RSD PTR "  /* RSDT Pointer signature */
-#define APIC_SIG                "APIC"      /* Multiple APIC Description Table */
-#define DSDT_SIG                "DSDT"      /* Differentiated System Description Table */
-#define FADT_SIG                "FACP"      /* Fixed ACPI Description Table */
-#define FACS_SIG                "FACS"      /* Firmware ACPI Control Structure */
-#define PSDT_SIG                "PSDT"      /* Persistent System Description Table */
-#define RSDT_SIG                "RSDT"      /* Root System Description Table */
-#define XSDT_SIG                "XSDT"      /* Extended  System Description Table */
-#define SSDT_SIG                "SSDT"      /* Secondary System Description Table */
-#define SBST_SIG                "SBST"      /* Smart Battery Specification Table */
-#define SPIC_SIG                "SPIC"      /* IOSAPIC table */
-#define SRAT_SIG                "SRAT"      /* SRAT table */
-#define SLIT_SIG                "SLIT"      /* SLIT table */
-#define BOOT_SIG                "BOOT"      /* Boot table */
-#define ACPI_SRAT_REVISION 1
-#define ACPI_SLIT_REVISION 1
-
-#define OEMID			"SGI"
-#ifdef SGI_SN2
-#define PRODUCT			"SN2"
-#define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)
-#endif
-
-#define MB	(1024*1024UL)
-#define GB	(MB*1024UL)
-#define BOOT_PARAM_ADDR 0x40000
-#define MAX(i,j)		((i) > (j) ? (i) : (j))
-#define MIN(i,j)		((i) < (j) ? (i) : (j))
-#define ALIGN8(p)		(((long)(p) +7) & ~7)
-
-#define FPROM_BUG()		do {while (1);} while (0)
-#define MAX_SN_NODES		128
-#define MAX_LSAPICS		512
-#define MAX_CPUS		512
-#define MAX_CPUS_NODE		4
-#define CPUS_PER_NODE		4
-#define CPUS_PER_FSB		2
-#define CPUS_PER_FSB_MASK	(CPUS_PER_FSB-1)
-
-#define NUM_EFI_DESCS		2
-
-#define RSDP_CHECKSUM_LENGTH	20
-
-typedef union ia64_nasid_va {
-        struct {
-#if defined(SGI_SN2)
-                unsigned long off   : 36;       /* intra-region offset */
-		unsigned long attr  :  2;
-		unsigned long nasid : 11;	/* NASID */
-		unsigned long off2  : 12;	/* fill */
-                unsigned long reg   :  3;       /* region number */
-#endif
-        } f;
-        unsigned long l;
-        void *p;
-} ia64_nasid_va;
-
-typedef struct {
-	unsigned long	pc;
-	unsigned long	gp;
-} func_ptr_t;
- 
-#define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
-#define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
-
-#if defined(SGI_SN2)
-#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;})
-#endif
-
-/*
- * The following variables are passed thru registersfrom the configuration file and
- * are set via the _start function.
- */
-long		base_nasid;
-long		num_cpus;
-long		bsp_entry_pc=0;
-long		num_nodes;
-long		app_entry_pc;
-int		bsp_lid;
-func_ptr_t	ap_entry;
-
-
-extern void pal_emulator(void);
-static efi_runtime_services_t    *efi_runtime_p;
-static char fw_mem[(  sizeof(efi_system_table_t)
-		    + sizeof(efi_runtime_services_t)
-		    + NUM_EFI_DESCS*sizeof(efi_config_table_t)
-		    + sizeof(struct ia64_sal_systab)
-		    + sizeof(struct ia64_sal_desc_entry_point)
-		    + sizeof(struct ia64_sal_desc_ap_wakeup)
-		    + sizeof(struct acpi20_table_rsdp)
-		    + sizeof(struct acpi_table_xsdt)
-		    + sizeof(struct acpi_table_slit)
-		    +   MAX_SN_NODES*MAX_SN_NODES+8
-		    + sizeof(struct acpi_table_madt)
-		    +   16*MAX_CPUS
-		    + (1+8*MAX_SN_NODES)*(sizeof(efi_memory_desc_t))
-		    + sizeof(struct acpi_table_srat)
-		    +   MAX_CPUS*sizeof(struct acpi_table_processor_affinity)
-		    +   MAX_SN_NODES*sizeof(struct acpi_table_memory_affinity)
-		    + sizeof(ia64_sal_desc_ptc_t) +
-		    + MAX_SN_NODES*sizeof(ia64_sal_ptc_domain_info_t) +
-		    + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) +
-		    + 1024)] __attribute__ ((aligned (8)));
-
-
-static efi_status_t
-efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
-{
-	if (tm) {
-		memset(tm, 0, sizeof(*tm));
-		tm->year = 2000;
-		tm->month = 2;
-		tm->day = 13;
-		tm->hour = 10;
-		tm->minute = 11;
-		tm->second = 12;
-	}
-
-	if (tc) {
-		tc->resolution = 10;
-		tc->accuracy = 12;
-		tc->sets_to_zero = 1;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static void
-efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
-{
-	while(1);	/* Is there a pseudo-op to stop medusa */
-}
-
-static efi_status_t
-efi_success (void)
-{
-	return EFI_SUCCESS;
-}
-
-static efi_status_t
-efi_unimplemented (void)
-{
-	return EFI_UNSUPPORTED;
-}
-
-#ifdef SGI_SN2
-
-#undef cpu_physical_id
-#define cpu_physical_id(cpuid)                  ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
-
-void
-fprom_send_cpei(void) {
-        long            *p, val;
-        long            physid;
-        long            nasid, slice;
-
-        physid = cpu_physical_id(0);
-        nasid = cpu_physical_id_to_nasid(physid);
-        slice = cpu_physical_id_to_slice(physid);
-
-        p = (long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT);
-        val =   (1UL<<SH_IPI_INT_SEND_SHFT) |
-                (physid<<SH_IPI_INT_PID_SHFT) |
-                ((long)0<<SH_IPI_INT_TYPE_SHFT) |
-                ((long)0x1e<<SH_IPI_INT_IDX_SHFT) |
-                (0x000feeUL<<SH_IPI_INT_BASE_SHFT);
-        *p = val;
-
-}
-#endif
-
-
-static struct sal_ret_values
-sal_emulator (long index, unsigned long in1, unsigned long in2,
-	      unsigned long in3, unsigned long in4, unsigned long in5,
-	      unsigned long in6, unsigned long in7)
-{
-	long r9  = 0;
-	long r10 = 0;
-	long r11 = 0;
-	long status;
-
-	/*
-	 * Don't do a "switch" here since that gives us code that
-	 * isn't self-relocatable.
-	 */
-	status = 0;
-	if (index == SAL_FREQ_BASE) {
-		switch (in1) {
-		      case SAL_FREQ_BASE_PLATFORM:
-			r9 = 500000000;
-			break;
-
-		      case SAL_FREQ_BASE_INTERVAL_TIMER:
-			/*
-			 * Is this supposed to be the cr.itc frequency
-			 * or something platform specific?  The SAL
-			 * doc ain't exactly clear on this...
-			 */
-			r9 = 700000000;
-			break;
-
-		      case SAL_FREQ_BASE_REALTIME_CLOCK:
-			r9 = 50000000;
-			break;
-
-		      default:
-			status = -1;
-			break;
-		}
-	} else if (index == SAL_SET_VECTORS) {
-		if (in1 == SAL_VECTOR_OS_BOOT_RENDEZ) {
-			func_ptr_t	*fp;
-			fp = ADDR_OF(&ap_entry);
-			fp->pc = in2;
-			fp->gp = in3;
-		} else if (in1 == SAL_VECTOR_OS_MCA || in1 == SAL_VECTOR_OS_INIT) {
-		} else {
-			status = -1;
-		}
-		;
-	} else if (index == SAL_GET_STATE_INFO) {
-		;
-	} else if (index == SAL_GET_STATE_INFO_SIZE) {
-		r9 = 10000;
-		;
-	} else if (index == SAL_CLEAR_STATE_INFO) {
-		;
-	} else if (index == SAL_MC_RENDEZ) {
-		;
-	} else if (index == SAL_MC_SET_PARAMS) {
-		;
-	} else if (index == SAL_CACHE_FLUSH) {
-		;
-	} else if (index == SAL_CACHE_INIT) {
-		;
-	} else if (index == SAL_UPDATE_PAL) {
-		;
-#ifdef SGI_SN2
-	} else if (index == SN_SAL_LOG_CE) {
-#ifdef ajmtestcpei
-		fprom_send_cpei();
-#else /* ajmtestcpei */
-		;
-#endif /* ajmtestcpei */
-#endif
-	} else if (index == SN_SAL_PROBE) {
-		r9 = 0UL;
-		if (in2 == 4) {
-			r9 = *(unsigned *)in1;
-			if (r9 == -1) {
-				status = 1;
-			}
-		} else if (in2 == 2) {
-			r9 = *(unsigned short *)in1;
-			if (r9 == -1) {
-				status = 1;
-			}
-		} else if (in2 == 1) {
-			r9 = *(unsigned char *)in1;
-			if (r9 == -1) {
-				status = 1;
-			}
-		} else if (in2 == 8) {
-			r9 = *(unsigned long *)in1;
-			if (r9 == -1) {
-				status = 1;
-			}
-		} else {
-			status = 2;
-		}
-	} else if (index == SN_SAL_GET_KLCONFIG_ADDR) {
-		r9 = 0x30000;
-	} else if (index == SN_SAL_CONSOLE_PUTC) {
-		status = -1;
-	} else if (index == SN_SAL_CONSOLE_GETC) {
-		status = -1;
-	} else if (index == SN_SAL_CONSOLE_POLL) {
-		status = -1;
-	} else if (index == SN_SAL_SYSCTL_IOBRICK_MODULE_GET) {
-		status = -1;
-	} else {
-		status = -1;
-	}
-
-	asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11));
-	return ((struct sal_ret_values) {status, r9, r10, r11});
-}
-
-
-/*
- * This is here to work around a bug in egcs-1.1.1b that causes the
- * compiler to crash (seems like a bug in the new alias analysis code.
- */
-void *
-id (long addr)
-{
-	return (void *) addr;
-}
-
-
-/*
- * Fix the addresses in a function pointer by adding base node address
- * to pc & gp.
- */
-void
-fix_function_pointer(void *fp)
-{
-	func_ptr_t	*_fp;
-
-	_fp = fp;
-	_fp->pc = __fwtab_pa(base_nasid, _fp->pc);
-	_fp->gp = __fwtab_pa(base_nasid, _fp->gp);
-}
-
-void
-fix_virt_function_pointer(void **fptr)
-{
-        func_ptr_t      *fp;
-	long		*p;
-
-	p = (long*)fptr;
-        fp = *fptr;
-        fp->pc = fp->pc | PAGE_OFFSET;
-        fp->gp = fp->gp | PAGE_OFFSET;
-	*p |= PAGE_OFFSET;
-}
-
-
-int
-efi_set_virtual_address_map(void)
-{
-        efi_runtime_services_t            *runtime;
-
-        runtime = efi_runtime_p;
-        fix_virt_function_pointer((void**)&runtime->get_time);
-        fix_virt_function_pointer((void**)&runtime->set_time);
-        fix_virt_function_pointer((void**)&runtime->get_wakeup_time);
-        fix_virt_function_pointer((void**)&runtime->set_wakeup_time);
-        fix_virt_function_pointer((void**)&runtime->set_virtual_address_map);
-        fix_virt_function_pointer((void**)&runtime->get_variable);
-        fix_virt_function_pointer((void**)&runtime->get_next_variable);
-        fix_virt_function_pointer((void**)&runtime->set_variable);
-        fix_virt_function_pointer((void**)&runtime->get_next_high_mono_count);
-        fix_virt_function_pointer((void**)&runtime->reset_system);
-        return EFI_SUCCESS;
-}
-
-void
-acpi_table_initx(struct acpi_table_header *p, char *sig, int siglen, int revision, int oem_revision)
-{
-	memcpy(p->signature, sig, siglen);
-	memcpy(p->oem_id, OEMID, 6);
-	memcpy(p->oem_table_id, sig, 4);
-	memcpy(p->oem_table_id+4, PRODUCT, 4);
-	p->revision = revision;
-	p->oem_revision = (revision<<16) + oem_revision;
-	memcpy(p->asl_compiler_id, "FPRM", 4);
-	p->asl_compiler_revision = 1;
-}
-
-void
-acpi_checksum(struct acpi_table_header *p, int length)
-{
-	u8	*cp, *cpe, checksum;
-
-	p->checksum = 0;
-	p->length = length;
-	checksum = 0;
-	for (cp=(u8*)p, cpe=cp+p->length; cp<cpe; cp++)
-		checksum += *cp;
-	p->checksum = -checksum;
-}
-
-void
-acpi_checksum_rsdp20(struct acpi20_table_rsdp *p, int length)
-{
-	u8	*cp, *cpe, checksum;
-
-	p->checksum = 0;
-	p->ext_checksum = 0;
-	p->length = length;
-	checksum = 0;
-	for (cp=(u8*)p, cpe=cp+20; cp<cpe; cp++)
-		checksum += *cp;
-	p->checksum = -checksum;
-
-	checksum = 0;
-	for (cp=(u8*)p, cpe=cp+length; cp<cpe; cp++)
-		checksum += *cp;
-	p->ext_checksum = -checksum;
-}
-
-int
-nasid_present(int nasid)
-{
-	int	cnode;
-	for (cnode=0; cnode<num_nodes; cnode++)
-		if (GetNasid(cnode) == nasid)
-			return 1;
-	return 0;
-}
-
-void
-sys_fw_init (const char *args, int arglen, int bsp)
-{
-	/*
-	 * Use static variables to keep from overflowing the RSE stack
-	 */
-	static efi_system_table_t *efi_systab;
-	static efi_runtime_services_t *efi_runtime;
-	static efi_config_table_t *efi_tables;
-	static ia64_sal_desc_ptc_t *sal_ptc;
-	static ia64_sal_ptc_domain_info_t *sal_ptcdi;
-	static ia64_sal_ptc_domain_proc_entry_t *sal_ptclid;
-	static struct acpi20_table_rsdp *acpi20_rsdp;
-	static struct acpi_table_xsdt *acpi_xsdt;
-	static struct acpi_table_slit *acpi_slit;
-	static struct acpi_table_madt *acpi_madt;
-	static struct acpi_table_lsapic *lsapic20;
-	static struct ia64_sal_systab *sal_systab;
-	static struct acpi_table_srat *acpi_srat;
-	static struct acpi_table_processor_affinity *srat_cpu_affinity;
-	static struct acpi_table_memory_affinity *srat_memory_affinity;
-	static efi_memory_desc_t *efi_memmap, *md;
-	static unsigned long *pal_desc, *sal_desc;
-	static struct ia64_sal_desc_entry_point *sal_ed;
-	static struct ia64_boot_param *bp;
-	static struct ia64_sal_desc_ap_wakeup *sal_apwake;
-	static unsigned char checksum;
-	static char *cp, *cmd_line, *vendor;
-	static void *ptr;
-	static int mdsize, domain, last_domain ;
-	static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found;
-
-	/*
-	 * Pass the parameter base address to the build_efi_xxx routines.
-	 */
-#if defined(SGI_SN2)
-	build_init(0x3000000000UL | ((long)base_nasid<<38));
-#endif
-
-	num_nodes = GetNumNodes();
-	num_cpus = GetNumCpus();
-	for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++)
-		max_nasid = MAX(max_nasid, GetNasid(cnode));
-
-
-	memset(fw_mem, 0, sizeof(fw_mem));
-
-	pal_desc = (unsigned long *) &pal_emulator;
-	sal_desc = (unsigned long *) &sal_emulator;
-	fix_function_pointer(&pal_emulator);
-	fix_function_pointer(&sal_emulator);
-
-	/* Align this to 16 bytes, probably EFI does this  */
-	mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ;
-
-	cp = fw_mem;
-	efi_systab  = (void *) cp; cp += ALIGN8(sizeof(*efi_systab));
-	efi_runtime_p = efi_runtime = (void *) cp; cp += ALIGN8(sizeof(*efi_runtime));
-	efi_tables  = (void *) cp; cp += ALIGN8(NUM_EFI_DESCS*sizeof(*efi_tables));
-	sal_systab  = (void *) cp; cp += ALIGN8(sizeof(*sal_systab));
-	sal_ed      = (void *) cp; cp += ALIGN8(sizeof(*sal_ed));
-	sal_ptc     = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc));
-	sal_apwake  = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake));
-	acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp));
-	acpi_xsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64); 
-			/* save space for more OS defined table pointers. */
-
-	acpi_slit   = (void *) cp; cp += ALIGN8(sizeof(*acpi_slit) + 8 + (max_nasid+1)*(max_nasid+1));
-	acpi_madt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_madt) + sizeof(struct acpi_table_lsapic) * (num_cpus+1));
-	acpi_srat   = (void *) cp; cp += ALIGN8(sizeof(struct acpi_table_srat));
-	cp         += sizeof(struct acpi_table_processor_affinity)*num_cpus + sizeof(struct acpi_table_memory_affinity)*num_nodes;
-	vendor 	    = (char *) cp; cp += ALIGN8(40);
-	efi_memmap  = (void *) cp; cp += ALIGN8(8*32*sizeof(*efi_memmap));
-	sal_ptcdi   = (void *) cp; cp += ALIGN8(CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi));
-	sal_ptclid  = (void *) cp; cp += ALIGN8(((3+num_cpus)*sizeof(*sal_ptclid)+7)/8*8);
-	cmd_line    = (void *) cp;
-
-	if (args) {
-		if (arglen >= 1024)
-			arglen = 1023;
-		memcpy(cmd_line, args, arglen);
-	} else {
-		arglen = 0;
-	}
-	cmd_line[arglen] = '\0';
-	/* 
-	 * For now, just bring up bash.
-	 * If you want to execute all the startup scripts, delete the "init=..".
-	 * You can also edit this line to pass other arguments to the kernel.
-	 *    Note: disable kernel text replication.
-	 */
-	strcpy(cmd_line, "init=/bin/bash console=ttyS0");
-
-	memset(efi_systab, 0, sizeof(efi_systab));
-	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
-	efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
-	efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
-	efi_systab->fw_vendor = __fwtab_pa(base_nasid, vendor);
-	efi_systab->fw_revision = 1;
-	efi_systab->runtime = __fwtab_pa(base_nasid, efi_runtime);
-	efi_systab->nr_tables = 2;
-	efi_systab->tables = __fwtab_pa(base_nasid, efi_tables);
-	memcpy(vendor, "S\0i\0l\0i\0c\0o\0n\0-\0G\0r\0a\0p\0h\0i\0c\0s\0\0", 40);
-
-	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
-	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
-	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-	efi_runtime->get_time = __fwtab_pa(base_nasid, &efi_get_time);
-	efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map);
-	efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->get_next_high_mono_count = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->reset_system = __fwtab_pa(base_nasid, &efi_reset_system);
-
-	efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
-	efi_tables->table = __fwtab_pa(base_nasid, sal_systab);
-	efi_tables++;
-	efi_tables->guid = ACPI_20_TABLE_GUID;
-	efi_tables->table = __fwtab_pa(base_nasid, acpi20_rsdp);
-	efi_tables++;
-
-	fix_function_pointer(&efi_unimplemented);
-	fix_function_pointer(&efi_get_time);
-	fix_function_pointer(&efi_success);
-	fix_function_pointer(&efi_reset_system);
-	fix_function_pointer(&efi_set_virtual_address_map);
-
-
-	/* fill in the ACPI20 system table - has a pointer to the ACPI table header */
-	memcpy(acpi20_rsdp->signature, "RSD PTR ", 8);
-	acpi20_rsdp->xsdt_address = (u64)__fwtab_pa(base_nasid, acpi_xsdt);
-	acpi20_rsdp->revision = 2;
-	acpi_checksum_rsdp20(acpi20_rsdp, sizeof(struct acpi20_table_rsdp));
-
-	/* Set up the XSDT table  - contains pointers to the other ACPI tables */
-	acpi_table_initx(&acpi_xsdt->header, XSDT_SIG, 4, 1, 1);
-	acpi_xsdt->entry[0] = __fwtab_pa(base_nasid, acpi_madt);
-	acpi_xsdt->entry[1] = __fwtab_pa(base_nasid, acpi_slit);
-	acpi_xsdt->entry[2] = __fwtab_pa(base_nasid, acpi_srat);
-	acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 16);
-
-	/* Set up the APIC table */
-	acpi_table_initx(&acpi_madt->header, APIC_SIG, 4, 1, 1);
-	lsapic20 = (struct acpi_table_lsapic*) (acpi_madt + 1);
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (!IsCpuPresent(cnode, cpu))
-				continue;
-			lsapic20->header.type = ACPI_MADT_LSAPIC;
-			lsapic20->header.length = sizeof(struct acpi_table_lsapic);
-			lsapic20->acpi_id = cnode*4+cpu;
-			lsapic20->flags.enabled = 1;
-#if defined(SGI_SN2)
-			lsapic20->eid = nasid&0xffff;
-			lsapic20->id = (cpu<<4) | (nasid>>16);
-#endif
-			lsapic20 = (struct acpi_table_lsapic*) ((long)lsapic20+sizeof(struct acpi_table_lsapic));
-		}
-	}
-	acpi_checksum(&acpi_madt->header, (char*)lsapic20 - (char*)acpi_madt);
-
-	/* Set up the SRAT table */
-	acpi_table_initx(&acpi_srat->header, SRAT_SIG, 4, ACPI_SRAT_REVISION, 1);
-	ptr = acpi_srat+1;
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		srat_memory_affinity = ptr;
-		ptr = srat_memory_affinity+1;
-		srat_memory_affinity->header.type = ACPI_SRAT_MEMORY_AFFINITY;
-		srat_memory_affinity->header.length = sizeof(struct acpi_table_memory_affinity);
-		srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
-		srat_memory_affinity->base_addr_lo = 0;
-		srat_memory_affinity->length_lo = 0;
-#if defined(SGI_SN2)
-		srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
-		srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
-#endif
-		srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
-		srat_memory_affinity->flags.enabled = 1;
-	}
-
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (!IsCpuPresent(cnode, cpu))
-				continue;
-			srat_cpu_affinity = ptr;
-			ptr = srat_cpu_affinity + 1;
-			srat_cpu_affinity->header.type = ACPI_SRAT_PROCESSOR_AFFINITY;
-			srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity);
-			srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
-			srat_cpu_affinity->flags.enabled = 1;
-#if defined(SGI_SN2)
-			srat_cpu_affinity->lsapic_eid = nasid&0xffff;
-			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
-#endif
-		}
-	}
-	acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat);
-
-
-	/* Set up the SLIT table */
-	acpi_table_initx(&acpi_slit->header, SLIT_SIG, 4, ACPI_SLIT_REVISION, 1);
-	acpi_slit->localities = PROXIMITY_DOMAIN(max_nasid)+1;
-	cp=acpi_slit->entry;
-	memset(cp, 255, acpi_slit->localities*acpi_slit->localities);
-
-	for (i=0; i<=max_nasid; i++)
-		for (j=0; j<=max_nasid; j++)
-			if (nasid_present(i) && nasid_present(j))
-				*(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*abs(i-j));
-
-	cp = acpi_slit->entry + acpi_slit->localities*acpi_slit->localities;
-	acpi_checksum(&acpi_slit->header, cp - (char*)acpi_slit);
-
-
-	/* fill in the SAL system table: */
-	memcpy(sal_systab->signature, "SST_", 4);
-	sal_systab->size = sizeof(*sal_systab);
-	sal_systab->sal_rev_minor = 1;
-	sal_systab->sal_rev_major = 0;
-	sal_systab->entry_count = 3;
-	sal_systab->sal_b_rev_major = 0x1; /* set the SN SAL rev to */
-	sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
-
-	strcpy(sal_systab->oem_id, "SGI");
-	strcpy(sal_systab->product_id, "SN2");
-
-	/* fill in an entry point: */	
-	sal_ed->type = SAL_DESC_ENTRY_POINT;
-	sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]);
-	sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]);
-	sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]);
-
-	/* kludge the PTC domain info */
-	sal_ptc->type = SAL_DESC_PTC;
-	sal_ptc->num_domains = 0;
-	sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi);
-	cpus_found = 0;
-	last_domain = -1;
-	sal_ptcdi--;
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (IsCpuPresent(cnode, cpu)) {
-				domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB;
-				if (domain != last_domain) {
-					sal_ptc->num_domains++;
-					sal_ptcdi++;
-					sal_ptcdi->proc_count = 0;
-					sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid);
-					last_domain = domain;
-				}
-				sal_ptcdi->proc_count++;
-				sal_ptclid->id = nasid;
-				sal_ptclid->eid = cpu;
-				sal_ptclid++;
-				cpus_found++;
-			}
-		}
-	}
-
-	if (cpus_found != num_cpus)
-		FPROM_BUG();
-
-	/* Make the AP WAKEUP entry */
-	sal_apwake->type = SAL_DESC_AP_WAKEUP;
-	sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
-	sal_apwake->vector = 18;
-
-	for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp)
-		checksum += *cp;
-	sal_systab->checksum = -checksum;
-
-	/* If the checksum is correct, the kernel tries to use the
-	 * table. We dont build enough table & the kernel aborts.
-	 * Note that the PROM hasd thhhe same problem!!
-	 */
-
-	md = &efi_memmap[0];
-	num_memmd = build_efi_memmap((void *)md, mdsize) ;
-
-	bp = (struct ia64_boot_param*) __fwtab_pa(base_nasid, BOOT_PARAM_ADDR);
-	bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem);
-	bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap);
-	bp->efi_memmap_size = num_memmd*mdsize;
-	bp->efi_memdesc_size = mdsize;
-	bp->efi_memdesc_version = 0x101;
-	bp->command_line = __fwtab_pa(base_nasid, cmd_line);
-	bp->console_info.num_cols = 80;
-	bp->console_info.num_rows = 25;
-	bp->console_info.orig_x = 0;
-	bp->console_info.orig_y = 24;
-	bp->fpswa = 0;
-
-	/*
-	 * Now pick the BSP & store it LID value in
-	 * a global variable. Note if BSP is greater than last cpu,
-	 * pick the last cpu.
-	 */
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (!IsCpuPresent(cnode, cpu))
-				continue;
-#ifdef SGI_SN2
-			bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
-#endif
-			if (bsp-- > 0)
-				continue;
-			return;
-		}
-	}
-}
diff -Nru a/arch/ia64/sn/fakeprom/klgraph_init.c b/arch/ia64/sn/fakeprom/klgraph_init.c
--- a/arch/ia64/sn/fakeprom/klgraph_init.c	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,205 +0,0 @@
-/* $Id: klgraph_init.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-
-/*
- * This is a temporary file that statically initializes the expected 
- * initial klgraph information that is normally provided by prom.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-#define WIDGET4                 ((char *)0xc0000a0000000004)
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-
-#define convert(a,b,c) temp = (u64 *)a; *temp = b; temp++; *temp = c
-void
-klgraph_init(void)
-{
-
-	u64 *temp;
-	/*
-	 * Initialize some hub/xbow registers that allows access to 
-	 * Xbridge etc.  These are normally done in PROM.
-	 */
-
-        /* Write IOERR clear to clear the CRAZY bit in the status */
-        *(volatile uint64_t *)0xc000000801c001f8 = (uint64_t)0xffffffff;
-
-        /* set widget control register...setting bedrock widget id to a */
-        *(volatile uint64_t *)0xc000000801c00020 = (uint64_t)0x801a;
-
-        /* set io outbound widget access...allow all */
-        *(volatile uint64_t *)0xc000000801c00110 = (uint64_t)0xff01;
-
-        /* set io inbound widget access...allow all */
-        *(volatile uint64_t *)0xc000000801c00118 = (uint64_t)0xff01;
-
-        /* set io crb timeout to max */
-        *(volatile uint64_t *)0xc000000801c003c0 = (uint64_t)0xffffff;
-        *(volatile uint64_t *)0xc000000801c003c0 = (uint64_t)0xffffff;
-
-        /* set local block io permission...allow all */
-// [LB]        *(volatile uint64_t *)0xc000000801e04010 = (uint64_t)0xfffffffffffffff;
-
-        /* clear any errors */
-        /* clear_ii_error(); medusa should have cleared these */
-
-        /* set default read response buffers in bridge */
-// [PI]       *(volatile u32 *)0xc00000080f000280L = 0xba98;
-// [PI]       *(volatile u32 *)0xc00000080f000288L = 0xba98;
-
-        /*
-         * klconfig entries initialization - mankato
-         */
-        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
-        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
-        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
-        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
-        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
-        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
-        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
-        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
-        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
-        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
-        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
-        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
-        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
-        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
-        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
-        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
-        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
-        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
-        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
-        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
-        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
-        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
-        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
-        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
-        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
-        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
-        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
-        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
-        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
-        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
-        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
-        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
-        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
-        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
-        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
-        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
-        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
-        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
-        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
-        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
-        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
-        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
-        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
-        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
-        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
-        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
-        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
-        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
-        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
-        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
-        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
-        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
-        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
-        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
-        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
-        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
-        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
-        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
-        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
-        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
-        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
-        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
-        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
-        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
-}
diff -Nru a/arch/ia64/sn/fakeprom/main.c b/arch/ia64/sn/fakeprom/main.c
--- a/arch/ia64/sn/fakeprom/main.c	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,109 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
- */
-
-
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/bitops.h>
-
-extern void klgraph_init(void);
-void bedrock_init(int);
-void synergy_init(int, int);
-void sys_fw_init (const char *args, int arglen, int bsp);
-
-volatile int	bootmaster=0;		/* Used to pick bootmaster */
-volatile int	nasidmaster[128]={0};	/* Used to pick node/synergy masters */
-int		init_done=0;
-extern int	bsp_lid;
-
-#define get_bit(b,p)	(((*p)>>(b))&1)
-
-int
-fmain(int lid, int bsp) {
-	int	syn, nasid, cpu;
-
-	/*
-	 * First lets figure out who we are. This is done from the
-	 * LID passed to us.
-	 */
-	nasid = (lid>>16)&0xfff;
-	cpu = (lid>>28)&3;
-	syn = 0;
-	
-	/*
-	 * Now pick a nasid master to initialize Bedrock registers.
-	 */
-	if (test_and_set_bit(8, &nasidmaster[nasid]) == 0) {
-		bedrock_init(nasid);
-		test_and_set_bit(9, &nasidmaster[nasid]);
-	} else
-		while (get_bit(9, &nasidmaster[nasid]) == 0);
-	
-
-	/*
-	 * Now pick a BSP & finish init.
-	 */
-	if (test_and_set_bit(0, &bootmaster) == 0) {
-		sys_fw_init(0, 0, bsp);
-		test_and_set_bit(1, &bootmaster);
-	} else
-		while (get_bit(1, &bootmaster) == 0);
-
-	return (lid == bsp_lid);
-}
-
-
-void
-bedrock_init(int nasid)
-{
-	nasid = nasid;		/* to quiet gcc */
-#if 0
-	/*
-	 * Undef if you need fprom to generate a 1 node klgraph
-	 * information .. only works for 1 node for nasid 0.
-	 */
-	klgraph_init();
-#endif
-}
-
-
-void
-synergy_init(int nasid, int syn)
-{
-	long	*base;
-	long	off;
-
-	/*
-	 * Enable all FSB flashed interrupts.
-	 * I'd really like defines for this......
-	 */
-	base = (long*)0x80000e0000000000LL;		/* base of synergy regs */
-	for (off = 0x2a0; off < 0x2e0; off+=8)		/* offset for VEC_MASK_{0-3}_A/B */
-		*(base+off/8) = -1LL;
-
-	/*
-	 * Set the NASID in the FSB_CONFIG register.
-	 */
-	base = (long*)0x80000e0000000450LL;
-	*base = (long)((nasid<<16)|(syn<<9));
-}
-
-
-/* Why isnt there a bcopy/memcpy in lib64.a */
-
-void* 
-memcpy(void * dest, const void *src, size_t count)
-{
-	char *s, *se, *d;
-
-	for(d=dest, s=(char*)src, se=s+count; s<se; s++, d++)
-		*d = *s;
-	return dest;
-}
diff -Nru a/arch/ia64/sn/fakeprom/make_textsym b/arch/ia64/sn/fakeprom/make_textsym
--- a/arch/ia64/sn/fakeprom/make_textsym	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,174 +0,0 @@
-#!/bin/sh
-#
-# Build a textsym file for use in the Arium ITP probe.
-#
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
-#
-
-help() {
-cat <<END
-Build a WinDD "symtxt" file for use with the Arium ECM-30 probe.
-
-	Usage: $0 [<vmlinux file> [<output file>]]
-		If no input file is specified, it defaults to vmlinux.
-		If no output file name is specified, it defaults to "textsym".
-END
-exit 1
-}
-
-err () {
-	echo "ERROR - $*" >&2
-	exit 1
-}
-
-
-OPTS="H"
-while getopts "$OPTS" c ; do
-	case $c in
-		H)  help;;
-		\?) help;;
-	esac
-
-done
-shift `expr $OPTIND - 1`
-
-#OBJDUMP=/usr/bin/ia64-linux-objdump
-LINUX=${1:-vmlinux}
-TEXTSYM=${2:-${LINUX}.sym}
-TMPSYM=${2:-${LINUX}.sym.tmp}
-trap "/bin/rm -f $TMPSYM" 0
-
-[ -f $VMLINUX ] || help
-
-$OBJDUMP -t $LINUX | egrep -v '__ks' | sort > $TMPSYM
-SN1=`egrep "dig_setup|Synergy_da_indr" $TMPSYM|wc -l`
-
-# Dataprefix and textprefix correspond to the VGLOBAL_BASE and VPERNODE_BASE.
-# Eventually, these values should be:
-#	dataprefix	ffffffff
-#	textprefix	fffffffe
-# but right now they're still changing, so make them dynamic.
-dataprefix=`awk ' / \.data	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
-textprefix=`awk ' / \.text	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
-
-# pipe everything thru sort
-echo "TEXTSYM V1.0"
-(cat <<END 
-GLOBAL | ${textprefix}00000000 | CODE | VEC_VHPT_Translation_0000
-GLOBAL | ${textprefix}00000400 | CODE | VEC_ITLB_0400
-GLOBAL | ${textprefix}00000800 | CODE | VEC_DTLB_0800
-GLOBAL | ${textprefix}00000c00 | CODE | VEC_Alt_ITLB_0c00
-GLOBAL | ${textprefix}00001000 | CODE | VEC_Alt_DTLB_1000
-GLOBAL | ${textprefix}00001400 | CODE | VEC_Data_nested_TLB_1400
-GLOBAL | ${textprefix}00001800 | CODE | VEC_Instruction_Key_Miss_1800
-GLOBAL | ${textprefix}00001c00 | CODE | VEC_Data_Key_Miss_1c00
-GLOBAL | ${textprefix}00002000 | CODE | VEC_Dirty-bit_2000
-GLOBAL | ${textprefix}00002400 | CODE | VEC_Instruction_Access-bit_2400
-GLOBAL | ${textprefix}00002800 | CODE | VEC_Data_Access-bit_2800
-GLOBAL | ${textprefix}00002c00 | CODE | VEC_Break_instruction_2c00
-GLOBAL | ${textprefix}00003000 | CODE | VEC_External_Interrupt_3000
-GLOBAL | ${textprefix}00003400 | CODE | VEC_Reserved_3400
-GLOBAL | ${textprefix}00003800 | CODE | VEC_Reserved_3800
-GLOBAL | ${textprefix}00003c00 | CODE | VEC_Reserved_3c00
-GLOBAL | ${textprefix}00004000 | CODE | VEC_Reserved_4000
-GLOBAL | ${textprefix}00004400 | CODE | VEC_Reserved_4400
-GLOBAL | ${textprefix}00004800 | CODE | VEC_Reserved_4800
-GLOBAL | ${textprefix}00004c00 | CODE | VEC_Reserved_4c00
-GLOBAL | ${textprefix}00005000 | CODE | VEC_Page_Not_Present_5000
-GLOBAL | ${textprefix}00005100 | CODE | VEC_Key_Permission_5100
-GLOBAL | ${textprefix}00005200 | CODE | VEC_Instruction_Access_Rights_5200
-GLOBAL | ${textprefix}00005300 | CODE | VEC_Data_Access_Rights_5300
-GLOBAL | ${textprefix}00005400 | CODE | VEC_General_Exception_5400
-GLOBAL | ${textprefix}00005500 | CODE | VEC_Disabled_FP-Register_5500
-GLOBAL | ${textprefix}00005600 | CODE | VEC_Nat_Consumption_5600
-GLOBAL | ${textprefix}00005700 | CODE | VEC_Speculation_5700
-GLOBAL | ${textprefix}00005800 | CODE | VEC_Reserved_5800
-GLOBAL | ${textprefix}00005900 | CODE | VEC_Debug_5900
-GLOBAL | ${textprefix}00005a00 | CODE | VEC_Unaligned_Reference_5a00
-GLOBAL | ${textprefix}00005b00 | CODE | VEC_Unsupported_Data_Reference_5b00
-GLOBAL | ${textprefix}00005c00 | CODE | VEC_Floating-Point_Fault_5c00
-GLOBAL | ${textprefix}00005d00 | CODE | VEC_Floating_Point_Trap_5d00
-GLOBAL | ${textprefix}00005e00 | CODE | VEC_Lower_Privilege_Tranfer_Trap_5e00
-GLOBAL | ${textprefix}00005f00 | CODE | VEC_Taken_Branch_Trap_5f00
-GLOBAL | ${textprefix}00006000 | CODE | VEC_Single_Step_Trap_6000
-GLOBAL | ${textprefix}00006100 | CODE | VEC_Reserved_6100
-GLOBAL | ${textprefix}00006200 | CODE | VEC_Reserved_6200
-GLOBAL | ${textprefix}00006300 | CODE | VEC_Reserved_6300
-GLOBAL | ${textprefix}00006400 | CODE | VEC_Reserved_6400
-GLOBAL | ${textprefix}00006500 | CODE | VEC_Reserved_6500
-GLOBAL | ${textprefix}00006600 | CODE | VEC_Reserved_6600
-GLOBAL | ${textprefix}00006700 | CODE | VEC_Reserved_6700
-GLOBAL | ${textprefix}00006800 | CODE | VEC_Reserved_6800
-GLOBAL | ${textprefix}00006900 | CODE | VEC_IA-32_Exeception_6900
-GLOBAL | ${textprefix}00006a00 | CODE | VEC_IA-32_Intercept_6a00
-GLOBAL | ${textprefix}00006b00 | CODE | VEC_IA-32_Interrupt_6b00
-GLOBAL | ${textprefix}00006c00 | CODE | VEC_Reserved_6c00
-GLOBAL | ${textprefix}00006d00 | CODE | VEC_Reserved_6d00
-GLOBAL | ${textprefix}00006e00 | CODE | VEC_Reserved_6e00
-GLOBAL | ${textprefix}00006f00 | CODE | VEC_Reserved_6f00
-GLOBAL | ${textprefix}00007000 | CODE | VEC_Reserved_7000
-GLOBAL | ${textprefix}00007100 | CODE | VEC_Reserved_7100
-GLOBAL | ${textprefix}00007200 | CODE | VEC_Reserved_7200
-GLOBAL | ${textprefix}00007300 | CODE | VEC_Reserved_7300
-GLOBAL | ${textprefix}00007400 | CODE | VEC_Reserved_7400
-GLOBAL | ${textprefix}00007500 | CODE | VEC_Reserved_7500
-GLOBAL | ${textprefix}00007600 | CODE | VEC_Reserved_7600
-GLOBAL | ${textprefix}00007700 | CODE | VEC_Reserved_7700
-GLOBAL | ${textprefix}00007800 | CODE | VEC_Reserved_7800
-GLOBAL | ${textprefix}00007900 | CODE | VEC_Reserved_7900
-GLOBAL | ${textprefix}00007a00 | CODE | VEC_Reserved_7a00
-GLOBAL | ${textprefix}00007b00 | CODE | VEC_Reserved_7b00
-GLOBAL | ${textprefix}00007c00 | CODE | VEC_Reserved_7c00
-GLOBAL | ${textprefix}00007d00 | CODE | VEC_Reserved_7d00
-GLOBAL | ${textprefix}00007e00 | CODE | VEC_Reserved_7e00
-GLOBAL | ${textprefix}00007f00 | CODE | VEC_Reserved_7f00
-END
-
-
-awk '
-/ _start$/ {start=1}
-/ start_ap$/ {start=1}
-/__start_gate_section/ {start=1}
-/^'${dataprefix}\|${textprefix}'/ {
-	if ($4 == ".kdb")
-		next
-	if (start && substr($NF,1,1) != "0") {
-		type = substr($0,26,5)
-		if (type == ".text")
-			printf "GLOBAL | %s | CODE | %s\n", $1, $NF
-		else {
-			n = 0
-			s = $(NF-1)
-			while (length(s) > 0) {
-				n = n*16 + (index("0123456789abcdef", substr(s,1,1)) - 1)
-				s = substr(s,2)
-			}
-			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n
-		}
-	}
-	if($NF == "_end") 
-		exit
-
-}
-' $TMPSYM ) | egrep -v " __device| __vendor" | awk -v sn1="$SN1" '
-/GLOBAL/ {
-	print $0
-	if (sn1 != 0) {
-		/* 32 bits of sn1 physical addrs, */
-		print substr($0,1,9) "04" substr($0,20,16) "Phy_" substr($0,36)
-	} else {
-		/* 38 bits of sn2 physical addrs, need addr space bits */
-		print substr($0,1,9) "3004" substr($0,20,16) "Phy_" substr($0,36)
-	}
-
-} ' | sort -k3
-
-N=`wc -l $TEXTSYM|awk '{print $1}'`
-echo "Generated TEXTSYM file" >&2
-echo "  $LINUX --> $TEXTSYM" >&2
-echo "  Found $N symbols" >&2
diff -Nru a/arch/ia64/sn/fakeprom/runsim b/arch/ia64/sn/fakeprom/runsim
--- a/arch/ia64/sn/fakeprom/runsim	2004-08-25 19:44:40 -07:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,387 +0,0 @@
-#!/bin/sh
-
-# Script for running PROMs and LINUX kernwls on medusa. 
-# Type "sim -H" for instructions.
-
-MEDUSA=${MEDUSA:-/home/rickc/official_medusa/medusa}
-
-# ------------------ err -----------------------
-err() {
-	echo "ERROR - $1"
-	exit 1
-}
-
-# ----------------  help ----------------------
-help() {
-cat <<END
-Script for running a PROM or LINUX kernel under medusa.
-This script creates a control file, creates links to the appropriate
-linux/prom files, and/or calls medusa to make simulation runs.
-
-Usage:  
-   Initial setup:
-   	sim [-c <config_file>] <-p> | <-k>  [<work_dir>]
-		-p	Create PROM control file & links
-		-k	Create LINUX control file & links
-		-c<cf>	Control file name				[Default: cf]
-		<work_dir> Path to directory that contains the linux or PROM files.
-		    The directory can be any of the following:
-		       (linux simulations)
-		       		worktree
-				worktree/linux
-				any directory with vmlinux, vmlinux.sym & fprom files
-			(prom simulations)
-				worktree
-				worktree/stand/arcs/IP37prom/dev
-				any directory with fw.bin & fw.sim files
-
-    Simulations:
-	sim  [-X <n>] [-o <output>] [-M] [<config_file>]
-		-c<cf>	Control file name				[Default: cf]
-		-M	Pipe output thru fmtmedusa
-		-o	Output filename (copy of all commands/output)	[Default: simout]
-		-X	Specifies number of instructions to execute	[Default: 0]
-			(Used only in auto test mode - not described here)
-
-Examples:
-	sim -p <promtree>	# create control file (cf) & links for prom simulations
-	sim -k <linuxtree>	# create control file (cf) & links for linux simulations
-	sim -p -c cfprom	# create a prom control file (cfprom) only. No links are made.
-
-	sim			# run medusa using previously created links &
-				#   control file (cf).
-END
-exit 1
-}
-
-# ----------------------- create control file header --------------------
-create_cf_header() {
-cat <<END >>$CF
-#
-# Template for a control file for running linux kernels under medusa. 
-# You probably want to make mods here but this is a good starting point.
-#
-
-# Preferences
-setenv cpu_stepping A
-setenv exceptionPrint off
-setenv interrupt_messages off
-setenv lastPCsize 100000
-setenv low_power_mode on
-setenv partialIntelChipSet on
-setenv printIntelMessages off
-setenv prom_write_action halt
-setenv prom_write_messages on
-setenv step_quantum 100
-setenv swizzling on
-setenv tsconsole on
-setenv uart_echo on
-symbols on
-
-# IDE disk params
-setenv diskCylinders 611
-setenv bootDrive C
-setenv diskHeads 16
-setenv diskPath idedisk
-setenv diskPresent 1
-setenv diskSpt 63
-
-# Hardware config
-setenv coherency_type nasid
-setenv cpu_cache_type default
-setenv synergy_cache_type syn_cac_64m_8w
-setenv l4_uc_snoop off
-
-# Numalink config
-setenv route_enable on
-setenv network_type router		# Select [xbar|router]
-setenv network_warning 0xff
-
-END
-}
-
-
-# ------------------ create control file entries for linux simulations -------------
-create_cf_linux() {
-cat <<END >>$CF
-# Kernel specific options
-setenv calias_size 0
-setenv mca_on_memory_failure off
-setenv LOADPC 0x00100000		# FPROM load address/entry point (8 digits!)
-setenv symbol_table vmlinux.sym
-load fprom
-load vmlinux
-
-# Useful breakpoints to always have set. Add more if desired.
-break 0xe000000000505e00	all	# dispatch_to_fault_handler
-break panic			all	# stop on panic
-break die_if_kernel		all	# may as well stop
-
-END
-}
-
-# ------------------ create control file entries for prom simulations ---------------
-create_cf_prom() {
-	SYM2=""
-	ADDR="0x80000000ff800000"
-	[ "$EMBEDDED_LINUX" != "0" ] || SYM2="setenv symbol_table2 vmlinux.sym"
-	[ "$SIZE" = "8MB" ] || ADDR="0x80000000ffc00000"
-	cat <<END >>$CF
-# PROM specific options
-setenv mca_on_memory_failure on
-setenv LOADPC 0x80000000ffffffb0
-setenv promFile fw.bin
-setenv promAddr $ADDR
-setenv symbol_table fw.sym
-$SYM2
-
-# Useful breakpoints to always have set. Add more if desired.
-break ivt_gexx 		all
-break ivt_brk		all
-break PROM_Panic_Spin	all
-break PROM_Panic	all
-break PROM_C_Panic	all
-break fled_die		all
-break ResetNow		all
-break zzzbkpt		all
-
-END
-}
-
-
-# ------------------ create control file entries for memory configuration -------------
-create_cf_memory() {
-cat <<END >>$CF
-# CPU/Memory map format:
-#	setenv nodeN_memory_config 0xBSBSBSBS
-#		B=banksize (0=unused, 1=64M, 2=128M, .., 5-1G, c=8M, d=16M, e=32M)
-#		S=bank enable (0=both disable, 3=both enable, 2=bank1 enable, 1=bank0 enable)
-#		  rightmost digits are for bank 0, the lowest address.
-#	setenv nodeN_nasid <nasid>
-#		specifies the NASID for the node. This is used ONLY if booting the kernel.
-#		On PROM configurations, set to 0 - PROM will change it later.
-#	setenv nodeN_cpu_config <cpu_mask>
-#		Set bit number N to 1 to enable cpu N. Ex., a value of 5 enables cpu 0 & 2.
-#
-# Repeat the above 3 commands for each node.
-#
-# For kernel, default to 32MB. Although this is not a valid hardware configuration,
-# it runs faster on medusa. For PROM, 64MB is smallest allowed value.
-
-setenv node0_cpu_config		0x1	# Enable only cpu 0 on the node
-END
-
-if [ $LINUX -eq 1 ] ; then
-cat <<END >>$CF
-setenv node0_nasid		0	# cnode 0 has NASID 0
-setenv node0_memory_config 	0xe1	# 32MB
-END
-else
-cat <<END >>$CF
-setenv node0_memory_config 	0x31	# 256MB
-END
-fi
-}
-
-# -------------------- set links to linux files -------------------------
-set_linux_links() {
-	if [ -d $D/linux/arch ] ; then
-		D=$D/linux
-	elif [ -d $D/arch -o -e vmlinux.sym -o -e $D/vmlinux ] ; then
-		D=$D
-	else
-		err "cant determine directory for linux binaries"
-	fi
-	rm -rf vmlinux vmlinux.sym fprom
-	ln -s $D/vmlinux vmlinux
-	if [ -f $D/vmlinux.sym ] ; then
-		ln -s $D/vmlinux.sym vmlinux.sym
-	elif  [ -f $D/System.map ] ; then
-		ln -s $D/System.map vmlinux.sym
-	fi
-	if [ -d $D/arch ] ; then
-		ln -s $D/arch/ia64/sn/fprom/fprom fprom
-	else
-		ln -s $D/fprom fprom
-	fi
-	echo "  .. Created links to linux files"	
-}
-
-# -------------------- set links to prom files -------------------------
-set_prom_links() {
-	if [ -d $D/stand ] ; then
-		D=$D/stand/arcs/IP37prom/dev
-	elif [ -d $D/sal ] ; then
-		D=$D
-	else
-		err "cant determine directory for PROM binaries"
-	fi
-	SETUP="/tmp/tmp.$$"
-	rm -r -f $SETUP
-	sed 's/export/setenv/' < $D/../../../../.setup | sed 's/=/ /' >$SETUP
-	egrep -q '^ *setenv *PROMSIZE *8MB|^ *export' $SETUP
-	if [ $? -eq 0 ] ; then
-		SIZE="8MB"
-	else
-		SIZE="4MB"
-	fi
-	grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP
-	EMBEDDED_LINUX=$?
-	PRODUCT=`grep '^ *setenv *PRODUCT' $SETUP | cut -d" " -f3`
-	rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom $SETUP
-	SDIR="${PRODUCT}${SIZE}.O"
-	BIN="${PRODUCT}ip37prom${SIZE}"
-	ln -s $D/$SDIR/$BIN.bin fw.bin
-	ln -s $D/$SDIR/$BIN.map fw.map
-	ln -s $D/$SDIR/$BIN.sym fw.sym
-	echo "  .. Created links to $SIZE prom files"
-	if [ $EMBEDDED_LINUX -eq 0 ] ; then
-		ln -s $D/linux/vmlinux vmlinux
-		ln -s $D/linux/vmlinux.sym vmlinux.sym
-		if [ -d linux/arch ] ; then
-			ln -s $D/linux/arch/ia64/sn/fprom/fprom fprom
-		else
-			ln -s $D/linux/fprom fprom
-		fi
-		echo "  .. Created links to embedded linux files in prom tree"
-	fi
-}
-
-# --------------- start of shell script --------------------------------
-OUT="simout"
-FMTMED=0
-STEPCNT=0
-PROM=0
-LINUX=0
-NCF="cf"
-while getopts "HMX:c:o:pk" c ; do
-        case ${c} in
-                H) help;;
-		M) FMTMED=1;;
-		X) STEPCNT=${OPTARG};;
-		c) NCF=${OPTARG};;
-		k) PROM=0;LINUX=1;;
-		p) PROM=1;LINUX=0;;
-		o) OUT=${OPTARG};;
-                \?) exit 1;;
-        esac
-done
-shift `expr ${OPTIND} - 1`
-
-# Check if command is for creating control file and/or links to images.
-if [ $PROM -eq 1 -o $LINUX -eq 1 ] ; then
-	CF=$NCF
-	[ ! -f $CF ] || err "wont overwrite an existing control file ($CF)"
-	if [ $# -gt 0 ] ; then
-		D=$1
-		[ -d $D ] || err "cannot find directory $D"
-		[ $PROM -eq 0 ]  || set_prom_links
-		[ $LINUX -eq 0 ] || set_linux_links
-	fi
-	create_cf_header
-	[ $PROM -eq 0 ]  || create_cf_prom
-	[ $LINUX -eq 0 ] || create_cf_linux
-	[ ! -f ../idedisk ] || ln -s ../idedisk .
-	create_cf_memory
-	echo "  .. Basic control file created (in $CF). You might want to edit"
-	echo "     this file (at least, look at it)."
-	exit 0
-fi
-
-# Verify that the control file exists
-CF=${1:-$NCF}
-[ -f $CF ] || err "No control file exists. For help, type: $0 -H"
-
-# Build the .cf files from the user control file. The .cf file is
-# identical except that the actual start & load addresses are inserted
-# into the file. In addition, the FPROM commands for configuring memory
-# and LIDs are generated. 
-
-rm -f .cf .cf1 .cf2
-awk '
-function strtonum(n) {
-	 if (substr(n,1,2) != "0x")
-	 	return int(n)
-	 n = substr(n,3)
-	 r=0
-	 while (length(n) > 0) {
-	 	r = r*16+(index("0123456789abcdef", substr(n,1,1))-1)
-		n = substr(n,2)
-	 }
-	 return r
-	}
-/^#/   	{next}
-/^$/	{next}
-/^setenv *LOADPC/               {loadpc = $3; next}
-/^setenv *node.._cpu_config/	{n=int(substr($2,5,2)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node.._memory_config/	{n=int(substr($2,5,2)); memconf[n] = strtonum($3); print; next}
-/^setenv *node.._nasid/		{n=int(substr($2,5,2)); nasid[n] = strtonum($3); print; next}
-/^setenv *node._cpu_config/	{n=int(substr($2,5,1)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node._memory_config/	{n=int(substr($2,5,1)); memconf[n] = strtonum($3); print; next}
-/^setenv *node._nasid/		{n=int(substr($2,5,1)); nasid[n] = strtonum($3); print; next}
-		{print}
-END	{
-	 # Generate the memmap info that starts at the beginning of
-	 # the node the kernel was loaded on.
-	 loadnasid = nasid[0]
-	 cnode = 0
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "sm 0x%x%08x 0x%x%04x%04x\n", 
-				2*loadnasid, 8*cnodes+8, memconf[i], cpuconf[i], nasid[i]
-			cnodes++
-			cpus += substr("0112122312232334", cpuconf[i]+1,1)
-		}
-	 }
-	 printf "sm 0x%x00000000 0x%x%08x\n", 2*loadnasid, cnodes, cpus
-	 printf "setenv number_of_nodes %d\n", cnodes
-
-	 # Now set the starting PC for each cpu.
-	 cnode = 0
-	 lowcpu=-1
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "setnode %d\n", cnode
-			conf = cpuconf[i]
-			for (j=0; j<4; j++) {
-				if (conf != int(conf/2)*2) {
-	 				printf "setcpu %d\n", j
-					if (length(loadpc) == 18)
-						printf "sr pc %s\n", loadpc
-					else
-						printf "sr pc 0x%x%s\n", 2*loadnasid, substr(loadpc,3)
-					if (lowcpu == -1)
-						lowcpu = j
-				}
-				conf = int(conf/2)
-			}
-			cnode++
-		}
-	 }
-	 printf "setnode 0\n"
-	 printf "setcpu %d\n", lowcpu
-	}
-' <$CF >.cf
-
-# Now build the .cf1 & .cf2 control files.
-CF2_LINES="^sm |^break |^run |^si |^quit |^symbols "
-egrep  "$CF2_LINES" .cf >.cf2
-egrep -v "$CF2_LINES" .cf >.cf1
-if [ $STEPCNT -ne 0 ] ; then
-	echo "s $STEPCNT" >>.cf2
-	echo "lastpc 1000" >>.cf2
-	echo "q" >>.cf2
-fi
-if [ -f vmlinux.sym ] ; then
-	awk '/ _start$/ {print "sr g 9 0x" $3}' < vmlinux.sym >> .cf2
-fi
-echo "script-on $OUT" >>.cf2
-
-# Now start medusa....
-if [ $FMTMED -ne 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 |  fmtmedusa
-elif [ $STEPCNT -eq 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 
-else
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 2>&1 
-fi
diff -Nru a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2004-08-25 19:44:40 -07:00
@@ -290,6 +290,7 @@
 			addr |= __IA64_UNCACHED_OFFSET;
 			dev->resource[idx].start = addr;
 			dev->resource[idx].end = addr + size;
+			dev->resource[idx].parent = &ioport_resource;
 		}
 
 		if (dev->resource[idx].flags & IORESOURCE_IO)
@@ -322,6 +323,7 @@
 			addr |= __IA64_UNCACHED_OFFSET;
 			dev->resource[idx].start = addr;
 			dev->resource[idx].end = addr + size;
+			dev->resource[idx].parent = &iomem_resource;
 		}
 
 		if (dev->resource[idx].flags & IORESOURCE_MEM)
@@ -351,6 +353,7 @@
                         addr |= __IA64_UNCACHED_OFFSET;
                         dev->resource[PCI_ROM_RESOURCE].start = addr;
                         dev->resource[PCI_ROM_RESOURCE].end = addr + size;
+			dev->resource[idx].parent = &iomem_resource;
                         if (dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_MEM)
                                 cmd |= PCI_COMMAND_MEMORY;
                 }
diff -Nru a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
--- a/arch/ia64/sn/kernel/bte.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/sn/kernel/bte.c	2004-08-25 19:44:40 -07:00
@@ -421,9 +421,10 @@
 	mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda;
 
 	for (i = 0; i < BTES_PER_NODE; i++) {
-		(u64) mynodepda->bte_if[i].bte_base_addr =
-		    REMOTE_HUB_ADDR(cnodeid_to_nasid(cnode),
-			(i == 0 ? IIO_IBLS0 : IIO_IBLS1));
+		/* Which link status register should we use? */
+		unsigned long link_status = (i == 0 ? IIO_IBLS0 : IIO_IBLS1);
+		mynodepda->bte_if[i].bte_base_addr = (u64 *)
+			REMOTE_HUB_ADDR(cnodeid_to_nasid(cnode), link_status);
 
 		/*
 		 * Initialize the notification and spinlock
diff -Nru a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
--- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2004-08-25 19:44:40 -07:00
@@ -3,10 +3,10 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * Module to export the system's Firmware Interface Tables, including
- * PROM revision numbers, in /proc
+ * PROM revision numbers and banners, in /proc
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -45,9 +45,18 @@
 #  define TRACE()
 #endif
 
+/* Architected IA64 firmware space */
+#define FW_BASE			0x00000000FF000000
+#define FW_TOP			0x0000000100000000
+
 /* Sub-regions determined by bits in Node Offset */
 #define	LB_PROM_SPACE		0x0000000700000000ul /* Local LB PROM */
 
+/* Offset of PROM banner pointers in SAL A and SAL B */
+#define SAL_A_BANNER_OFFSET	(1 * 16)
+#define SAL_B_BANNER_OFFSET	(3 * 16)
+
+
 #define FIT_SIGNATURE		0x2020205f5449465ful
 /* Standard Intel FIT entry types */
 #define FIT_ENTRY_FIT_HEADER	0x00	/* FIT header entry */
@@ -125,6 +134,26 @@
 	return "Unknown type";
 }
 
+static unsigned long
+convert_fw_addr(nasid_t nasid, unsigned long addr)
+{
+	/* snag just the node-relative offset */
+	addr &= ~0ul >> (63-35);
+	/* the pointer to SAL A is relative to IA-64 compatibility
+	 * space.  However, the PROM is mapped at a different offset
+	 * in MMR space (both local and global)
+	 */
+	addr += 0x700000000;
+	return GLOBAL_MMR_ADDR(nasid, addr);
+}
+
+static int
+valid_fw_addr(unsigned long addr)
+{
+	addr &= ~(1ul << 63); /* Clear cached/uncached bit */
+	return (addr >= FW_BASE && addr < FW_TOP);
+}
+
 /* These two routines read the FIT table directly from the FLASH PROM
  * on a specific node.  The PROM can only be accessed using aligned 64
  * bit reads, so we do that and then shift and mask the result to get
@@ -194,6 +223,8 @@
 	int nentries;
 	int fentry;
 	unsigned long qw;
+	int len;
+	nasid_t nasid = NASID_GET(fit);
 
 	TRACE();
 
@@ -203,10 +234,31 @@
 	for (fentry = 0; fentry < nentries; fentry++) {
 		qw = readq(fit + 2 * fentry + 1);
 		if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A)
-			return sprintf(page, "%x.%02x\n",
-				       FIT_MAJOR(qw), FIT_MINOR(qw));
+			break;
 	}
-	return 0;
+	if (fentry >= nentries)
+		return 0;
+
+	len = sprintf(page, "%x.%02x\n", FIT_MAJOR(qw), FIT_MINOR(qw));
+	page += len;
+
+	qw = readq(fit + 2 * fentry);	/* Address of SAL A */
+	DPRINTK("SAL A at %p\n", (void *)qw);
+	if (!valid_fw_addr(qw))
+		return len;
+
+	qw += SAL_A_BANNER_OFFSET;
+	qw = convert_fw_addr(nasid, qw);
+	DPRINTK("Banner ptr at %p\n", (void *)qw);
+
+	qw = readq(qw);			/* Address of banner */
+	if (!valid_fw_addr(qw))
+		return len;
+	qw = convert_fw_addr(nasid, qw);
+	DPRINTK("Banner at %p\n", (void *)qw);
+
+	len += snprintf(page, PAGE_SIZE-len, "%s\n", (char *)qw);
+	return len;
 }
 
 /* same as in proc_misc.c */
@@ -278,14 +330,10 @@
 	DPRINTK("pointer to fit at %p\n", (void *)fitp);
 	fit_paddr = readq(fitp);
 	DPRINTK("fit pointer contains %lx\n", fit_paddr);
-	/* snag just the node-relative offset */
-	fit_paddr &= ~0ul >> (63-35);
-	/* the pointer to the FIT is relative to IA-64 compatibility
-	 * space.  However, the PROM is mapped at a different offset
-	 * in MMR space (both local and global)
-	 */
-	fit_paddr += 0x700000000;
-	fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr);
+
+	BUG_ON(!valid_fw_addr(fit_paddr));
+	fit_vaddr = (void *)convert_fw_addr(nasid, fit_paddr);
+
 	DPRINTK("fit at %p\n", (void *)fit_vaddr);
 	return fit_vaddr;
 }
diff -Nru a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	2004-08-25 19:44:40 -07:00
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
  */
 #include <linux/config.h>
 #include <asm/uaccess.h>
@@ -118,11 +118,33 @@
 	}
 }
 
+static int coherence_id_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data) {
+	return sprintf(page, "%d\n", cpuid_to_coherence_id(smp_processor_id()));
+}
+
+void
+register_sn_coherence_id(void) {
+	struct proc_dir_entry *entry;
+
+	if (!sgi_proc_dir) {
+		sgi_proc_dir = proc_mkdir("sgi_sn", 0);
+	}
+	entry = create_proc_entry("coherence_id", 0444, sgi_proc_dir);
+	if (entry) {
+		entry->nlink = 1;
+		entry->data = 0;
+		entry->read_proc = coherence_id_read_proc;
+		entry->write_proc = NULL;
+	}
+}
+
 void
 register_sn_procfs(void) {
 	register_sn_partition_id();
 	register_sn_serial_numbers();
 	register_sn_force_interrupt();
+	register_sn_coherence_id();
 }
 
 #endif /* CONFIG_PROC_FS */
diff -Nru a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c
--- a/arch/ia64/sn/kernel/sn2/timer.c	2004-08-25 19:44:40 -07:00
+++ b/arch/ia64/sn/kernel/sn2/timer.c	2004-08-25 19:44:40 -07:00
@@ -20,57 +20,16 @@
 
 
 extern unsigned long sn_rtc_cycles_per_second;
-static volatile unsigned long last_wall_rtc;
 
-static unsigned long rtc_offset;	/* updated only when xtime write-lock is held! */
-static long rtc_nsecs_per_cycle;
-static long rtc_per_timer_tick;
-
-static unsigned long
-getoffset(void)
-{
-	return rtc_offset + (GET_RTC_COUNTER() - last_wall_rtc)*rtc_nsecs_per_cycle;
-}
-
-
-static void
-update(long delta_nsec)
-{
-	unsigned long rtc_counter = GET_RTC_COUNTER();
-	unsigned long offset = rtc_offset + (rtc_counter - last_wall_rtc)*rtc_nsecs_per_cycle;
-
-	/* Be careful about signed/unsigned comparisons here: */
-	if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
-		rtc_offset = offset - delta_nsec;
-	else
-		rtc_offset = 0;
-	last_wall_rtc = rtc_counter;
-}
-
-
-static void
-reset(void)
-{
-	rtc_offset = 0;
-	last_wall_rtc = GET_RTC_COUNTER();
-}
-
-
-static struct time_interpolator sn2_interpolator = {
-	.get_offset =	getoffset,
-	.update =	update,
-	.reset =	reset
-};
+static struct time_interpolator sn2_interpolator;
 
 void __init
 sn_timer_init(void)
 {
 	sn2_interpolator.frequency = sn_rtc_cycles_per_second;
 	sn2_interpolator.drift = -1;	/* unknown */
+	sn2_interpolator.shift = 10;	/* RTC is 54 bits maximum shift is 10 */
+	sn2_interpolator.addr = RTC_COUNTER_ADDR;
+	sn2_interpolator.source = TIME_SOURCE_MMIO64;
 	register_time_interpolator(&sn2_interpolator);
-
-	rtc_per_timer_tick = sn_rtc_cycles_per_second / HZ;
-	rtc_nsecs_per_cycle = 1000000000 / sn_rtc_cycles_per_second;
-
-	last_wall_rtc = GET_RTC_COUNTER();
 }
diff -Nru a/drivers/char/hpet.c b/drivers/char/hpet.c
--- a/drivers/char/hpet.c	2004-08-25 19:44:40 -07:00
+++ b/drivers/char/hpet.c	2004-08-25 19:44:40 -07:00
@@ -662,40 +662,10 @@
 
 #ifdef	CONFIG_TIME_INTERPOLATION
 
-static unsigned long hpet_offset, last_wall_hpet;
-static long hpet_nsecs_per_cycle, hpet_cycles_per_sec;
-
-static unsigned long hpet_getoffset(void)
-{
-	return hpet_offset + (read_counter(&hpets->hp_hpet->hpet_mc) -
-			      last_wall_hpet) * hpet_nsecs_per_cycle;
-}
-
-static void hpet_update(long delta)
-{
-	unsigned long mc;
-	unsigned long offset;
-
-	mc = read_counter(&hpets->hp_hpet->hpet_mc);
-	offset = hpet_offset + (mc - last_wall_hpet) * hpet_nsecs_per_cycle;
-
-	if (delta < 0 || (unsigned long)delta < offset)
-		hpet_offset = offset - delta;
-	else
-		hpet_offset = 0;
-	last_wall_hpet = mc;
-}
-
-static void hpet_reset(void)
-{
-	hpet_offset = 0;
-	last_wall_hpet = read_counter(&hpets->hp_hpet->hpet_mc);
-}
-
 static struct time_interpolator hpet_interpolator = {
-	.get_offset = hpet_getoffset,
-	.update = hpet_update,
-	.reset = hpet_reset
+	.source = TIME_SOURCE_MMIO64,
+	.shift = 10,
+	.addr = MC
 };
 
 #endif
diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
--- a/include/asm-ia64/acpi.h	2004-08-25 19:44:40 -07:00
+++ b/include/asm-ia64/acpi.h	2004-08-25 19:44:40 -07:00
@@ -96,7 +96,6 @@
 
 const char *acpi_get_sysname (void);
 int acpi_request_vector (u32 int_type);
-int acpi_register_irq (u32 gsi, u32 polarity, u32 trigger);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
 #ifdef CONFIG_ACPI_NUMA
diff -Nru a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
--- a/include/asm-ia64/mmu_context.h	2004-08-25 19:44:40 -07:00
+++ b/include/asm-ia64/mmu_context.h	2004-08-25 19:44:40 -07:00
@@ -28,36 +28,6 @@
 
 #include <asm/processor.h>
 
-#define MMU_CONTEXT_DEBUG	0
-
-#if MMU_CONTEXT_DEBUG
-
-#include <ia64intrin.h>
-
-extern struct mmu_trace_entry {
-	char op;
-	u8 cpu;
-	u32 context;
-	void *mm;
-} mmu_tbuf[1024];
-
-extern volatile int mmu_tbuf_index;
-
-# define MMU_TRACE(_op,_cpu,_mm,_ctx)							\
-do {											\
-	int i = __sync_fetch_and_add(&mmu_tbuf_index, 1) % ARRAY_SIZE(mmu_tbuf);	\
-	struct mmu_trace_entry e;							\
-	e.op = (_op);									\
-	e.cpu = (_cpu);									\
-	e.mm = (_mm);									\
-	e.context = (_ctx);								\
-	mmu_tbuf[i] = e;								\
-} while (0)
-
-#else
-# define MMU_TRACE(op,cpu,mm,ctx)	do { ; } while (0)
-#endif
-
 struct ia64_ctx {
 	spinlock_t lock;
 	unsigned int next;	/* next context number to use */
@@ -123,7 +93,6 @@
 static inline int
 init_new_context (struct task_struct *p, struct mm_struct *mm)
 {
-	MMU_TRACE('N', smp_processor_id(), mm, 0);
 	mm->context = 0;
 	return 0;
 }
@@ -132,7 +101,6 @@
 destroy_context (struct mm_struct *mm)
 {
 	/* Nothing to do.  */
-	MMU_TRACE('D', smp_processor_id(), mm, mm->context);
 }
 
 static inline void
@@ -171,19 +139,14 @@
 
 	do {
 		context = get_mmu_context(mm);
-		MMU_TRACE('A', smp_processor_id(), mm, context);
 		if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
 			cpu_set(smp_processor_id(), mm->cpu_vm_mask);
 		reload_context(context);
-		MMU_TRACE('a', smp_processor_id(), mm, context);
 		/* in the unlikely event of a TLB-flush by another thread, redo the load: */
 	} while (unlikely(context != mm->context));
 }
 
-#define deactivate_mm(tsk,mm)					\
-do {								\
-	MMU_TRACE('d', smp_processor_id(), mm, mm->context);	\
-} while (0)
+#define deactivate_mm(tsk,mm)	do { } while (0)
 
 /*
  * Switch from address space PREV to address space NEXT.
diff -Nru a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
--- a/include/asm-ia64/sal.h	2004-08-25 19:44:40 -07:00
+++ b/include/asm-ia64/sal.h	2004-08-25 19:44:40 -07:00
@@ -364,7 +364,7 @@
 	u64 cr[128];
 	u64 ar[128];
 	u64 rr[8];
-	struct ia64_fpreg fr[128];
+	struct ia64_fpreg __attribute__ ((packed)) fr[128];
 } sal_processor_static_info_t;
 
 struct sal_cpuid_info {
@@ -818,6 +818,16 @@
 struct sal_ret_values {
 	long r8; long r9; long r10; long r11;
 };
+
+#define IA64_SAL_OEMFUNC_MIN		0x02000000
+#define IA64_SAL_OEMFUNC_MAX		0x03ffffff
+
+extern int ia64_sal_oemcall(struct ia64_sal_retval *, u64, u64, u64, u64, u64,
+			    u64, u64, u64);
+extern int ia64_sal_oemcall_nolock(struct ia64_sal_retval *, u64, u64, u64,
+				   u64, u64, u64, u64, u64);
+extern int ia64_sal_oemcall_reentrant(struct ia64_sal_retval *, u64, u64, u64,
+				      u64, u64, u64, u64, u64);
 
 #endif /* __ASSEMBLY__ */
 
diff -Nru a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
--- a/include/asm-ia64/sn/sn_cpuid.h	2004-08-25 19:44:40 -07:00
+++ b/include/asm-ia64/sn/sn_cpuid.h	2004-08-25 19:44:40 -07:00
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -93,6 +93,7 @@
  */
 #define cpu_physical_id_to_nasid(cpi)		((cpi) &0xfff)
 #define cpu_physical_id_to_slice(cpi)		((cpi>>12) & 3)
+#define cpu_physical_id_to_coherence_id(cpi)	(cpu_physical_id_to_nasid(cpi) >> 9)
 #define get_nasid()				((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xfff)
 #define get_slice()				((ia64_getreg(_IA64_REG_CR_LID) >> 28) & 0xf)
 #define get_node_number(addr)			(((unsigned long)(addr)>>38) & 0x7ff)
@@ -172,6 +173,11 @@
 
 #define smp_physical_node_id()			(cpuid_to_nasid(smp_processor_id()))
 
+/*
+ * cpuid_to_coherence_id - convert a cpuid to the coherence domain id it
+ * resides on
+ */
+#define cpuid_to_coherence_id(cpuid)	cpu_physical_id_to_coherence_id(cpu_physical_id(cpuid))
 
 #endif /* _ASM_IA64_SN_SN_CPUID_H */
 
diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
--- a/include/asm-ia64/tlb.h	2004-08-25 19:44:40 -07:00
+++ b/include/asm-ia64/tlb.h	2004-08-25 19:44:40 -07:00
@@ -39,6 +39,7 @@
  */
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <linux/pagemap.h>
 #include <linux/swap.h>
 
 #include <asm/pgalloc.h>
diff -Nru a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
--- a/include/asm-ia64/tlbflush.h	2004-08-25 19:44:40 -07:00
+++ b/include/asm-ia64/tlbflush.h	2004-08-25 19:44:40 -07:00
@@ -48,22 +48,19 @@
 static inline void
 flush_tlb_mm (struct mm_struct *mm)
 {
-	MMU_TRACE('F', smp_processor_id(), mm, mm->context);
 	if (!mm)
-		goto out;
+		return;
 
 	mm->context = 0;
 
 	if (atomic_read(&mm->mm_users) == 0)
-		goto out;		/* happens as a result of exit_mmap() */
+		return;		/* happens as a result of exit_mmap() */
 
 #ifdef CONFIG_SMP
 	smp_flush_tlb_mm(mm);
 #else
 	local_finish_flush_tlb_mm(mm);
 #endif
-  out:
-	MMU_TRACE('f', smp_processor_id(), mm, mm->context);
 }
 
 extern void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end);
diff -Nru a/include/linux/timex.h b/include/linux/timex.h
--- a/include/linux/timex.h	2004-08-25 19:44:40 -07:00
+++ b/include/linux/timex.h	2004-08-25 19:44:40 -07:00
@@ -47,14 +47,18 @@
  *      kernel PLL updated to 1994-12-13 specs (rfc-1589)
  * 1997-08-30    Ulrich Windl
  *      Added new constant NTP_PHASE_LIMIT
+ * 2004-08-12    Christoph Lameter
+ *      Reworked time interpolation logic
  */
 #ifndef _LINUX_TIMEX_H
 #define _LINUX_TIMEX_H
 
 #include <linux/config.h>
 #include <linux/compiler.h>
+#include <linux/jiffies.h>
 
 #include <asm/param.h>
+#include <asm/io.h>
 
 /*
  * The following defines establish the engineering parameters of the PLL
@@ -320,81 +324,148 @@
 
 #ifdef CONFIG_TIME_INTERPOLATION
 
-struct time_interpolator {
-	/* cache-hot stuff first: */
-	unsigned long (*get_offset) (void);
-	void (*update) (long);
-	void (*reset) (void);
+#define TIME_SOURCE_CPU 0
+#define TIME_SOURCE_MMIO64 1
+#define TIME_SOURCE_MMIO32 2
+#define TIME_SOURCE_FUNCTION 3
+
+/* For proper operations time_interpolator clocks must run slightly slower
+ * than the standard clock since the interpolator may only correct by having
+ * time jump forward during a tick. A slower clock is usually a side effect
+ * of the integer divide of the nanoseconds in a second by the frequency.
+ * The accuracy of the division can be increased by specifying a shift.
+ * However, this may cause the clock not to be slow enough.
+ * The interpolator will self-tune the clock by slowing down if no
+ * resets occur or speeding up if the time jumps per analysis cycle
+ * become too high.
+ *
+ * Setting jitter compensates for a fluctuating timesource by comparing
+ * to the last value read from the timesource to insure that an earlier value
+ * is not returned by a later call. The price to pay
+ * for the compensation is that the timer routines are not as scalable anymore.
+ */
 
-	/* cache-cold stuff follows here: */
-	struct time_interpolator *next;
+#define INTERPOLATOR_ADJUST 65536
+#define INTERPOLATOR_MAX_SKIP 10*INTERPOLATOR_ADJUST
+
+struct time_interpolator {
+	unsigned short source;		/* time source flags */
+	unsigned char shift;		/* increases accuracy of multiply by shifting. */
+			/* Note that bits may be lost if shift is set too high */
+	unsigned char jitter;		/* if set compensate for fluctuations */
+	unsigned nsec_per_cyc;		/* set by register_time_interpolator() */
+	void *addr;			/* address of counter or function */
+	unsigned long offset;		/* nsec offset at last update of interpolator */
+	unsigned long last_counter;	/* counter value in units of the counter at last update */
+	unsigned long last_cycle;	/* Last timer value if TIME_SOURCE_JITTER is set */
 	unsigned long frequency;	/* frequency in counts/second */
 	long drift;			/* drift in parts-per-million (or -1) */
+	unsigned long skips;		/* skips forward */
+	unsigned long ns_skipped;	/* nanoseconds skipped */
+	struct time_interpolator *next;
 };
 
-extern volatile unsigned long last_nsec_offset;
-#ifndef __HAVE_ARCH_CMPXCHG
-extern spin_lock_t last_nsec_offset_lock;
-#endif
 extern struct time_interpolator *time_interpolator;
 
-extern void register_time_interpolator(struct time_interpolator *);
-extern void unregister_time_interpolator(struct time_interpolator *);
+static inline unsigned long
+time_interpolator_get_cycles(unsigned int src)
+{
+	unsigned long (*x)(void);
 
-/* Called with xtime WRITE-lock acquired.  */
-static inline void
-time_interpolator_update(long delta_nsec)
+	switch (src)
+	{
+		case TIME_SOURCE_FUNCTION:
+			x = time_interpolator->addr;
+			return x();
+
+		case TIME_SOURCE_MMIO64	:
+			return readq(time_interpolator->addr);
+
+		case TIME_SOURCE_MMIO32	:
+			return readl(time_interpolator->addr);
+
+		default: return get_cycles();
+	}
+}
+
+static inline unsigned long
+time_interpolator_get_counter(void)
 {
-	struct time_interpolator *ti = time_interpolator;
+	unsigned int src = time_interpolator->source;
 
-	if (last_nsec_offset > 0) {
-#ifdef __HAVE_ARCH_CMPXCHG
-		unsigned long new, old;
+	if (time_interpolator->jitter)
+	{
+		unsigned long lcycle;
+		unsigned long now;
 
 		do {
-			old = last_nsec_offset;
-			if (old > delta_nsec)
-				new = old - delta_nsec;
-			else
-				new = 0;
-		} while (cmpxchg(&last_nsec_offset, old, new) != old);
-#else
-		/*
-		 * This really hurts, because it serializes gettimeofday(), but without an
-		 * atomic single-word compare-and-exchange, there isn't all that much else
-		 * we can do.
-		 */
-		spin_lock(&last_nsec_offset_lock);
-		{
-			last_nsec_offset -= min(last_nsec_offset, delta_nsec);
-		}
-		spin_unlock(&last_nsec_offset_lock);
-#endif
+			lcycle = time_interpolator->last_cycle;
+			now = time_interpolator_get_cycles(src);
+			if (lcycle && time_after(lcycle,now)) return lcycle;
+			/* Keep track of the last timer value returned. The use of cmpxchg here
+			 * will cause contention in an SMP environment.
+			 */
+		} while (unlikely(cmpxchg(&time_interpolator->last_cycle,lcycle,now) != lcycle));
+		return now;
 	}
-
-	if (ti)
-		(*ti->update)(delta_nsec);
+	else
+		return time_interpolator_get_cycles(src);
 }
 
-/* Called with xtime WRITE-lock acquired.  */
+extern void register_time_interpolator(struct time_interpolator *);
+extern void unregister_time_interpolator(struct time_interpolator *);
+
 static inline void
 time_interpolator_reset(void)
 {
-	struct time_interpolator *ti = time_interpolator;
-
-	last_nsec_offset = 0;
-	if (ti)
-		(*ti->reset)();
+	time_interpolator->offset = 0;
+	time_interpolator->last_counter = time_interpolator_get_counter();
 }
 
-/* Called with xtime READ-lock acquired.  */
+#define GET_TI_NSECS(count,i) ((((count) - i->last_counter) * i->nsec_per_cyc) >> i->shift)
+
 static inline unsigned long
 time_interpolator_get_offset(void)
 {
-	struct time_interpolator *ti = time_interpolator;
-	if (ti)
-		return (*ti->get_offset)();
-	return last_nsec_offset;
+	return time_interpolator->offset +
+		GET_TI_NSECS(time_interpolator_get_counter(),time_interpolator);
+}
+
+static inline void time_interpolator_update(long delta_nsec)
+{
+	unsigned long counter=time_interpolator_get_counter();
+	unsigned long offset=time_interpolator->offset + GET_TI_NSECS(counter,time_interpolator);
+
+	/* The interpolator compensates for late ticks by accumulating
+         * the late time in time_interpolator->offset. A tick earlier than
+	 * expected will lead to a reset of the offset and a corresponding
+	 * jump of the clock forward. Again this only works if the
+	 * interpolator clock is running slightly slower than the regular clock
+	 * and the tuning logic insures that.
+         */
+
+	if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
+		time_interpolator->offset = offset - delta_nsec;
+	else {
+		time_interpolator->skips++;
+		time_interpolator->ns_skipped += delta_nsec - offset;
+		time_interpolator->offset = 0;
+	}
+	time_interpolator->last_counter = counter;
+
+	/* Tuning logic for time interpolator invoked every minute or so.
+	 * Decrease interpolator clock speed if no skips occurred and an offset is carried.
+	 * Increase interpolator clock speed if we skip too much time.
+	 */
+	if (jiffies % INTERPOLATOR_ADJUST == 0)
+	{
+		if (time_interpolator->skips == 0 && time_interpolator->offset > TICK_NSEC)
+			time_interpolator->nsec_per_cyc--;
+		if (time_interpolator->ns_skipped > INTERPOLATOR_MAX_SKIP && time_interpolator->offset == 0)
+			time_interpolator->nsec_per_cyc++;
+		time_interpolator->skips = 0;
+		time_interpolator->ns_skipped = 0;
+	}
 }
 
 #else /* !CONFIG_TIME_INTERPOLATION */
diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c	2004-08-25 19:44:40 -07:00
+++ b/kernel/posix-timers.c	2004-08-25 19:44:40 -07:00
@@ -219,6 +219,11 @@
 		.clock_set = do_posix_clock_monotonic_settime
 	};
 
+#ifdef CONFIG_TIME_INTERPOLATION
+	/* Clocks are more accurate with time interpolators */
+	clock_realtime.res = clock_monotonic.res = NSEC_PER_SEC/time_interpolator->frequency;
+#endif
+
 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
 
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	2004-08-25 19:44:40 -07:00
+++ b/kernel/timer.c	2004-08-25 19:44:40 -07:00
@@ -619,6 +619,9 @@
 	if (xtime.tv_sec % 86400 == 0) {
 	    xtime.tv_sec--;
 	    wall_to_monotonic.tv_sec++;
+	    /* The timer interpolator will make time change gradually instead
+	     * of an immediate jump by one second.
+	     */
 	    time_interpolator_update(-NSEC_PER_SEC);
 	    time_state = TIME_OOP;
 	    clock_was_set();
@@ -630,6 +633,7 @@
 	if ((xtime.tv_sec + 1) % 86400 == 0) {
 	    xtime.tv_sec++;
 	    wall_to_monotonic.tv_sec--;
+	    /* Use of time interpolator for a gradual change of time */
 	    time_interpolator_update(NSEC_PER_SEC);
 	    time_state = TIME_WAIT;
 	    clock_was_set();
@@ -1425,10 +1429,6 @@
 }
 
 #ifdef CONFIG_TIME_INTERPOLATION
-volatile unsigned long last_nsec_offset;
-#ifndef __HAVE_ARCH_CMPXCHG
-spinlock_t last_nsec_offset_lock = SPIN_LOCK_UNLOCKED;
-#endif
 
 struct time_interpolator *time_interpolator;
 static struct time_interpolator *time_interpolator_list;
@@ -1439,17 +1439,21 @@
 {
 	if (!time_interpolator)
 		return 1;
-	return new->frequency > 2*time_interpolator->frequency ||
+	return new->frequency > 2 * time_interpolator->frequency ||
 	    (unsigned long)new->drift < (unsigned long)time_interpolator->drift;
 }
 
 void
 register_time_interpolator(struct time_interpolator *ti)
 {
+	ti->nsec_per_cyc = (NSEC_PER_SEC << ti->shift) / ti->frequency;
 	spin_lock(&time_interpolator_lock);
 	write_seqlock_irq(&xtime_lock);
 	if (is_better_time_interpolator(ti))
+	{
 		time_interpolator = ti;
+		time_interpolator_reset();
+	}
 	write_sequnlock_irq(&xtime_lock);
 
 	ti->next = time_interpolator_list;
@@ -1480,6 +1484,7 @@
 		for (curr = time_interpolator_list; curr; curr = curr->next)
 			if (is_better_time_interpolator(curr))
 				time_interpolator = curr;
+		time_interpolator_reset();
 	}
 	write_sequnlock_irq(&xtime_lock);
 	spin_unlock(&time_interpolator_lock);
