EXTRA_CFLAGS := -DLITTLE_ENDIAN
-obj-y += sgi_if.o xswitch.o sgi_io_sim.o cdl.o ate_utils.o \
+obj-y += sgi_if.o xswitch.o sgi_io_sim.o cdl.o \
io.o machvec/ drivers/ platform_init/ sn2/ hwgfs/
+++ /dev/null
-/* $Id: ate_utils.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.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/io.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/sn_private.h>
-
-#include <asm/sn/ate_utils.h>
-
-/*
- * Allocate the map needed to allocate the ATE entries.
- */
-struct map *
-atemapalloc(ulong_t mapsiz)
-{
- struct map *mp;
- ulong_t size;
- struct a {
- spinlock_t lock;
- sv_t sema;
- } *sync;
-
- if (mapsiz == 0)
- return(NULL);
- size = sizeof(struct map) * (mapsiz + 2);
- if ((mp = (struct map *) kmalloc(size, GFP_KERNEL)) == NULL)
- return(NULL);
- memset(mp, 0x0, size);
-
- sync = kmalloc(sizeof(struct a), GFP_KERNEL);
- if (sync == NULL) {
- kfree(mp);
- return(NULL);
- }
- memset(sync, 0x0, sizeof(struct a));
-
- mutex_spinlock_init(&sync->lock);
- sv_init( &(sync->sema), &(sync->lock), SV_MON_SPIN | SV_ORDER_FIFO /*| SV_INTS*/);
- mp[1].m_size = (unsigned long) &sync->lock;
- mp[1].m_addr = (unsigned long) &sync->sema;
- mapsize(mp) = mapsiz - 1;
- return(mp);
-}
-
-/*
- * free a map structure previously allocated via rmallocmap().
- */
-void
-atemapfree(struct map *mp)
-{
- struct a {
- spinlock_t lock;
- sv_t sema;
- };
- /* ASSERT(sv_waitq(mapout(mp)) == 0); */
- /* sv_destroy(mapout(mp)); */
- spin_lock_destroy(maplock(mp));
- kfree((void *)mp[1].m_size);
- kfree(mp);
-}
-
-/*
- * Allocate 'size' units from the given map.
- * Return the base of the allocated space.
- * In a map, the addresses are increasing and the
- * list is terminated by a 0 size.
- * Algorithm is first-fit.
- */
-
-ulong_t
-atealloc(
- struct map *mp,
- size_t size)
-{
- register unsigned int a;
- register struct map *bp;
- register unsigned long s;
-
- ASSERT(size >= 0);
-
- if (size == 0)
- return((ulong_t) NULL);
-
- s = mutex_spinlock(maplock(mp));
-
- for (bp = mapstart(mp); bp->m_size; bp++) {
- if (bp->m_size >= size) {
- a = bp->m_addr;
- bp->m_addr += size;
- if ((bp->m_size -= size) == 0) {
- do {
- bp++;
- (bp-1)->m_addr = bp->m_addr;
- } while ((((bp-1)->m_size) = (bp->m_size)));
- mapsize(mp)++;
- }
-
- ASSERT(bp->m_size < 0x80000000);
- mutex_spinunlock(maplock(mp), s);
- return(a);
- }
- }
-
- /*
- * We did not get what we need .. we cannot sleep ..
- */
- mutex_spinunlock(maplock(mp), s);
- return(0);
-}
-
-/*
- * Free the previously allocated space a of size units into the specified map.
- * Sort ``a'' into map and combine on one or both ends if possible.
- * Returns 0 on success, 1 on failure.
- */
-void
-atefree(struct map *mp, size_t size, ulong_t a)
-{
- register struct map *bp;
- register unsigned int t;
- register unsigned long s;
-
- ASSERT(size >= 0);
-
- if (size == 0)
- return;
-
- bp = mapstart(mp);
- s = mutex_spinlock(maplock(mp));
-
- for ( ; bp->m_addr<=a && bp->m_size!=0; bp++)
- ;
- if (bp>mapstart(mp) && (bp-1)->m_addr+(bp-1)->m_size == a) {
- (bp-1)->m_size += size;
- if (bp->m_addr) {
- /* m_addr==0 end of map table */
- ASSERT(a+size <= bp->m_addr);
- if (a+size == bp->m_addr) {
-
- /* compress adjacent map addr entries */
- (bp-1)->m_size += bp->m_size;
- while (bp->m_size) {
- bp++;
- (bp-1)->m_addr = bp->m_addr;
- (bp-1)->m_size = bp->m_size;
- }
- mapsize(mp)++;
- }
- }
- } else {
- if (a+size == bp->m_addr && bp->m_size) {
- bp->m_addr -= size;
- bp->m_size += size;
- } else {
- ASSERT(size);
- if (mapsize(mp) == 0) {
- mutex_spinunlock(maplock(mp), s);
- printk("atefree : map overflow 0x%p Lost 0x%lx items at 0x%lx",
- (void *)mp, size, a) ;
- return ;
- }
- do {
- t = bp->m_addr;
- bp->m_addr = a;
- a = t;
- t = bp->m_size;
- bp->m_size = size;
- bp++;
- } while ((size = t));
- mapsize(mp)--;
- }
- }
- mutex_spinunlock(maplock(mp), s);
- /*
- * wake up everyone waiting for space
- */
- if (mapout(mp))
- ;
- /* sv_broadcast(mapout(mp)); */
-}
}
static struct super_block *hwgfs_get_sb(struct file_system_type *fs_type,
- int flags, char *dev_name, void *data)
+ int flags, const char *dev_name, void *data)
{
return get_sb_single(fs_type, flags, data, hwgfs_fill_super);
}
sn_io_addr(unsigned long port)
{
if (!IS_RUNNING_ON_SIMULATOR()) {
+ /* On sn2, legacy I/O ports don't point at anything */
+ if (port < 64*1024)
+ return 0;
return( (void *) (port | __IA64_UNCACHED_OFFSET));
} else {
+ /* but the simulator uses them... */
unsigned long io_base;
unsigned long addr;
*dma_handle = 0;
- /* We can't easily support < 32 bit devices */
- if (IS_PCI32L(hwdev))
+ if (hwdev->dma_mask < 0xffffffffUL)
return NULL;
/*
if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
return NULL;
- memset(cpuaddr, 0, size); /* have to zero it out */
-
/* physical addr. of the memory we just got */
phys_addr = __pa(cpuaddr);
((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
PCIIO_DMA_CMD);
+ /*
+ * If this device is in PCI-X mode, the system would have
+ * automatically allocated a 64Bits DMA Address. Error out if the
+ * device cannot support DAC.
+ */
+ if (*dma_handle > hwdev->consistent_dma_mask) {
+ free_pages((unsigned long) cpuaddr, get_order(size));
+ return NULL;
+ }
+
/*
* It is a 32 bit card and we cannot do direct mapping,
* so we try to use an ATE.
}
-#define xtod(c) ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10)
-long
-atoi(register char *p)
-{
- register long n;
- register int c, neg = 0;
-
- if (p == NULL)
- return 0;
-
- if (!isdigit(c = *p)) {
- while (isspace(c))
- c = *++p;
- switch (c) {
- case '-':
- neg++;
- case '+': /* fall-through */
- c = *++p;
- }
- if (!isdigit(c))
- return (0);
- }
- if (c == '0' && *(p + 1) == 'x') {
- p += 2;
- c = *p;
- n = xtod(c);
- while ((c = *++p) && isxdigit(c)) {
- n *= 16; /* two steps to avoid unnecessary overflow */
- n += xtod(c); /* accum neg to avoid surprises at MAX */
- }
- } else {
- n = '0' - c;
- while ((c = *++p) && isdigit(c)) {
- n *= 10; /* two steps to avoid unnecessary overflow */
- n += '0' - c; /* accum neg to avoid surprises at MAX */
- }
- }
- return (neg ? n : -n);
-}
-
/*
* print_register() allows formatted printing of bit fields. individual
* bit fields are described by a struct reg_desc, multiple bit fields within
EXTRA_CFLAGS := -DLITTLE_ENDIAN
obj-y += pcibr/ ml_SN_intr.o shub_intr.o shuberror.o shub.o bte_error.o \
- pic.o geo_op.o l1.o l1_command.o klconflib.o klgraph.o ml_SN_init.o \
+ pic.o geo_op.o l1_command.o klconflib.o klgraph.o ml_SN_init.o \
ml_iograph.o module.o pciio.o xbow.o xtalk.o shubio.o
obj-$(CONFIG_KDB) += kdba_io.o
+++ /dev/null
-/* $Id$
- *
- * 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.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- * UART routines
- * Bedrock/L1 "PPP-like" protocol implementation
- * System controller "message" interface (allows multiplexing
- * of various kinds of requests and responses with
- * console I/O)
- * Console interface:
- * "l1_cons", the glue that allows the L1 to act
- * as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <asm/io.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-
-#define UART_BAUD_RATE 57600
-
-static int L1_connected; /* non-zero when interrupts are enabled */
-
-
-int
-get_L1_baud(void)
-{
- return UART_BAUD_RATE;
-}
-
-
-
-/* Return the current interrupt level */
-int
-l1_get_intr_value( void )
-{
- cpuid_t intr_cpuid;
- nasid_t console_nasid;
- int major, minor;
- extern nasid_t get_console_nasid(void);
-
- /* if it is an old prom, run in poll mode */
-
- major = sn_sal_rev_major();
- minor = sn_sal_rev_minor();
- if ( (major < 1) || ((major == 1) && (minor < 10)) ) {
- /* before version 1.10 doesn't work */
- return (0);
- }
-
- console_nasid = get_console_nasid();
- intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu;
- return CPU_VECTOR_TO_IRQ(intr_cpuid, SGI_UART_VECTOR);
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-int
-l1_connect_intr(void *intr_func, void *arg, struct pt_regs *ep)
-{
- cpuid_t intr_cpuid;
- nasid_t console_nasid;
- unsigned int console_irq;
- int result;
- extern int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
- extern nasid_t get_console_nasid(void);
-
-
- /* don't call to connect multiple times - we DON'T support changing the handler */
-
- if ( !L1_connected ) {
- L1_connected++;
- console_nasid = get_console_nasid();
- intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu;
- console_irq = CPU_VECTOR_TO_IRQ(intr_cpuid, SGI_UART_VECTOR);
- result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR,
- 0 /*not used*/, 0 /*not used*/);
- if (result != SGI_UART_VECTOR) {
- if (result < 0)
- printk(KERN_WARNING "L1 console driver : intr_connect_level failed %d\n", result);
- else
- printk(KERN_WARNING "L1 console driver : intr_connect_level returns wrong bit %d\n", result);
- return (-1);
- }
-
- result = request_irq(console_irq, intr_func, SA_INTERRUPT,
- "SGI L1 console driver", (void *)arg);
- if (result < 0) {
- printk(KERN_WARNING "L1 console driver : request_irq failed %d\n", result);
- return (-1);
- }
-
- /* ask SAL to turn on interrupts in the UART itself */
- ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
- }
- return (0);
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
- /* quietly ignore unless simulator */
- if ( IS_RUNNING_ON_SIMULATOR() ) {
- extern u64 master_node_bedrock_address;
- if ( master_node_bedrock_address != (u64)0 ) {
- writeb(value, (unsigned long)master_node_bedrock_address +
- (offset<< 3));
- }
- return;
- }
-}
-
-/* Console input exported interface. Return a register value. */
-
-int
-l1_control_in_polled(int offset)
-{
- static int l1_control_in_local(int);
-
- return(l1_control_in_local(offset));
-}
-
-int
-l1_control_in(int offset)
-{
- static int l1_control_in_local(int);
-
- return(l1_control_in_local(offset));
-}
-
-static int
-l1_control_in_local(int offset)
-{
- int sal_call_status = 0, input;
- int ret = 0;
-
- if ( IS_RUNNING_ON_SIMULATOR() ) {
- extern u64 master_node_bedrock_address;
- ret = readb((unsigned long)master_node_bedrock_address +
- (offset<< 3));
- return(ret);
- }
- if ( offset == REG_LSR ) {
- ret = (LSR_XHRE | LSR_XSRE); /* can send anytime */
- sal_call_status = ia64_sn_console_check(&input);
- if ( !sal_call_status && input ) {
- /* input pending */
- ret |= LSR_RCA;
- }
- }
- return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
- static int l1_serial_in_local(void);
-
- return(l1_serial_in_local());
-}
-
-int
-l1_serial_in(void)
-{
- static int l1_serial_in_local(void);
-
- if ( IS_RUNNING_ON_SIMULATOR() ) {
- extern u64 master_node_bedrock_address;
- return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
- }
- return(l1_serial_in_local());
-}
-
-static int
-l1_serial_in_local(void)
-{
- int ch;
-
- if ( IS_RUNNING_ON_SIMULATOR() ) {
- extern u64 master_node_bedrock_address;
- return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
- }
-
- if ( !(ia64_sn_console_getc(&ch)) )
- return(ch);
- else
- return(0);
-}
-
-/* Console output exported interface. Write message to the console. */
-
-int
-l1_serial_out( char *str, int len )
-{
- int tmp;
-
- /* Ignore empty messages */
- if ( len == 0 )
- return(len);
-
-#if defined(CONFIG_IA64_EARLY_PRINTK)
- /* Need to setup SAL calls so the PROM calls will work */
- {
- static int inited;
- void early_sn_setup(void);
- if(!inited) {
- inited=1;
- early_sn_setup();
- }
- }
-#endif
-
- if ( IS_RUNNING_ON_SIMULATOR() ) {
- extern u64 master_node_bedrock_address;
- void early_sn_setup(void);
- int counter = len;
-
- if (!master_node_bedrock_address)
- early_sn_setup();
- if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
- /* This is an easy way to pre-pend the output to know whether the output
- * was done via sal or directly */
- writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
- writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
- writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
- writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif /* FLAG_DIRECT_CONSOLE_WRITES */
- while ( counter > 0 ) {
- writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
- counter--;
- str++;
- }
- }
- return(len);
- }
-
- /* Attempt to write things out thru the sal */
- if ( L1_connected )
- tmp = ia64_sn_console_xmit_chars(str, len);
- else
- tmp = ia64_sn_console_putb(str, len);
- return ((tmp < 0) ? 0 : tmp);
-}
if (nserial == 0)
DPRINTF(KERN_WARNING "io_module_init: No serial number found.\n");
}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
- if (cmod < 0 || cmod >= nummodules)
- return -EINVAL;
-
- mod_info->mod_num = modules[cmod]->id;
-
- ia64_sn_sys_serial_get(mod_info->serial_str);
-
- mod_info->serial_num = ia64_sn_partition_serial_get();
-
- return 0;
-}
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
-#ifdef __ia64
-uint64_t atealloc(struct map *mp, size_t size);
-void atefree(struct map *mp, size_t size, uint64_t a);
-void atemapfree(struct map *mp);
-struct map *atemapalloc(uint64_t mapsiz);
-
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-
#ifndef LOCAL
#define LOCAL static
#endif
int
pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
{
- int index = 0;
+ int status = 0;
+ struct resource *new_res;
+ struct resource **allocated_res;
+
+ new_res = (struct resource *) kmalloc( sizeof(struct resource), GFP_ATOMIC);
+ memset(new_res, 0, sizeof(*new_res));
+ status = allocate_resource( &pcibr_soft->bs_int_ate_resource, new_res,
+ count, pcibr_soft->bs_int_ate_resource.start,
+ pcibr_soft->bs_int_ate_resource.end, 1,
+ NULL, NULL);
+
+ if ( status && (pcibr_soft->bs_ext_ate_resource.end != 0) ) {
+ status = allocate_resource( &pcibr_soft->bs_ext_ate_resource, new_res,
+ count, pcibr_soft->bs_ext_ate_resource.start,
+ pcibr_soft->bs_ext_ate_resource.end, 1,
+ NULL, NULL);
+ if (status) {
+ new_res->start = -1;
+ }
+ }
- index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
+ if (status) {
+ /* Failed to allocate */
+ kfree(new_res);
+ return -1;
+ }
- if (!index && pcibr_soft->bs_ext_ate_map)
- index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
+ /* Save the resource for freeing */
+ allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + new_res->start * sizeof( unsigned long));
+ *allocated_res = new_res;
- /* rmalloc manages resources in the 1..n
- * range, with 0 being failure.
- * pcibr_ate_alloc manages resources
- * in the 0..n-1 range, with -1 being failure.
- */
- return index - 1;
+ return new_res->start;
}
void
pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
/* Who says there's no such thing as a free meal? :-) */
{
- /* note the "+1" since rmalloc handles 1..n but
- * we start counting ATEs at zero.
- */
- rmfree((index < pcibr_soft->bs_int_ate_size)
- ? pcibr_soft->bs_int_ate_map
- : pcibr_soft->bs_ext_ate_map,
- count, index + 1);
+
+ struct resource **allocated_res;
+ int status = 0;
+
+ allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + index * sizeof(unsigned long));
+
+ status = release_resource(*allocated_res);
+ if (status)
+ BUG(); /* Ouch .. */
+ kfree(*allocated_res);
+
}
/*
#include <linux/module.h>
#include <linux/string.h>
#include <linux/interrupt.h>
+#include <linux/ioport.h>
#include <asm/sn/sgi.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/sn_cpuid.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
/*
* global variables to toggle the different levels of pcibr debugging.
* -pcibr_debug_mask is the mask of the different types of debugging
xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
if (xp == NULL)
return 0;
- widgetnum = atoi(xp+7);
+ widgetnum = simple_strtoul(xp+7, NULL, 0);
if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
return 0;
/* we always have 128 ATEs (512 for Xbridge) inside the chip
* even if disabled for debugging.
*/
- pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
- pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
+ pcibr_soft->bs_int_ate_resource.start = 0;
+ pcibr_soft->bs_int_ate_resource.end = pcibr_soft->bs_int_ate_size - 1;
if (num_entries > pcibr_soft->bs_int_ate_size) {
#if PCIBR_ATE_NOTBOTH /* for debug -- forces us to use external ates */
printk("pcibr_attach: disabling internal ATEs.\n");
pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
#endif
- pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
- pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
- num_entries - pcibr_soft->bs_int_ate_size);
+ pcibr_soft->bs_ext_ate_resource.start = pcibr_soft->bs_int_ate_size;
+ pcibr_soft->bs_ext_ate_resource.end = num_entries;
}
+
+ pcibr_soft->bs_allocated_ate_res = (void *) kmalloc(pcibr_soft->bs_int_ate_size * sizeof(unsigned long), GFP_KERNEL);
+ memset(pcibr_soft->bs_allocated_ate_res, 0x0, pcibr_soft->bs_int_ate_size * sizeof(unsigned long));
+
PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_vhdl,
"pcibr_attach2: %d ATEs, %d internal & %d external\n",
num_entries ? num_entries : pcibr_soft->bs_int_ate_size,
{
- pciio_win_map_t win_map_p;
iopaddr_t prom_base_addr = pcibr_soft->bs_xid << 24;
int prom_base_size = 0x1000000;
- iopaddr_t prom_base_limit = prom_base_addr + prom_base_size;
+ int status;
+ struct resource *res;
/* Allocate resource maps based on bus page size; for I/O and memory
* space, free all pages except those in the base area and in the
* the widget number and s is the device register offset for the slot.
*/
- win_map_p = &pcibr_soft->bs_io_win_map;
- pciio_device_win_map_new(win_map_p,
- PCIBR_BUS_IO_MAX + 1,
- PCIBR_BUS_IO_PAGE);
- pciio_device_win_populate(win_map_p,
- PCIBR_BUS_IO_BASE,
- prom_base_addr - PCIBR_BUS_IO_BASE);
- pciio_device_win_populate(win_map_p,
- prom_base_limit,
- (PCIBR_BUS_IO_MAX + 1) - prom_base_limit);
-
- win_map_p = &pcibr_soft->bs_swin_map;
- pciio_device_win_map_new(win_map_p,
- PCIBR_BUS_SWIN_MAX + 1,
- PCIBR_BUS_SWIN_PAGE);
- pciio_device_win_populate(win_map_p,
- PCIBR_BUS_SWIN_BASE,
- (PCIBR_BUS_SWIN_MAX + 1) - PCIBR_BUS_SWIN_PAGE);
-
- win_map_p = &pcibr_soft->bs_mem_win_map;
- pciio_device_win_map_new(win_map_p,
- PCIBR_BUS_MEM_MAX + 1,
- PCIBR_BUS_MEM_PAGE);
- pciio_device_win_populate(win_map_p,
- PCIBR_BUS_MEM_BASE,
- prom_base_addr - PCIBR_BUS_MEM_BASE);
- pciio_device_win_populate(win_map_p,
- prom_base_limit,
- (PCIBR_BUS_MEM_MAX + 1) - prom_base_limit);
+ /* Setup the Bus's PCI IO Root Resource. */
+ pcibr_soft->bs_io_win_root_resource.start = PCIBR_BUS_IO_BASE;
+ pcibr_soft->bs_io_win_root_resource.end = 0xffffffff;
+ res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
+ if (!res)
+ panic("PCIBR:Unable to allocate resource structure\n");
+
+ /* Block off the range used by PROM. */
+ res->start = prom_base_addr;
+ res->end = prom_base_addr + (prom_base_size - 1);
+ status = request_resource(&pcibr_soft->bs_io_win_root_resource, res);
+ if (status)
+ panic("PCIBR:Unable to request_resource()\n");
+
+ /* Setup the Small Window Root Resource */
+ pcibr_soft->bs_swin_root_resource.start = _PAGESZ;
+ pcibr_soft->bs_swin_root_resource.end = 0x000FFFFF;
+
+ /* Setup the Bus's PCI Memory Root Resource */
+ pcibr_soft->bs_mem_win_root_resource.start = 0x200000;
+ pcibr_soft->bs_mem_win_root_resource.end = 0xffffffff;
+ res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
+ if (!res)
+ panic("PCIBR:Unable to allocate resource structure\n");
+
+ /* Block off the range used by PROM. */
+ res->start = prom_base_addr;
+ res->end = prom_base_addr + (prom_base_size - 1);;
+ status = request_resource(&pcibr_soft->bs_mem_win_root_resource, res);
+ if (status)
+ panic("PCIBR:Unable to request_resource()\n");
+
}
/* build "no-slot" connection point
spin_lock_destroy(&pcibr_soft->bs_lock);
kfree(pcibr_soft->bs_name);
- /* Error handler gets unregistered when the widget info is
- * cleaned
- */
- /* Free the soft ATE maps */
- if (pcibr_soft->bs_int_ate_map)
- rmfreemap(pcibr_soft->bs_int_ate_map);
- if (pcibr_soft->bs_ext_ate_map)
- rmfreemap(pcibr_soft->bs_ext_ate_map);
-
/* Disconnect the error interrupt and free the xtalk resources
* associated with it.
*/
cp = strstr(hwpath, "/xtalk/");
if (cp) {
cp += strlen("/xtalk/");
- widget = atoi(cp);
+ widget = simple_strtoul(cp, NULL, 0);
}
}
if (pcibr_debug_slot != -1) {
cp = strstr(hwpath, "/pci/");
if (cp) {
cp += strlen("/pci/");
- slot = atoi(cp);
+ slot = simple_strtoul(cp, NULL, 0);
}
}
}
* Since we have a variable length argument list, we
* need to call printk this way rather than directly
*/
- va_start(ap, format);
- printk(format, ap);
- va_end(ap);
+ {
+ char buffer[500];
+
+ va_start(ap, format);
+ vsnprintf(buffer, 500, format, ap);
+ va_end(ap);
+ buffer[499] = (char)0; /* just to be safe */
+ printk("%s", buffer);
+ }
}
}
}
#include <asm/sn/sn_private.h>
#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-
inline int
compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
{
pcibr_soft = pcibr_soft_get(pcibr_vhdl);
if (!pcibr_soft)
- return(EINVAL);
+ return(-EINVAL);
if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
- return(EINVAL);
+ return(-EINVAL);
bridge = pcibr_soft->bs_base;
pcibr_soft->bs_rrb_valid[slot][3] = chan[3];
- return(ENODEV);
+ return(-ENODEV);
+ }
+
+ /* Give back any assigned to empty slots */
+ if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && !pcibr_soft->bs_slot[slot].has_host) {
+ do_pcibr_rrb_free_all(pcibr_soft, bridge, slot);
+ return(-ENODEV);
}
for (vchan = 0; vchan < vchan_total; vchan++)
#include <asm/sn/ioc3.h>
#include <asm/sn/io.h>
#include <asm/sn/sn_private.h>
-#include <asm/sn/ate_utils.h>
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
extern pcibr_info_t pcibr_info_get(vertex_hdl_t);
extern int pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
error = pcibr_slot_attach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_ATTACH,
l1_msg, &tmp_up_resp.resp_sub_errno);
- strlcpy(tmp_up_resp.resp_l1_msg, l1_msg, L1_QSIZE);
+ strncpy(tmp_up_resp.resp_l1_msg, l1_msg, L1_QSIZE);
tmp_up_resp.resp_l1_msg[L1_QSIZE] = '\0';
if (COPYOUT(&tmp_up_resp, reqp->req_respp.up, reqp->req_size)) {
error = pcibr_slot_detach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_DETACH,
l1_msg, &tmp_down_resp.resp_sub_errno);
- strlcpy(tmp_down_resp.resp_l1_msg, l1_msg,
- sizeof(tmp_down_resp.resp_l1_msg));
+ strncpy(tmp_down_resp.resp_l1_msg, l1_msg, L1_QSIZE);
+ tmp_down_resp.resp_l1_msg[L1_QSIZE] = '\0';
shutdown_copyout:
pciio_space_t space, int start, int size, int align)
{
pciio_win_map_t win_map_p;
+ struct resource *root_resource = NULL;
+ iopaddr_t iopaddr = 0;
switch (space) {
case PCIIO_SPACE_IO:
win_map_p = &pcibr_soft->bs_io_win_map;
+ root_resource = &pcibr_soft->bs_io_win_root_resource;
break;
case PCIIO_SPACE_MEM:
win_map_p = &pcibr_soft->bs_swin_map;
+ root_resource = &pcibr_soft->bs_swin_root_resource;
break;
case PCIIO_SPACE_MEM32:
win_map_p = &pcibr_soft->bs_mem_win_map;
+ root_resource = &pcibr_soft->bs_mem_win_root_resource;
break;
default:
return 0;
}
- return pciio_device_win_alloc(win_map_p,
+ iopaddr = pciio_device_win_alloc(root_resource,
win_info_p
? &win_info_p->w_win_alloc
: NULL,
start, size, align);
+ return(iopaddr);
}
#include <asm/sn/sn_sal.h>
#include <asm/sn/io.h>
#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/ate_utils.h>
#include <asm/sn/simulator.h>
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
#define DEBUG_PCIIO
#undef DEBUG_PCIIO /* turn this on for yet more console output */
return(0);
}
-/* SN2 */
-/*
- * Allocate (if necessary) and initialize a PCI window mapping structure.
- */
-pciio_win_map_t
-pciio_device_win_map_new(pciio_win_map_t win_map,
- size_t region_size,
- size_t page_size)
-{
- ASSERT((page_size & (page_size - 1)) == 0);
- ASSERT((region_size & (page_size - 1)) == 0);
-
- if (win_map == NULL)
- NEW(win_map);
-
- /*
- * The map array tracks the free ``pages'' in the region. The worst
- * case scenario is when every other page in the region is free --
- * e.i. maximum fragmentation. This leads to (max pages + 1) / 2 + 1
- * map entries. The first "+1" handles the divide by 2 rounding; the
- * second handles the need for an end marker sentinel.
- */
- win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1);
- win_map->wm_page_size = page_size;
- ASSERT(win_map->wm_map != NULL);
-
- return win_map;
-}
-
-/*
- * Free resources associated with a PCI window mapping structure.
- */
-extern void
-pciio_device_win_map_free(pciio_win_map_t win_map)
-{
- rmfreemap(win_map->wm_map);
- bzero(win_map, sizeof *win_map);
-}
-
-/*
- * Populate window map with specified free range.
- */
-void
-pciio_device_win_populate(pciio_win_map_t win_map,
- iopaddr_t ioaddr,
- size_t size)
-{
- ASSERT((size & (win_map->wm_page_size - 1)) == 0);
- ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0);
-
- rmfree(win_map->wm_map,
- size / win_map->wm_page_size,
- (unsigned long)ioaddr / win_map->wm_page_size);
-
-}
/*
* Allocate space from the specified PCI window mapping resource. On
* success record information about the allocation in the supplied window
* and alignment.
*/
iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,
+pciio_device_win_alloc(struct resource *root_resource,
pciio_win_alloc_t win_alloc,
size_t start, size_t size, size_t align)
{
- unsigned long base;
-
-#ifdef PIC_LATER
- ASSERT((size & (size - 1)) == 0);
- ASSERT((align & (align - 1)) == 0);
- /*
- * Convert size and alignment to pages. If size is greated than the
- * requested alignment, we bump the alignment up to size; otherwise
- * convert the size into a multiple of the alignment request.
- */
- size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size;
- align = align / win_map->wm_page_size;
- if (size > align)
- align = size;
- else
- size = (size + align - 1) & ~(align - 1);
-
- /* XXXX */
- base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP);
- if (base == RMALLOC_FAIL)
- return((iopaddr_t)NULL);
-#else
- int index_page, index_page_align;
- int align_pages, size_pages;
- int alloc_pages, free_pages;
- int addr_align;
-
- /* Convert PCI bus alignment from bytes to pages */
- align_pages = align / win_map->wm_page_size;
-
- /* Convert PCI request from bytes to pages */
- size_pages = (size / win_map->wm_page_size) +
- ((size % win_map->wm_page_size) ? 1 : 0);
-
- /* Align address with the larger of the size or the requested slot align */
- if (size_pages > align_pages)
- align_pages = size_pages;
-
- /*
- * Avoid wasting space by aligning - 1; this will prevent crossing
- * another alignment boundary.
- */
- alloc_pages = size_pages + (align_pages - 1);
+ struct resource *new_res;
+ int status = 0;
- /* Allocate PCI bus space in pages */
- index_page = (int) rmalloc(win_map->wm_map,
- (size_t) alloc_pages);
+ new_res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
- /* Error if no PCI bus address space available */
- if (!index_page)
- return 0;
-
- /* PCI bus address index starts at 0 */
- index_page--;
-
- /* Align the page offset as requested */
- index_page_align = (index_page + (align_pages - 1)) -
- ((index_page + (align_pages - 1)) % align_pages);
-
- free_pages = (align_pages - 1) - (index_page_align - index_page);
-
- /* Free unused PCI bus pages adjusting the index to start at 1 */
- rmfree(win_map->wm_map,
- free_pages,
- (index_page_align + 1) + size_pages);
-
- /* Return aligned PCI bus space in bytes */
- addr_align = (index_page_align * win_map->wm_page_size);
- base = index_page;
- size = alloc_pages - free_pages;
-#endif /* PIC_LATER */
+ status = allocate_resource( root_resource, new_res,
+ size, align /* Min start addr. */,
+ root_resource->end, align,
+ NULL, NULL);
+ if (status) {
+ kfree(new_res);
+ return((iopaddr_t) NULL);
+ }
/*
* If a window allocation cookie has been supplied, use it to keep
* track of all the allocated space assigned to this window.
*/
if (win_alloc) {
- win_alloc->wa_map = win_map;
- win_alloc->wa_base = base;
+ win_alloc->wa_resource = new_res;
+ win_alloc->wa_base = new_res->start;
win_alloc->wa_pages = size;
}
- return base * win_map->wm_page_size;
+ return new_res->start;;
}
/*
void
pciio_device_win_free(pciio_win_alloc_t win_alloc)
{
- if (win_alloc->wa_pages)
- rmfree(win_alloc->wa_map->wm_map,
- win_alloc->wa_pages,
- win_alloc->wa_base);
+
+ int status = 0;
+
+ if (win_alloc->wa_resource) {
+ status = release_resource(win_alloc->wa_resource);
+ if (!status)
+ kfree(win_alloc->wa_resource);
+ else
+ BUG();
+ }
}
/*
#include <asm/smp.h>
#include <asm/irq.h>
#include <asm/hw_irq.h>
+#include <asm/system.h>
#include <asm/sn/sgi.h>
#include <asm/sn/iograph.h>
#include <asm/sn/invent.h>
static int __init
linkstatd_init(void)
{
+ if (!ia64_platform_is("sn2"))
+ return -ENODEV;
+
spin_lock_init(&sn_linkstats_lock);
sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL);
sn_linkstats_reset(60000UL); /* default 60 second update interval */
- kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES);
+ kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
return 0;
}
rv = intr_connect_level(intr_cpu, SGI_II_ERROR, 0, NULL);
request_irq(SGI_II_ERROR, hubii_eint_handler, SA_SHIRQ, "SN_hub_error", (void *)hub_v);
- irq_desc(bit)->status |= SN2_IRQ_PER_HUB;
+ irq_descp(bit)->status |= SN2_IRQ_PER_HUB;
ASSERT_ALWAYS(rv >= 0);
hubio_eint.ii_iidsr_regval = 0;
hubio_eint.ii_iidsr_fld_s.i_enable = 1;
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/vmalloc.h>
#include <asm/current.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
if (pcibr_intr_list == NULL) {
pcibr_intr_list = kmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS, GFP_KERNEL);
+ if (pcibr_intr_list == NULL)
+ pcibr_intr_list = vmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n");
memset( (void *)pcibr_intr_list, 0, sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
}
#include <linux/acpi.h>
#include <linux/compiler.h>
#include <linux/sched.h>
+#include <linux/root_dev.h>
#include <asm/io.h>
#include <asm/sal.h>
extern void bte_init_node (nodepda_t *, cnodeid_t);
extern void bte_init_cpu (void);
extern void sn_timer_init(void);
+extern unsigned long last_time_offset;
extern void (*ia64_mark_idle)(int);
extern void snidle(int);
* Sets up an initial console to aid debugging. Intended primarily
* for bringup. See start_kernel() in init/main.c.
*/
-#if defined(CONFIG_IA64_EARLY_PRINTK) || defined(CONFIG_IA64_SGI_SN_SIM)
+#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
void __init
early_sn_setup(void)
printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
}
}
-#endif /* CONFIG_IA64_EARLY_PRINTK */
+#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */
#ifdef CONFIG_IA64_MCA
extern int platform_intr_list[];
master_node_bedrock_address);
}
+ /*
+ * we set the default root device to /dev/hda
+ * to make simulation easy
+ */
+ ROOT_DEV = Root_HDA1;
+
/*
* Create the PDAs and NODEPDAs for all the cpus.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
+#include <asm/system.h>
#include <asm/io.h>
#include <asm/sn/simulator.h>
nasid_t nasid;
char name[NODE_NAME_LEN];
+ if (!ia64_platform_is("sn2"))
+ return 0;
+
TRACE();
DPRINTK("running on cpu %d\n", smp_processor_id());
+++ /dev/null
-#ifndef _ASM_IA64_SN_ATE_UTILS_H
-#define _ASM_IA64_SN_ATE_UTILS_H
-
-/* $Id: ate_utils.h,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.
- */
-
-/*
- * struct map X[] .m_size .m_addr
- * --- ------------ -----------
- * [0] mapsize(X) unused
- * # X[] unused
- * [1] map lock * mapwant sv_t *
- * map access wait for free map space
- *
- * mapstart(X)-> [2] # units unit number
- * : : :
- * [ ] 0
- */
-
-#include <linux/types.h>
-
-#define ulong_t uint64_t
-
-struct map
-{
- unsigned long m_size; /* number of units available */
- unsigned long m_addr; /* address of first available unit */
-};
-
-#define mapstart(X) &X[2] /* start of map array */
-
-#define mapsize(X) X[0].m_size /* number of empty slots */
- /* remaining in map array */
-#define maplock(X) (((spinlock_t *) X[1].m_size))
-
-#define mapout(X) ((sv_t *) X[1].m_addr)
-
-
-extern ulong_t atealloc(struct map *, size_t);
-extern struct map *atemapalloc(ulong_t);
-extern void atefree(struct map *, size_t, ulong_t);
-extern void atemapfree(struct map *);
-
-#endif /* _ASM_IA64_SN_ATE_UTILS_H */
-
#include <asm/sn/addrs.h>
typedef long clkreg_t;
+
extern unsigned long sn_rtc_cycles_per_second;
+extern unsigned long sn_rtc_usec_per_cyc;
+extern unsigned long sn_rtc_per_itc;
+extern unsigned long sn_rtc_delta;
+
#include <asm/sn/addrs.h>
#include <asm/sn/sn2/addrs.h>
#include <asm/sn/sn2/shubio.h>
#include <asm/sn/sn2/shub_mmr.h>
+#define RTC_MASK SH_RTC_MASK
#define RTC_COUNTER_ADDR ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
#define RTC_COMPARE_A_ADDR ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
#define RTC_COMPARE_B_ADDR ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
#define RTC_INT_ENABLED_A_ADDR ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
#define RTC_INT_ENABLED_B_ADDR ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
+#define SN_RTC_PER_ITC_SHIFT 34
#define GET_RTC_COUNTER() (*RTC_COUNTER_ADDR)
#define rtc_time() GET_RTC_COUNTER()
/*
- * The following APIs are externalized to the kernel to allocate/free fetchop variables.
- * fetchop_kalloc_one - Allocate/initialize 1 fetchop variable on the specified cnode.
- * fetchop_kfree_one - Free a previously allocated fetchop variable
+ * The following APIs are externalized to the kernel to allocate/free pages of
+ * fetchop variables.
+ * fetchop_kalloc_page - Allocate/initialize 1 fetchop page on the
+ * specified cnode.
+ * fetchop_kfree_page - Free a previously allocated fetchop page
*/
-unsigned long fetchop_kalloc_one(int nid);
-void fetchop_kfree_one(unsigned long maddr);
+unsigned long fetchop_kalloc_page(int nid);
+void fetchop_kfree_page(unsigned long maddr);
#endif /* __KERNEL__ */
#include <linux/config.h>
-#include <asm/sn/systeminfo.h>
#include <asm/sn/klconfig.h>
#include <asm/sn/ksys/elsc.h>
extern module_t *module_lookup(moduleid_t id);
-extern int get_kmod_info(cmoduleid_t cmod,
- module_info_t *mod_info);
extern int get_kmod_sys_snum(cmoduleid_t cmod,
char *snum);
*/
#define PV854697 (~0) /* PIC: write 64bit regs as 64bits. permanent */
#define PV854827 (~0) /* PIC: fake widget 0xf presence bit. permanent */
-#define PV855271 (~0) /* PIC: use virt chan iff 64-bit device. permanent */
+#define PV855271 (1 << 1) /* PIC: PIC: use virt chan iff 64-bit device. */
#define PV855272 (1 << 1) /* PIC: runaway interrupt WAR */
#define PV856155 (1 << 1) /* PIC: arbitration WAR */
#define PV856864 (1 << 1) /* PIC: lower timeout to free TNUMs quicker */
iopaddr_t bs_dir_xbase; /* xtalk address for 32-bit PCI direct map */
xwidgetnum_t bs_dir_xport; /* xtalk port for 32-bit PCI direct map */
- struct map *bs_int_ate_map; /* rmalloc map for internal ATEs */
- struct map *bs_ext_ate_map; /* rmalloc map for external ATEs */
+ struct resource bs_int_ate_resource;/* root resource for internal ATEs */
+ struct resource bs_ext_ate_resource;/* root resource for external ATEs */
+ void *bs_allocated_ate_res;/* resource struct allocated */
short bs_int_ate_size; /* number of internal ates */
short bs_bridge_type; /* see defines above */
short bs_bridge_mode; /* see defines above */
struct pciio_win_map_s bs_swin_map; /* Small window addr space */
struct pciio_win_map_s bs_mem_win_map; /* Memory addr space */
+ struct resource bs_io_win_root_resource; /* I/O addr space */
+ struct resource bs_swin_root_resource; /* Small window addr space */
+ struct resource bs_mem_win_root_resource; /* Memory addr space */
+
int bs_bus_addr_status; /* Bus space status */
#define PCIBR_BUS_ADDR_MEM_FREED 1 /* Reserved PROM mem addr freed */
*/
#include <linux/config.h>
+#include <linux/ioport.h>
#include <asm/sn/ioerror.h>
#include <asm/sn/driver.h>
#include <asm/sn/hcl.h>
/* allocate window from mapping resource */
extern iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map, /* win map */
+pciio_device_win_alloc(struct resource * res,
pciio_win_alloc_t win_alloc, /* opaque allocation cookie */
size_t start, /* start unit, or 0 */
size_t size, /* size of allocation */
* Opaque structure used to keep track of window allocation information.
*/
struct pciio_win_alloc_s {
- pciio_win_map_t wa_map; /* window map allocation is from */
+ struct resource *wa_resource; /* window map allocation resource */
unsigned long wa_base; /* allocation starting page number */
size_t wa_pages; /* number of pages in allocation */
};
static inline unsigned int
__sn_inb (unsigned long port)
{
- volatile unsigned char *addr = sn_io_addr(port);
- unsigned char ret;
-
- ret = *addr;
- __sn_mf_a();
- sn_dma_flush((unsigned long)addr);
+ volatile unsigned char *addr;
+ unsigned char ret = -1;
+
+ if ((addr = sn_io_addr(port))) {
+ ret = *addr;
+ __sn_mf_a();
+ sn_dma_flush((unsigned long)addr);
+ }
return ret;
}
static inline unsigned int
__sn_inw (unsigned long port)
{
- volatile unsigned short *addr = sn_io_addr(port);
- unsigned short ret;
+ volatile unsigned short *addr;
+ unsigned short ret = -1;
- ret = *addr;
- __sn_mf_a();
- sn_dma_flush((unsigned long)addr);
+ if ((addr = sn_io_addr(port))) {
+ ret = *addr;
+ __sn_mf_a();
+ sn_dma_flush((unsigned long)addr);
+ }
return ret;
}
static inline unsigned int
__sn_inl (unsigned long port)
{
- volatile unsigned int *addr = sn_io_addr(port);
- unsigned int ret;
+ volatile unsigned int *addr;
+ unsigned int ret = -1;
- ret = *addr;
- __sn_mf_a();
- sn_dma_flush((unsigned long)addr);
+ if ((addr = sn_io_addr(port))) {
+ ret = *addr;
+ __sn_mf_a();
+ sn_dma_flush((unsigned long)addr);
+ }
return ret;
}
static inline void
__sn_outb (unsigned char val, unsigned long port)
{
- volatile unsigned char *addr = sn_io_addr(port);
+ volatile unsigned char *addr;
- *addr = val;
- sn_mmiob();
+ if ((addr = sn_io_addr(port))) {
+ *addr = val;
+ sn_mmiob();
+ }
}
static inline void
__sn_outw (unsigned short val, unsigned long port)
{
- volatile unsigned short *addr = sn_io_addr(port);
+ volatile unsigned short *addr;
- *addr = val;
- sn_mmiob();
+ if ((addr = sn_io_addr(port))) {
+ *addr = val;
+ sn_mmiob();
+ }
}
static inline void
__sn_outl (unsigned int val, unsigned long port)
{
- volatile unsigned int *addr = sn_io_addr(port);
+ volatile unsigned int *addr;
- *addr = val;
- sn_mmiob();
+ if ((addr = sn_io_addr(port))) {
+ *addr = val;
+ sn_mmiob();
+ }
}
/*
#define SN_SAL_LOG_CE 0x02000006
#define SN_SAL_REGISTER_CE 0x02000007
#define SN_SAL_GET_PARTITION_ADDR 0x02000009
+#define SN_SAL_XP_ADDR_REGION 0x0200000f
+#define SN_SAL_NO_FAULT_ZONE_VIRTUAL 0x02000010
+#define SN_SAL_NO_FAULT_ZONE_PHYSICAL 0x02000011
#define SN_SAL_PRINT_ERROR 0x02000012
#define SN_SAL_CONSOLE_PUTC 0x02000021
#define SN_SAL_CONSOLE_GETC 0x02000022
#define SN_SAL_SYSTEM_POWER_DOWN 0x0200003b
#define SN_SAL_GET_MASTER_BASEIO_NASID 0x0200003c
#define SN_SAL_COHERENCE 0x0200003d
+#define SN_SAL_MEMPROTECT 0x0200003e
#define SN_SAL_SYSCTL_FRU_CAPTURE 0x0200003f
}
}
+/*
+ * Register or unregister a physical address range being referenced across
+ * a partition boundary for which certain SAL errors should be scanned for,
+ * cleaned up and ignored. This is of value for kernel partitioning code only.
+ * Values for the operation argument:
+ * 1 = register this address range with SAL
+ * 0 = unregister this address range with SAL
+ *
+ * SAL maintains a reference count on an address range in case it is registered
+ * multiple times.
+ *
+ * On success, returns the reference count of the address range after the SAL
+ * call has performed the current registration/unregistration. Returns a
+ * negative value if an error occurred.
+ */
+static inline int
+sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
+{
+ struct ia64_sal_retval ret_stuff;
+ SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation,
+ 0, 0, 0, 0);
+ return ret_stuff.status;
+}
+
+/*
+ * Register or unregister an instruction range for which SAL errors should
+ * be ignored. If an error occurs while in the registered range, SAL jumps
+ * to return_addr after ignoring the error. Values for the operation argument:
+ * 1 = register this instruction range with SAL
+ * 0 = unregister this instruction range with SAL
+ *
+ * Returns 0 on success, or a negative value if an error occurred.
+ */
+static inline int
+sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
+ int virtual, int operation)
+{
+ struct ia64_sal_retval ret_stuff;
+ u64 call;
+ if (virtual) {
+ call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
+ } else {
+ call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
+ }
+ SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1,
+ 0, 0, 0);
+ return ret_stuff.status;
+}
+
/*
* Change or query the coherence domain for this partition. Each cpu-based
* nasid is represented by a bit in an array of 64-bit words:
* 0 = not in this partition's coherency domain
* 1 = in this partition's coherency domain
- * It is not possible for the local system's nasids to be removed from
- * the coherency domain.
*
+ * It is not possible for the local system's nasids to be removed from
+ * the coherency domain. Purpose of the domain arguments:
* new_domain = set the coherence domain to the given nasids
* old_domain = return the current coherence domain
+ *
+ * Returns 0 on success, or a negative value if an error occurred.
*/
static inline int
sn_change_coherence(u64 *new_domain, u64 *old_domain)
return ret_stuff.status;
}
+/*
+ * Change memory access protections for a physical address range.
+ * nasid_array is not used on Altix, but may be in future architectures.
+ * Available memory protection access classes are defined after the function.
+ */
+static inline int
+sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
+{
+ struct ia64_sal_retval ret_stuff;
+ SAL_CALL(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array,
+ perms, 0, 0, 0);
+ return ret_stuff.status;
+}
+#define SN_MEMPROT_ACCESS_CLASS_0 0x14a080
+#define SN_MEMPROT_ACCESS_CLASS_1 0x2520c2
+#define SN_MEMPROT_ACCESS_CLASS_2 0x14a1ca
+#define SN_MEMPROT_ACCESS_CLASS_3 0x14a290
+#define SN_MEMPROT_ACCESS_CLASS_6 0x084080
+#define SN_MEMPROT_ACCESS_CLASS_7 0x021080
+
/*
* Turns off system power.
*/
+++ /dev/null
-/* $Id$
- *
- * 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.
- */
-#ifndef _ASM_IA64_SN_SYSTEMINFO_H
-#define _ASM_IA64_SN_SYSTEMINFO_H
-
-#include <linux/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_SERIAL_SIZE 16
-
-typedef struct module_info_s {
- uint64_t serial_num;
- int mod_num;
- char serial_str[MAX_SERIAL_SIZE];
-} module_info_t;
-
-
-
-/*
- * Commands to sysinfo()
- */
-
-#define SI_SYSNAME 1 /* return name of operating system */
-#define SI_HOSTNAME 2 /* return name of node */
-#define SI_RELEASE 3 /* return release of operating system */
-#define SI_VERSION 4 /* return version field of utsname */
-#define SI_MACHINE 5 /* return kind of machine */
-#define SI_ARCHITECTURE 6 /* return instruction set arch */
-#define SI_HW_SERIAL 7 /* return hardware serial number */
-#define SI_HW_PROVIDER 8 /* return hardware manufacturer */
-#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
-#define SI_INITTAB_NAME 10 /* return name of inittab file used */
-
-#define _MIPS_SI_VENDOR 100 /* return system provider */
-#define _MIPS_SI_OS_PROVIDER 101 /* return OS manufacturer */
-#define _MIPS_SI_OS_NAME 102 /* return OS name */
-#define _MIPS_SI_HW_NAME 103 /* return system name */
-#define _MIPS_SI_NUM_PROCESSORS 104 /* return number of processors */
-#define _MIPS_SI_HOSTID 105 /* return hostid */
-#define _MIPS_SI_OSREL_MAJ 106 /* return OS major release number */
-#define _MIPS_SI_OSREL_MIN 107 /* return OS minor release number */
-#define _MIPS_SI_OSREL_PATCH 108 /* return OS release number */
-#define _MIPS_SI_PROCESSORS 109 /* return CPU revison id */
-#define _MIPS_SI_AVAIL_PROCESSORS 110 /* return number of available processors */
-#define _MIPS_SI_SERIAL 111
-/*
- * These commands are unpublished interfaces to sysinfo().
- */
-#define SI_SET_HOSTNAME 258 /* set name of node */
- /* -unpublished option */
-#define SI_SET_SRPC_DOMAIN 265 /* set secure RPC domain */
- /* -unpublished option */
-
-#if !defined(__KERNEL__)
-int sysinfo(int, char *, long);
-int get_num_modules(void);
-int get_module_info(int, module_info_t *, size_t);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ASM_IA64_SN_SYSTEMINFO_H */