Commit deb8e8c4 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://lia64.bkbits.net/linux-ia64-release-2.6.9

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents bb74564f 65fd90f1
...@@ -145,6 +145,9 @@ ia32_gdt_init (void) ...@@ -145,6 +145,9 @@ ia32_gdt_init (void)
int cpu = smp_processor_id(); int cpu = smp_processor_id();
ia32_shared_page[cpu] = alloc_page(GFP_KERNEL); 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]); cpu_gdt_table[cpu] = page_address(ia32_shared_page[cpu]);
/* Copy from the boot cpu's GDT */ /* Copy from the boot cpu's GDT */
...@@ -161,6 +164,9 @@ ia32_boot_gdt_init (void) ...@@ -161,6 +164,9 @@ ia32_boot_gdt_init (void)
unsigned long ldt_size; unsigned long ldt_size;
ia32_shared_page[0] = alloc_page(GFP_KERNEL); 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]); ia32_boot_gdt = page_address(ia32_shared_page[0]);
cpu_gdt_table[0] = ia32_boot_gdt; cpu_gdt_table[0] = ia32_boot_gdt;
......
#include <linux/module.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/io.h>
/* IBM Summit (EXA) Cyclone counter code*/ /* IBM Summit (EXA) Cyclone counter code*/
#define CYCLONE_CBAR_ADDR 0xFEB00CD0 #define CYCLONE_CBAR_ADDR 0xFEB00CD0
......
...@@ -781,8 +781,7 @@ GLOBAL_ENTRY(ia64_switch_mode_virt) ...@@ -781,8 +781,7 @@ GLOBAL_ENTRY(ia64_switch_mode_virt)
// going to virtual // going to virtual
// - for code addresses, set upper bits of addr to KERNEL_START // - 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 // - for stack addresses, copy from input argument
// lower bits since we want it to stay identity mapped
movl r18=KERNEL_START movl r18=KERNEL_START
dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT 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 dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
......
...@@ -371,7 +371,7 @@ ia64_init_itm (void) ...@@ -371,7 +371,7 @@ ia64_init_itm (void)
itc_drift = -1; itc_drift = -1;
local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; 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(), "ITC freq=%lu.%03luMHz+/-%ldppm\n", smp_processor_id(),
platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000, itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000,
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* 03/05/07 davidm Switch from PCI-DMA to generic device DMA API. * 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 * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid
* unnecessary i-cache flushing. * unnecessary i-cache flushing.
* 04/07/.. ak Better overflow handling. Assorted fixes.
*/ */
#include <linux/cache.h> #include <linux/cache.h>
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/ctype.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/pci.h> #include <asm/pci.h>
...@@ -46,6 +48,8 @@ ...@@ -46,6 +48,8 @@
*/ */
#define IO_TLB_SHIFT 11 #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 * 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. * if the memory was in fact allocated by this API.
...@@ -55,8 +59,16 @@ static char *io_tlb_start, *io_tlb_end; ...@@ -55,8 +59,16 @@ static char *io_tlb_start, *io_tlb_end;
/* /*
* The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and io_tlb_end. * 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. * 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 * This is a free list describing the number of free entries available from each index
...@@ -78,15 +90,19 @@ static spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED; ...@@ -78,15 +90,19 @@ static spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED;
static int __init static int __init
setup_io_tlb_npages (char *str) setup_io_tlb_npages (char *str)
{ {
io_tlb_nslabs = simple_strtoul(str, NULL, 0) << (PAGE_SHIFT - IO_TLB_SHIFT); if (isdigit(*str)) {
io_tlb_nslabs = simple_strtoul(str, &str, 0) << (PAGE_SHIFT - IO_TLB_SHIFT);
/* avoid tail segment of size < IO_TLB_SEGSIZE */ /* avoid tail segment of size < IO_TLB_SEGSIZE */
io_tlb_nslabs = ALIGN(io_tlb_nslabs, 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; return 1;
} }
__setup("swiotlb=", setup_io_tlb_npages); __setup("swiotlb=", setup_io_tlb_npages);
/* make io_tlb_overflow tunable too? */
/* /*
* Statically reserve bounce buffer space and initialize bounce buffer data structures for * Statically reserve bounce buffer space and initialize bounce buffer data structures for
...@@ -102,7 +118,7 @@ swiotlb_init (void) ...@@ -102,7 +118,7 @@ swiotlb_init (void)
*/ */
io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
if (!io_tlb_start) if (!io_tlb_start)
BUG(); panic("Cannot allocate SWIOTLB buffer");
io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
/* /*
...@@ -115,11 +131,23 @@ swiotlb_init (void) ...@@ -115,11 +131,23 @@ swiotlb_init (void)
io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE);
io_tlb_index = 0; io_tlb_index = 0;
io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); 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. * Allocates bounce buffer and returns its kernel virtual address.
*/ */
...@@ -184,11 +212,8 @@ map_single (struct device *hwdev, char *buffer, size_t size, int dir) ...@@ -184,11 +212,8 @@ map_single (struct device *hwdev, char *buffer, size_t size, int dir)
index = 0; index = 0;
} while (index != wrap); } while (index != wrap);
/* spin_unlock_irqrestore(&io_tlb_lock, flags);
* XXX What is a suitable recovery mechanism here? We cannot return NULL;
* sleep because we are called from with in interrupts!
*/
panic("map_single: could not allocate software IO TLB (%ld bytes)", size);
} }
found: found:
spin_unlock_irqrestore(&io_tlb_lock, flags); spin_unlock_irqrestore(&io_tlb_lock, flags);
...@@ -285,7 +310,7 @@ swiotlb_alloc_coherent (struct device *hwdev, size_t size, dma_addr_t *dma_handl ...@@ -285,7 +310,7 @@ swiotlb_alloc_coherent (struct device *hwdev, size_t size, dma_addr_t *dma_handl
memset(ret, 0, size); memset(ret, 0, size);
dev_addr = virt_to_phys(ret); 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"); panic("swiotlb_alloc_consistent: allocated memory is out of range for device");
*dma_handle = dev_addr; *dma_handle = dev_addr;
return ret; return ret;
...@@ -297,6 +322,28 @@ swiotlb_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_ ...@@ -297,6 +322,28 @@ swiotlb_free_coherent (struct device *hwdev, size_t size, void *vaddr, dma_addr_
free_pages((unsigned long) vaddr, get_order(size)); 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 * Map a single buffer of the indicated size for DMA in streaming mode. The PCI address
* to use is returned. * to use is returned.
...@@ -308,13 +355,14 @@ dma_addr_t ...@@ -308,13 +355,14 @@ dma_addr_t
swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, int dir) swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, int dir)
{ {
unsigned long dev_addr = virt_to_phys(ptr); unsigned long dev_addr = virt_to_phys(ptr);
void *map;
if (dir == DMA_NONE) if (dir == DMA_NONE)
BUG(); BUG();
/* /*
* Check if the PCI device can DMA to ptr... if so, just return ptr * 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 * Device is bit capable of DMA'ing to the buffer... just return the PCI
* address of ptr * address of ptr
...@@ -324,12 +372,18 @@ swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, int dir) ...@@ -324,12 +372,18 @@ swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, int dir)
/* /*
* get a bounce buffer: * 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: * 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"); panic("map_single: bounce buffer is not DMA'ble");
return dev_addr; return dev_addr;
...@@ -437,9 +491,17 @@ swiotlb_map_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int di ...@@ -437,9 +491,17 @@ swiotlb_map_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int di
for (i = 0; i < nelems; i++, sg++) { for (i = 0; i < nelems; i++, sg++) {
addr = SG_ENT_VIRT_ADDRESS(sg); addr = SG_ENT_VIRT_ADDRESS(sg);
dev_addr = virt_to_phys(addr); dev_addr = virt_to_phys(addr);
if (hwdev && hwdev->dma_mask && (dev_addr & ~*hwdev->dma_mask) != 0) if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
sg->dma_address = (dma_addr_t) map_single(hwdev, addr, sg->length, dir); sg->dma_address = (dma_addr_t) virt_to_phys(map_single(hwdev, addr, sg->length, dir));
else 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_address = dev_addr;
sg->dma_length = sg->length; sg->dma_length = sg->length;
} }
...@@ -460,7 +522,7 @@ swiotlb_unmap_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int ...@@ -460,7 +522,7 @@ swiotlb_unmap_sg (struct device *hwdev, struct scatterlist *sg, int nelems, int
for (i = 0; i < nelems; i++, sg++) for (i = 0; i < nelems; i++, sg++)
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(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) else if (dir == DMA_FROM_DEVICE)
mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
} }
...@@ -501,7 +563,7 @@ swiotlb_sync_sg_for_device (struct device *hwdev, struct scatterlist *sg, int ne ...@@ -501,7 +563,7 @@ swiotlb_sync_sg_for_device (struct device *hwdev, struct scatterlist *sg, int ne
int int
swiotlb_dma_mapping_error (dma_addr_t dma_addr) swiotlb_dma_mapping_error (dma_addr_t dma_addr)
{ {
return 0; return (dma_addr == virt_to_phys(io_tlb_overflow_buffer));
} }
/* /*
......
# 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)
/*
* 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
/*
*
* 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 */
}
/*
*
* 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);
/*
* 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) }
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
*
* 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;
}
#!/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
This diff is collapsed.
...@@ -290,6 +290,7 @@ sn_pci_fixup_slot(struct pci_dev *dev) ...@@ -290,6 +290,7 @@ sn_pci_fixup_slot(struct pci_dev *dev)
addr |= __IA64_UNCACHED_OFFSET; addr |= __IA64_UNCACHED_OFFSET;
dev->resource[idx].start = addr; dev->resource[idx].start = addr;
dev->resource[idx].end = addr + size; dev->resource[idx].end = addr + size;
dev->resource[idx].parent = &ioport_resource;
} }
if (dev->resource[idx].flags & IORESOURCE_IO) if (dev->resource[idx].flags & IORESOURCE_IO)
...@@ -322,6 +323,7 @@ sn_pci_fixup_slot(struct pci_dev *dev) ...@@ -322,6 +323,7 @@ sn_pci_fixup_slot(struct pci_dev *dev)
addr |= __IA64_UNCACHED_OFFSET; addr |= __IA64_UNCACHED_OFFSET;
dev->resource[idx].start = addr; dev->resource[idx].start = addr;
dev->resource[idx].end = addr + size; dev->resource[idx].end = addr + size;
dev->resource[idx].parent = &iomem_resource;
} }
if (dev->resource[idx].flags & IORESOURCE_MEM) if (dev->resource[idx].flags & IORESOURCE_MEM)
...@@ -351,6 +353,7 @@ sn_pci_fixup_slot(struct pci_dev *dev) ...@@ -351,6 +353,7 @@ sn_pci_fixup_slot(struct pci_dev *dev)
addr |= __IA64_UNCACHED_OFFSET; addr |= __IA64_UNCACHED_OFFSET;
dev->resource[PCI_ROM_RESOURCE].start = addr; dev->resource[PCI_ROM_RESOURCE].start = addr;
dev->resource[PCI_ROM_RESOURCE].end = addr + size; dev->resource[PCI_ROM_RESOURCE].end = addr + size;
dev->resource[idx].parent = &iomem_resource;
if (dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_MEM) if (dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY; cmd |= PCI_COMMAND_MEMORY;
} }
......
...@@ -421,9 +421,10 @@ bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode) ...@@ -421,9 +421,10 @@ bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda; mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda;
for (i = 0; i < BTES_PER_NODE; i++) { for (i = 0; i < BTES_PER_NODE; i++) {
(u64) mynodepda->bte_if[i].bte_base_addr = /* Which link status register should we use? */
REMOTE_HUB_ADDR(cnodeid_to_nasid(cnode), unsigned long link_status = (i == 0 ? IIO_IBLS0 : IIO_IBLS1);
(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 * Initialize the notification and spinlock
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * 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 <linux/config.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -118,11 +118,33 @@ register_sn_force_interrupt(void) { ...@@ -118,11 +118,33 @@ register_sn_force_interrupt(void) {
} }
} }
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 void
register_sn_procfs(void) { register_sn_procfs(void) {
register_sn_partition_id(); register_sn_partition_id();
register_sn_serial_numbers(); register_sn_serial_numbers();
register_sn_force_interrupt(); register_sn_force_interrupt();
register_sn_coherence_id();
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
...@@ -96,7 +96,6 @@ static inline void disable_acpi(void) { } ...@@ -96,7 +96,6 @@ static inline void disable_acpi(void) { }
const char *acpi_get_sysname (void); const char *acpi_get_sysname (void);
int acpi_request_vector (u32 int_type); 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); int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
#ifdef CONFIG_ACPI_NUMA #ifdef CONFIG_ACPI_NUMA
......
...@@ -364,7 +364,7 @@ typedef struct sal_processor_static_info { ...@@ -364,7 +364,7 @@ typedef struct sal_processor_static_info {
u64 cr[128]; u64 cr[128];
u64 ar[128]; u64 ar[128];
u64 rr[8]; u64 rr[8];
struct ia64_fpreg fr[128]; struct ia64_fpreg __attribute__ ((packed)) fr[128];
} sal_processor_static_info_t; } sal_processor_static_info_t;
struct sal_cpuid_info { struct sal_cpuid_info {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * 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 @@ ...@@ -93,6 +93,7 @@
*/ */
#define cpu_physical_id_to_nasid(cpi) ((cpi) &0xfff) #define cpu_physical_id_to_nasid(cpi) ((cpi) &0xfff)
#define cpu_physical_id_to_slice(cpi) ((cpi>>12) & 3) #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_nasid() ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xfff)
#define get_slice() ((ia64_getreg(_IA64_REG_CR_LID) >> 28) & 0xf) #define get_slice() ((ia64_getreg(_IA64_REG_CR_LID) >> 28) & 0xf)
#define get_node_number(addr) (((unsigned long)(addr)>>38) & 0x7ff) #define get_node_number(addr) (((unsigned long)(addr)>>38) & 0x7ff)
...@@ -172,6 +173,11 @@ extern short physical_node_map[]; /* indexed by nasid to get cnode */ ...@@ -172,6 +173,11 @@ extern short physical_node_map[]; /* indexed by nasid to get cnode */
#define smp_physical_node_id() (cpuid_to_nasid(smp_processor_id())) #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 */ #endif /* _ASM_IA64_SN_SN_CPUID_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment