diff -urN linux-2.4.0-test12/Documentation/Configure.help linux-2.4.0-test12-lia/Documentation/Configure.help --- linux-2.4.0-test12/Documentation/Configure.help Wed Dec 13 17:29:08 2000 +++ linux-2.4.0-test12-lia/Documentation/Configure.help Thu Dec 14 15:08:15 2000 @@ -11433,6 +11433,12 @@ Say Y here if you would like to be able to read the hard disk partition table format used by SGI machines. +Intel EFI GUID partition support +CONFIG_EFI_PARTITION + Say Y here if you would like to use hard disks under Linux which + were partitioned using EFI GPT. Presently only useful on the + IA-64 platform. + ADFS file system support (EXPERIMENTAL) CONFIG_ADFS_FS The Acorn Disc Filing System is the standard file system of the @@ -16924,12 +16930,6 @@ Select this option to build a kernel for an Itanium prototype system with an A-step CPU. You have an A-step CPU if the "revision" field in /proc/cpuinfo is 0. - -Enable Itanium A1-step specific code -CONFIG_ITANIUM_A1_SPECIFIC - Select this option to build a kernel for an Itanium prototype system - with an A1-step CPU. If you don't know whether you have an A1-step CPU, - you probably don't and you can answer "no" here. Enable Itanium B-step specific code CONFIG_ITANIUM_BSTEP_SPECIFIC diff -urN linux-2.4.0-test12/Documentation/IO-mapping.txt linux-2.4.0-test12-lia/Documentation/IO-mapping.txt --- linux-2.4.0-test12/Documentation/IO-mapping.txt Fri Oct 27 10:58:02 2000 +++ linux-2.4.0-test12-lia/Documentation/IO-mapping.txt Thu Dec 14 14:06:14 2000 @@ -1,3 +1,9 @@ +[ NOTE: The virt_to_bus() and bus_to_virt() functions have been + superseded by the functionality provided by the PCI DMA + interface (see Documentation/DMA-mapping.txt). They continue + to be documented below for historical purposes, but new code + must not use them. --davidm 00/12/12 ] + [ This is a mail message in response to a query on IO mapping, thus the strange format for a "document" ] diff -urN linux-2.4.0-test12/Makefile linux-2.4.0-test12-lia/Makefile --- linux-2.4.0-test12/Makefile Wed Dec 13 17:29:10 2000 +++ linux-2.4.0-test12-lia/Makefile Wed Dec 13 17:31:35 2000 @@ -87,7 +87,7 @@ CPPFLAGS := -D__KERNEL__ -I$(HPATH) -CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -g -O2 -fomit-frame-pointer -fno-strict-aliasing AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) # @@ -227,14 +227,14 @@ include arch/$(ARCH)/Makefile -export CPPFLAGS CFLAGS AFLAGS +export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS .S.s: - $(CPP) $(AFLAGS) -traditional -o $*.s $< + $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $< .S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -c -o $*.o $< Version: dummy @rm -f include/linux/compile.h diff -urN linux-2.4.0-test12/arch/ia64/Makefile linux-2.4.0-test12-lia/arch/ia64/Makefile --- linux-2.4.0-test12/arch/ia64/Makefile Mon Oct 9 17:54:53 2000 +++ linux-2.4.0-test12-lia/arch/ia64/Makefile Wed Dec 6 22:09:11 2000 @@ -19,22 +19,28 @@ EXTRA = CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \ - -funwind-tables + -funwind-tables -falign-functions=32 +# -frename-registers CFLAGS_KERNEL := -mconstant-gp ifeq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y) CFLAGS += -ma-step endif +ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y) + CFLAGS += -mb-step +endif ifdef CONFIG_IA64_GENERIC CORE_FILES := arch/$(ARCH)/hp/hp.a \ arch/$(ARCH)/sn/sn.a \ arch/$(ARCH)/dig/dig.a \ + arch/$(ARCH)/sn/io/sgiio.o \ $(CORE_FILES) SUBDIRS := arch/$(ARCH)/hp \ arch/$(ARCH)/sn/sn1 \ arch/$(ARCH)/sn \ arch/$(ARCH)/dig \ + arch/$(ARCH)/sn/io \ $(SUBDIRS) else # !GENERIC @@ -47,10 +53,7 @@ endif ifdef CONFIG_IA64_SGI_SN1 -CFLAGS := $(CFLAGS) -DSN -I. -DBRINGUP -DDIRECT_L1_CONSOLE \ - -DNUMA_BASE -DSIMULATED_KLGRAPH -DNUMA_MIGR_CONTROL \ - -DLITTLE_ENDIAN -DREAL_HARDWARE -DLANGUAGE_C=1 \ - -D_LANGUAGE_C=1 +CFLAGS += -DBRINGUP SUBDIRS := arch/$(ARCH)/sn/sn1 \ arch/$(ARCH)/sn \ arch/$(ARCH)/sn/io \ @@ -96,7 +99,7 @@ arch/$(ARCH)/vmlinux.lds: arch/$(ARCH)/vmlinux.lds.S FORCE $(CPP) -D__ASSEMBLY__ -C -P -I$(HPATH) -I$(HPATH)/asm-$(ARCH) \ - arch/$(ARCH)/vmlinux.lds.S > $@ + -traditional arch/$(ARCH)/vmlinux.lds.S > $@ FORCE: ; diff -urN linux-2.4.0-test12/arch/ia64/boot/Makefile linux-2.4.0-test12-lia/arch/ia64/boot/Makefile --- linux-2.4.0-test12/arch/ia64/boot/Makefile Thu Jun 22 07:09:44 2000 +++ linux-2.4.0-test12-lia/arch/ia64/boot/Makefile Thu Dec 14 14:07:03 2000 @@ -16,13 +16,12 @@ $(CC) $(AFLAGS) -traditional -c -o $*.o $< OBJECTS = bootloader.o -TARGETS = +targets-y = -ifdef CONFIG_IA64_HP_SIM - TARGETS += bootloader -endif +targets-$(CONFIG_IA64_HP_SIM) += bootloader +targets-$(CONFIG_IA64_GENERIC) += bootloader -all: $(TARGETS) +all: $(targets-y) bootloader: $(OBJECTS) $(LD) $(LINKFLAGS) $(OBJECTS) $(TOPDIR)/lib/lib.a $(TOPDIR)/arch/$(ARCH)/lib/lib.a \ diff -urN linux-2.4.0-test12/arch/ia64/config.in linux-2.4.0-test12-lia/arch/ia64/config.in --- linux-2.4.0-test12/arch/ia64/config.in Wed Dec 6 18:32:29 2000 +++ linux-2.4.0-test12-lia/arch/ia64/config.in Thu Dec 14 19:51:13 2000 @@ -18,7 +18,6 @@ comment 'General setup' define_bool CONFIG_IA64 y -define_bool CONFIG_SWIOTLB y # for now... define_bool CONFIG_ISA n define_bool CONFIG_EISA n @@ -41,20 +40,22 @@ define_bool CONFIG_ITANIUM y define_bool CONFIG_IA64_BRL_EMU y bool ' Enable Itanium A-step specific code' CONFIG_ITANIUM_ASTEP_SPECIFIC - if [ "$CONFIG_ITANIUM_ASTEP_SPECIFIC" = "y" ]; then - bool ' Enable Itanium A1-step specific code' CONFIG_ITANIUM_A1_SPECIFIC - fi bool ' Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then bool ' Enable Itanium B0-step specific code' CONFIG_ITANIUM_B0_SPECIFIC + bool ' Enable Itanium B1-step specific code' CONFIG_ITANIUM_B1_SPECIFIC + bool ' Enable Itanium B2-step specific code' CONFIG_ITANIUM_B2_SPECIFIC + fi + bool ' Enable Itanium C-step specific code' CONFIG_ITANIUM_CSTEP_SPECIFIC + if [ "$CONFIG_ITANIUM_CSTEP_SPECIFIC" = "y" ]; then + bool ' Enable Itanium C0-step specific code' CONFIG_ITANIUM_C0_SPECIFIC fi bool ' Force interrupt redirection' CONFIG_IA64_HAVE_IRQREDIR bool ' Enable use of global TLB purge instruction (ptc.g)' CONFIG_ITANIUM_PTCG bool ' Enable SoftSDV hacks' CONFIG_IA64_SOFTSDV_HACKS bool ' Enable AzusA hacks' CONFIG_IA64_AZUSA_HACKS bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA - bool ' Force socket buffers below 4GB?' CONFIG_SKB_BELOW_4GB - + bool ' Enable ACPI 2.0 with errata 1.3' CONFIG_ACPI20 bool ' ACPI kernel configuration manager (EXPERIMENTAL)' CONFIG_ACPI_KERNEL_CONFIG if [ "$CONFIG_ACPI_KERNEL_CONFIG" = "y" ]; then define_bool CONFIG_PM y @@ -70,13 +71,14 @@ bool ' Enable Itanium B0-step specific code' CONFIG_ITANIUM_B0_SPECIFIC fi bool ' Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN1_SIM n - bool ' Enable SGI hack for version 1.0 syngery bugs' CONFIG_IA64_SGI_SYNERGY_1_0_HACKS n define_bool CONFIG_DEVFS_DEBUG y define_bool CONFIG_DEVFS_FS y define_bool CONFIG_IA64_BRL_EMU y define_bool CONFIG_IA64_MCA y - define_bool CONFIG_IA64_SGI_IO y define_bool CONFIG_ITANIUM y + define_bool CONFIG_SGI_IOC3_ETH y + bool ' Enable DISCONTIGMEM support' CONFIG_DISCONTIGMEM y + bool ' Enable NUMA support' CONFIG_NUMA y fi define_bool CONFIG_KCORE_ELF y # On IA-64, we always want an ELF /proc/kcore. diff -urN linux-2.4.0-test12/arch/ia64/dig/Makefile linux-2.4.0-test12-lia/arch/ia64/dig/Makefile --- linux-2.4.0-test12/arch/ia64/dig/Makefile Fri Apr 21 15:21:23 2000 +++ linux-2.4.0-test12-lia/arch/ia64/dig/Makefile Tue Oct 31 10:13:32 2000 @@ -13,7 +13,7 @@ all: dig.a O_TARGET = dig.a -O_OBJS = iosapic.o setup.o +O_OBJS = setup.o ifdef CONFIG_IA64_GENERIC O_OBJS += machvec.o diff -urN linux-2.4.0-test12/arch/ia64/dig/iosapic.c linux-2.4.0-test12-lia/arch/ia64/dig/iosapic.c --- linux-2.4.0-test12/arch/ia64/dig/iosapic.c Mon Oct 9 17:54:53 2000 +++ linux-2.4.0-test12-lia/arch/ia64/dig/iosapic.c Wed Dec 31 16:00:00 1969 @@ -1,409 +0,0 @@ -/* - * Streamlined APIC support. - * - * Copyright (C) 1999 Intel Corp. - * Copyright (C) 1999 Asit Mallick - * Copyright (C) 1999-2000 Hewlett-Packard Co. - * Copyright (C) 1999-2000 David Mosberger-Tang - * Copyright (C) 1999 VA Linux Systems - * Copyright (C) 1999,2000 Walt Drummond - * - * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code. - * In particular, we now have separate handlers for edge - * and level triggered interrupts. - */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ACPI_KERNEL_CONFIG -# include -#endif - -#undef DEBUG_IRQ_ROUTING - -static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; - -struct iosapic_vector iosapic_vector[NR_IRQS] = { - [0 ... NR_IRQS-1] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } -}; - -/* - * find the IRQ in the IOSAPIC map for the PCI device on bus/slot/pin - */ -int -iosapic_get_PCI_irq_vector (int bus, int slot, int pci_pin) -{ - int i; - - for (i = 0; i < NR_IRQS; i++) { - if ((iosapic_bustype(i) == BUS_PCI) && - (iosapic_bus(i) == bus) && - (iosapic_busdata(i) == ((slot << 16) | pci_pin))) { - return i; - } - } - return -1; -} - -static void -set_rte (unsigned long iosapic_addr, int entry, int pol, int trigger, int delivery, - long dest, int vector) -{ - u32 low32; - u32 high32; - - low32 = ((pol << IO_SAPIC_POLARITY_SHIFT) | - (trigger << IO_SAPIC_TRIGGER_SHIFT) | - (delivery << IO_SAPIC_DELIVERY_SHIFT) | - vector); - -#ifdef CONFIG_IA64_AZUSA_HACKS - /* set Flush Disable bit */ - if (iosapic_addr != 0xc0000000fec00000) - low32 |= (1 << 17); -#endif - - /* dest contains both id and eid */ - high32 = (dest << IO_SAPIC_DEST_SHIFT); - - writel(IO_SAPIC_RTE_HIGH(entry), iosapic_addr + IO_SAPIC_REG_SELECT); - writel(high32, iosapic_addr + IO_SAPIC_WINDOW); - writel(IO_SAPIC_RTE_LOW(entry), iosapic_addr + IO_SAPIC_REG_SELECT); - writel(low32, iosapic_addr + IO_SAPIC_WINDOW); -} - -static void -nop (unsigned int irq) -{ - /* do nothing... */ -} - -static void -mask_irq (unsigned int irq) -{ - unsigned long flags, iosapic_addr = iosapic_addr(irq); - u32 low32; - - spin_lock_irqsave(&iosapic_lock, flags); - { - writel(IO_SAPIC_RTE_LOW(iosapic_pin(irq)), iosapic_addr + IO_SAPIC_REG_SELECT); - low32 = readl(iosapic_addr + IO_SAPIC_WINDOW); - - low32 |= (1 << IO_SAPIC_MASK_SHIFT); /* Zero only the mask bit */ - writel(low32, iosapic_addr + IO_SAPIC_WINDOW); - } - spin_unlock_irqrestore(&iosapic_lock, flags); -} - -static void -unmask_irq (unsigned int irq) -{ - unsigned long flags, iosapic_addr = iosapic_addr(irq); - u32 low32; - - spin_lock_irqsave(&iosapic_lock, flags); - { - writel(IO_SAPIC_RTE_LOW(iosapic_pin(irq)), iosapic_addr + IO_SAPIC_REG_SELECT); - low32 = readl(iosapic_addr + IO_SAPIC_WINDOW); - - low32 &= ~(1 << IO_SAPIC_MASK_SHIFT); /* Zero only the mask bit */ - writel(low32, iosapic_addr + IO_SAPIC_WINDOW); - } - spin_unlock_irqrestore(&iosapic_lock, flags); -} - - -static void -iosapic_set_affinity (unsigned int irq, unsigned long mask) -{ - printk("iosapic_set_affinity: not implemented yet\n"); -} - -/* - * Handlers for level-triggered interrupts. - */ - -static unsigned int -iosapic_startup_level_irq (unsigned int irq) -{ - unmask_irq(irq); - return 0; -} - -static void -iosapic_end_level_irq (unsigned int irq) -{ - writel(irq, iosapic_addr(irq) + IO_SAPIC_EOI); -} - -#define iosapic_shutdown_level_irq mask_irq -#define iosapic_enable_level_irq unmask_irq -#define iosapic_disable_level_irq mask_irq -#define iosapic_ack_level_irq nop - -struct hw_interrupt_type irq_type_iosapic_level = { - typename: "IO-SAPIC-level", - startup: iosapic_startup_level_irq, - shutdown: iosapic_shutdown_level_irq, - enable: iosapic_enable_level_irq, - disable: iosapic_disable_level_irq, - ack: iosapic_ack_level_irq, - end: iosapic_end_level_irq, - set_affinity: iosapic_set_affinity -}; - -/* - * Handlers for edge-triggered interrupts. - */ - -static unsigned int -iosapic_startup_edge_irq (unsigned int irq) -{ - unmask_irq(irq); - /* - * IOSAPIC simply drops interrupts pended while the - * corresponding pin was masked, so we can't know if an - * interrupt is pending already. Let's hope not... - */ - return 0; -} - -static void -iosapic_ack_edge_irq (unsigned int irq) -{ - /* - * Once we have recorded IRQ_PENDING already, we can mask the - * interrupt for real. This prevents IRQ storms from unhandled - * devices. - */ - if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED)) - mask_irq(irq); -} - -#define iosapic_enable_edge_irq unmask_irq -#define iosapic_disable_edge_irq nop -#define iosapic_end_edge_irq nop - -struct hw_interrupt_type irq_type_iosapic_edge = { - typename: "IO-SAPIC-edge", - startup: iosapic_startup_edge_irq, - shutdown: iosapic_disable_edge_irq, - enable: iosapic_enable_edge_irq, - disable: iosapic_disable_edge_irq, - ack: iosapic_ack_edge_irq, - end: iosapic_end_edge_irq, - set_affinity: iosapic_set_affinity -}; - -unsigned int -iosapic_version (unsigned long base_addr) -{ - /* - * IOSAPIC Version Register return 32 bit structure like: - * { - * unsigned int version : 8; - * unsigned int reserved1 : 8; - * unsigned int pins : 8; - * unsigned int reserved2 : 8; - * } - */ - writel(IO_SAPIC_VERSION, base_addr + IO_SAPIC_REG_SELECT); - return readl(IO_SAPIC_WINDOW + base_addr); -} - -void -iosapic_init (unsigned long address, int irqbase) -{ - struct hw_interrupt_type *irq_type; - struct pci_vector_struct *vectors; - int i, irq, num_pci_vectors; - - if (irqbase == 0) - /* - * Map the legacy ISA devices into the IOSAPIC data. - * Some of these may get reprogrammed later on with - * data from the ACPI Interrupt Source Override table. - */ - for (i = 0; i < 16; i++) { - irq = isa_irq_to_vector(i); - iosapic_pin(irq) = i; - iosapic_bus(irq) = BUS_ISA; - iosapic_busdata(irq) = 0; - iosapic_dmode(irq) = IO_SAPIC_LOWEST_PRIORITY; - iosapic_trigger(irq) = IO_SAPIC_EDGE; - iosapic_polarity(irq) = IO_SAPIC_POL_HIGH; -#ifdef DEBUG_IRQ_ROUTING - printk("ISA: IRQ %02x -> Vector %02x IOSAPIC Pin %d\n", - i, irq, iosapic_pin(irq)); -#endif - } - -#ifndef CONFIG_IA64_SOFTSDV_HACKS - /* - * Map the PCI Interrupt data into the ACPI IOSAPIC data using - * the info that the bootstrap loader passed to us. - */ -# ifdef CONFIG_ACPI_KERNEL_CONFIG - acpi_cf_get_pci_vectors(&vectors, &num_pci_vectors); -# else - ia64_boot_param.pci_vectors = (__u64) __va(ia64_boot_param.pci_vectors); - vectors = (struct pci_vector_struct *) ia64_boot_param.pci_vectors; - num_pci_vectors = ia64_boot_param.num_pci_vectors; -# endif - for (i = 0; i < num_pci_vectors; i++) { - irq = vectors[i].irq; - if (irq < 16) - irq = isa_irq_to_vector(irq); - if (iosapic_baseirq(irq) != irqbase) - continue; - - iosapic_bustype(irq) = BUS_PCI; - iosapic_pin(irq) = irq - iosapic_baseirq(irq); - iosapic_bus(irq) = vectors[i].bus; - /* - * Map the PCI slot and pin data into iosapic_busdata() - */ - iosapic_busdata(irq) = (vectors[i].pci_id & 0xffff0000) | vectors[i].pin; - - /* Default settings for PCI */ - iosapic_dmode(irq) = IO_SAPIC_LOWEST_PRIORITY; - iosapic_trigger(irq) = IO_SAPIC_LEVEL; - iosapic_polarity(irq) = IO_SAPIC_POL_LOW; - -# ifdef DEBUG_IRQ_ROUTING - printk("PCI: BUS %d Slot %x Pin %x IRQ %02x --> Vector %02x IOSAPIC Pin %d\n", - vectors[i].bus, vectors[i].pci_id>>16, vectors[i].pin, vectors[i].irq, - irq, iosapic_pin(irq)); -# endif - } -#endif /* CONFIG_IA64_SOFTSDV_HACKS */ - - for (i = 0; i < NR_IRQS; ++i) { - if (iosapic_baseirq(i) != irqbase) - continue; - - if (iosapic_pin(i) != -1) { - if (iosapic_trigger(i) == IO_SAPIC_LEVEL) - irq_type = &irq_type_iosapic_level; - else - irq_type = &irq_type_iosapic_edge; - if (irq_desc[i].handler != &no_irq_type) - printk("dig_irq_init: warning: changing vector %d from %s to %s\n", - i, irq_desc[i].handler->typename, - irq_type->typename); - irq_desc[i].handler = irq_type; - - /* program the IOSAPIC routing table: */ - set_rte(iosapic_addr(i), iosapic_pin(i), iosapic_polarity(i), - iosapic_trigger(i), iosapic_dmode(i), - (ia64_get_lid() >> 16) & 0xffff, i); - } - } -} - -void -dig_irq_init (void) -{ - /* - * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support - * enabled. - */ - outb(0xff, 0xA1); - outb(0xff, 0x21); -} - -void -dig_pci_fixup (void) -{ - struct pci_dev *dev; - int irq; - unsigned char pin; - - pci_for_each_dev(dev) { - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - if (pin) { - pin--; /* interrupt pins are numbered starting from 1 */ - irq = iosapic_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), - pin); - if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ - struct pci_dev * bridge = dev->bus->self; - - /* allow for multiple bridges on an adapter */ - do { - /* do the bridge swizzle... */ - pin = (pin + PCI_SLOT(dev->devfn)) % 4; - irq = iosapic_get_PCI_irq_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), pin); - } while (irq < 0 && (bridge = bridge->bus->self)); - if (irq >= 0) - printk(KERN_WARNING - "PCI: using PPB(B%d,I%d,P%d) to get irq %02x\n", - bridge->bus->number, PCI_SLOT(bridge->devfn), - pin, irq); - else - printk(KERN_WARNING - "PCI: Couldn't map irq for B%d,I%d,P%d\n", - bridge->bus->number, PCI_SLOT(bridge->devfn), - pin); - } - if (irq >= 0) { - printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %02x\n", - dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); - dev->irq = irq; - } - } - /* - * Nothing to fixup - * Fix out-of-range IRQ numbers - */ - if (dev->irq >= NR_IRQS) - dev->irq = 15; /* Spurious interrupts */ - } -} - -/* - * Register an IOSAPIC discovered via ACPI. - */ -void __init -dig_register_iosapic (acpi_entry_iosapic_t *iosapic) -{ - unsigned int ver, v; - int l, max_pin; - - ver = iosapic_version((unsigned long) ioremap(iosapic->address, 0)); - max_pin = (ver >> 16) & 0xff; - - printk("IOSAPIC Version %x.%x: address 0x%lx IRQs 0x%x - 0x%x\n", - (ver & 0xf0) >> 4, (ver & 0x0f), iosapic->address, - iosapic->irq_base, iosapic->irq_base + max_pin); - - for (l = 0; l <= max_pin; l++) { - v = iosapic->irq_base + l; - if (v < 16) - v = isa_irq_to_vector(v); - if (v > IA64_MAX_VECTORED_IRQ) { - printk(" !!! bad IOSAPIC interrupt vector: %u\n", v); - continue; - } - /* XXX Check for IOSAPIC collisions */ - iosapic_addr(v) = (unsigned long) ioremap(iosapic->address, 0); - iosapic_baseirq(v) = iosapic->irq_base; - } - iosapic_init(iosapic->address, iosapic->irq_base); -} diff -urN linux-2.4.0-test12/arch/ia64/dig/setup.c linux-2.4.0-test12-lia/arch/ia64/dig/setup.c --- linux-2.4.0-test12/arch/ia64/dig/setup.c Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/arch/ia64/dig/setup.c Mon Oct 30 22:28:55 2000 @@ -84,3 +84,14 @@ screen_info.orig_video_isVGA = 1; /* XXX fake */ screen_info.orig_video_ega_bx = 3; /* XXX fake */ } + +void +dig_irq_init (void) +{ + /* + * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support + * enabled. + */ + outb(0xff, 0xA1); + outb(0xff, 0x21); +} diff -urN linux-2.4.0-test12/arch/ia64/hp/hpsim_setup.c linux-2.4.0-test12-lia/arch/ia64/hp/hpsim_setup.c --- linux-2.4.0-test12/arch/ia64/hp/hpsim_setup.c Fri Jul 14 16:08:11 2000 +++ linux-2.4.0-test12-lia/arch/ia64/hp/hpsim_setup.c Wed Dec 6 22:10:09 2000 @@ -63,12 +63,6 @@ } void __init -hpsim_pci_fixup (void) -{ -} - - -void __init hpsim_setup (char **cmdline_p) { ROOT_DEV = to_kdev_t(0x0801); /* default to first SCSI drive */ diff -urN linux-2.4.0-test12/arch/ia64/ia32/binfmt_elf32.c linux-2.4.0-test12-lia/arch/ia64/ia32/binfmt_elf32.c --- linux-2.4.0-test12/arch/ia64/ia32/binfmt_elf32.c Mon Oct 9 17:54:53 2000 +++ linux-2.4.0-test12-lia/arch/ia64/ia32/binfmt_elf32.c Mon Oct 30 22:29:21 2000 @@ -9,6 +9,7 @@ #include +#include #include #include @@ -31,6 +32,9 @@ # define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE #endif +#undef CLOCKS_PER_SEC +#define CLOCKS_PER_SEC IA32_CLOCKS_PER_SEC + extern void ia64_elf32_init(struct pt_regs *regs); extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address); @@ -239,6 +243,12 @@ if (eppnt->p_memsz >= (1UL<<32) || addr > (1UL<<32) - eppnt->p_memsz) return -EINVAL; + /* + * Make sure the elf interpreter doesn't get loaded at location 0 + * so that NULL pointers correctly cause segfaults. + */ + if (addr == 0) + addr += PAGE_SIZE; #if 1 set_brk(ia32_mm_addr(addr), addr + eppnt->p_memsz); memset((char *) addr + eppnt->p_filesz, 0, eppnt->p_memsz - eppnt->p_filesz); diff -urN linux-2.4.0-test12/arch/ia64/ia32/ia32_entry.S linux-2.4.0-test12-lia/arch/ia64/ia32/ia32_entry.S --- linux-2.4.0-test12/arch/ia64/ia32/ia32_entry.S Tue Sep 5 13:50:01 2000 +++ linux-2.4.0-test12-lia/arch/ia64/ia32/ia32_entry.S Mon Oct 30 22:29:33 2000 @@ -291,11 +291,43 @@ data8 sys_getcwd data8 sys_capget data8 sys_capset /* 185 */ - data8 sys_sigaltstack + data8 sys32_sigaltstack data8 sys_sendfile data8 sys32_ni_syscall /* streams1 */ data8 sys32_ni_syscall /* streams2 */ data8 sys32_vfork /* 190 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall /* 195 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall /* 200 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall /* 205 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall /* 210 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall /* 215 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall /* 220 */ + data8 sys_ni_syscall + data8 sys_ni_syscall /* * CAUTION: If any system calls are added beyond this point * then the check in `arch/ia64/kernel/ivt.S' will have diff -urN linux-2.4.0-test12/arch/ia64/ia32/ia32_ioctl.c linux-2.4.0-test12-lia/arch/ia64/ia32/ia32_ioctl.c --- linux-2.4.0-test12/arch/ia64/ia32/ia32_ioctl.c Fri Jul 14 16:08:11 2000 +++ linux-2.4.0-test12-lia/arch/ia64/ia32/ia32_ioctl.c Mon Oct 30 22:29:51 2000 @@ -22,81 +22,158 @@ #include #include #include +#include <../drivers/char/drm/drm.h> + +#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) + +#define DO_IOCTL(fd, cmd, arg) ({ \ + int _ret; \ + mm_segment_t _old_fs = get_fs(); \ + \ + set_fs(KERNEL_DS); \ + _ret = sys_ioctl(fd, cmd, (unsigned long)arg); \ + set_fs(_old_fs); \ + _ret; \ +}) + +#define P(i) ((void *)(long)(i)) + asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); asmlinkage long ia32_ioctl(unsigned int fd, unsigned int cmd, unsigned int arg) { + long ret; + + switch (IOCTL_NR(cmd)) { + + case IOCTL_NR(DRM_IOCTL_VERSION): + break; + case IOCTL_NR(DRM_IOCTL_GET_UNIQUE): + { + drm_unique_t un; + struct { + unsigned int unique_len; + unsigned int unique; + } un32; + + if (copy_from_user(&un32, P(arg), sizeof(un32))) + return -EFAULT; + un.unique_len = un32.unique_len; + un.unique = P(un32.unique); + ret = DO_IOCTL(fd, cmd, &un); + if (ret >= 0) { + un32.unique_len = un.unique_len; + if (copy_to_user(P(arg), &un32, sizeof(un32))) + return -EFAULT; + } + return(ret); + } + case IOCTL_NR(DRM_IOCTL_SET_UNIQUE): + case IOCTL_NR(DRM_IOCTL_ADD_MAP): + case IOCTL_NR(DRM_IOCTL_ADD_BUFS): + case IOCTL_NR(DRM_IOCTL_MARK_BUFS): + case IOCTL_NR(DRM_IOCTL_INFO_BUFS): + case IOCTL_NR(DRM_IOCTL_MAP_BUFS): + case IOCTL_NR(DRM_IOCTL_FREE_BUFS): + case IOCTL_NR(DRM_IOCTL_ADD_CTX): + case IOCTL_NR(DRM_IOCTL_RM_CTX): + case IOCTL_NR(DRM_IOCTL_MOD_CTX): + case IOCTL_NR(DRM_IOCTL_GET_CTX): + case IOCTL_NR(DRM_IOCTL_SWITCH_CTX): + case IOCTL_NR(DRM_IOCTL_NEW_CTX): + case IOCTL_NR(DRM_IOCTL_RES_CTX): + + case IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE): + case IOCTL_NR(DRM_IOCTL_AGP_RELEASE): + case IOCTL_NR(DRM_IOCTL_AGP_ENABLE): + case IOCTL_NR(DRM_IOCTL_AGP_INFO): + case IOCTL_NR(DRM_IOCTL_AGP_ALLOC): + case IOCTL_NR(DRM_IOCTL_AGP_FREE): + case IOCTL_NR(DRM_IOCTL_AGP_BIND): + case IOCTL_NR(DRM_IOCTL_AGP_UNBIND): + + /* Mga specific ioctls */ + + case IOCTL_NR(DRM_IOCTL_MGA_INIT): + + /* I810 specific ioctls */ + + case IOCTL_NR(DRM_IOCTL_I810_GETBUF): + case IOCTL_NR(DRM_IOCTL_I810_COPY): + + /* Rage 128 specific ioctls */ - switch (cmd) { + case IOCTL_NR(DRM_IOCTL_R128_PACKET): - case VFAT_IOCTL_READDIR_BOTH: - case VFAT_IOCTL_READDIR_SHORT: - case MTIOCGET: - case MTIOCPOS: - case MTIOCGETCONFIG: - case MTIOCSETCONFIG: - case PPPIOCSCOMPRESS: - case PPPIOCGIDLE: - case NCP_IOC_GET_FS_INFO_V2: - case NCP_IOC_GETOBJECTNAME: - case NCP_IOC_SETOBJECTNAME: - case NCP_IOC_GETPRIVATEDATA: - case NCP_IOC_SETPRIVATEDATA: - case NCP_IOC_GETMOUNTUID2: - case CAPI_MANUFACTURER_CMD: - case VIDIOCGTUNER: - case VIDIOCSTUNER: - case VIDIOCGWIN: - case VIDIOCSWIN: - case VIDIOCGFBUF: - case VIDIOCSFBUF: - case MGSL_IOCSPARAMS: - case MGSL_IOCGPARAMS: - case ATM_GETNAMES: - case ATM_GETLINKRATE: - case ATM_GETTYPE: - case ATM_GETESI: - case ATM_GETADDR: - case ATM_RSTADDR: - case ATM_ADDADDR: - case ATM_DELADDR: - case ATM_GETCIRANGE: - case ATM_SETCIRANGE: - case ATM_SETESI: - case ATM_SETESIF: - case ATM_GETSTAT: - case ATM_GETSTATZ: - case ATM_GETLOOP: - case ATM_SETLOOP: - case ATM_QUERYLOOP: - case ENI_SETMULT: - case NS_GETPSTAT: - /* case NS_SETBUFLEV: This is a duplicate case with ZATM_GETPOOLZ */ - case ZATM_GETPOOLZ: - case ZATM_GETPOOL: - case ZATM_SETPOOL: - case ZATM_GETTHIST: - case IDT77105_GETSTAT: - case IDT77105_GETSTATZ: - case IXJCTL_TONE_CADENCE: - case IXJCTL_FRAMES_READ: - case IXJCTL_FRAMES_WRITTEN: - case IXJCTL_READ_WAIT: - case IXJCTL_WRITE_WAIT: - case IXJCTL_DRYBUFFER_READ: - case I2OHRTGET: - case I2OLCTGET: - case I2OPARMSET: - case I2OPARMGET: - case I2OSWDL: - case I2OSWUL: - case I2OSWDEL: - case I2OHTML: - printk("%x:unimplemented IA32 ioctl system call\n", cmd); - return(-EINVAL); + case IOCTL_NR(VFAT_IOCTL_READDIR_BOTH): + case IOCTL_NR(VFAT_IOCTL_READDIR_SHORT): + case IOCTL_NR(MTIOCGET): + case IOCTL_NR(MTIOCPOS): + case IOCTL_NR(MTIOCGETCONFIG): + case IOCTL_NR(MTIOCSETCONFIG): + case IOCTL_NR(PPPIOCSCOMPRESS): + case IOCTL_NR(PPPIOCGIDLE): + case IOCTL_NR(NCP_IOC_GET_FS_INFO_V2): + case IOCTL_NR(NCP_IOC_GETOBJECTNAME): + case IOCTL_NR(NCP_IOC_SETOBJECTNAME): + case IOCTL_NR(NCP_IOC_GETPRIVATEDATA): + case IOCTL_NR(NCP_IOC_SETPRIVATEDATA): + case IOCTL_NR(NCP_IOC_GETMOUNTUID2): + case IOCTL_NR(CAPI_MANUFACTURER_CMD): + case IOCTL_NR(VIDIOCGTUNER): + case IOCTL_NR(VIDIOCSTUNER): + case IOCTL_NR(VIDIOCGWIN): + case IOCTL_NR(VIDIOCSWIN): + case IOCTL_NR(VIDIOCGFBUF): + case IOCTL_NR(VIDIOCSFBUF): + case IOCTL_NR(MGSL_IOCSPARAMS): + case IOCTL_NR(MGSL_IOCGPARAMS): + case IOCTL_NR(ATM_GETNAMES): + case IOCTL_NR(ATM_GETLINKRATE): + case IOCTL_NR(ATM_GETTYPE): + case IOCTL_NR(ATM_GETESI): + case IOCTL_NR(ATM_GETADDR): + case IOCTL_NR(ATM_RSTADDR): + case IOCTL_NR(ATM_ADDADDR): + case IOCTL_NR(ATM_DELADDR): + case IOCTL_NR(ATM_GETCIRANGE): + case IOCTL_NR(ATM_SETCIRANGE): + case IOCTL_NR(ATM_SETESI): + case IOCTL_NR(ATM_SETESIF): + case IOCTL_NR(ATM_GETSTAT): + case IOCTL_NR(ATM_GETSTATZ): + case IOCTL_NR(ATM_GETLOOP): + case IOCTL_NR(ATM_SETLOOP): + case IOCTL_NR(ATM_QUERYLOOP): + case IOCTL_NR(ENI_SETMULT): + case IOCTL_NR(NS_GETPSTAT): + /* case IOCTL_NR(NS_SETBUFLEV): This is a duplicate case with ZATM_GETPOOLZ */ + case IOCTL_NR(ZATM_GETPOOLZ): + case IOCTL_NR(ZATM_GETPOOL): + case IOCTL_NR(ZATM_SETPOOL): + case IOCTL_NR(ZATM_GETTHIST): + case IOCTL_NR(IDT77105_GETSTAT): + case IOCTL_NR(IDT77105_GETSTATZ): + case IOCTL_NR(IXJCTL_TONE_CADENCE): + case IOCTL_NR(IXJCTL_FRAMES_READ): + case IOCTL_NR(IXJCTL_FRAMES_WRITTEN): + case IOCTL_NR(IXJCTL_READ_WAIT): + case IOCTL_NR(IXJCTL_WRITE_WAIT): + case IOCTL_NR(IXJCTL_DRYBUFFER_READ): + case IOCTL_NR(I2OHRTGET): + case IOCTL_NR(I2OLCTGET): + case IOCTL_NR(I2OPARMSET): + case IOCTL_NR(I2OPARMGET): + case IOCTL_NR(I2OSWDL): + case IOCTL_NR(I2OSWUL): + case IOCTL_NR(I2OSWDEL): + case IOCTL_NR(I2OHTML): + break; default: return(sys_ioctl(fd, cmd, (unsigned long)arg)); } + printk("%x:unimplemented IA32 ioctl system call\n", cmd); + return(-EINVAL); } diff -urN linux-2.4.0-test12/arch/ia64/ia32/ia32_traps.c linux-2.4.0-test12-lia/arch/ia64/ia32/ia32_traps.c --- linux-2.4.0-test12/arch/ia64/ia32/ia32_traps.c Thu Jun 22 07:09:44 2000 +++ linux-2.4.0-test12-lia/arch/ia64/ia32/ia32_traps.c Mon Oct 30 22:30:04 2000 @@ -119,6 +119,6 @@ default: return -1; } - force_sig_info(SIGTRAP, &siginfo, current); + force_sig_info(siginfo.si_signo, &siginfo, current); return 0; } diff -urN linux-2.4.0-test12/arch/ia64/ia32/sys_ia32.c linux-2.4.0-test12-lia/arch/ia64/ia32/sys_ia32.c --- linux-2.4.0-test12/arch/ia64/ia32/sys_ia32.c Wed Dec 6 18:32:30 2000 +++ linux-2.4.0-test12-lia/arch/ia64/ia32/sys_ia32.c Wed Dec 6 18:36:35 2000 @@ -236,8 +236,6 @@ if (OFFSET4K(addr) || OFFSET4K(off)) return -EINVAL; - if (prot & PROT_WRITE) - prot |= PROT_EXEC; prot |= PROT_WRITE; front = NULL; back = NULL; @@ -287,23 +285,20 @@ unsigned int poff; flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + prot |= PROT_EXEC; if ((flags & MAP_FIXED) && ((addr & ~PAGE_MASK) || (offset & ~PAGE_MASK))) error = do_mmap_fake(file, addr, len, prot, flags, (loff_t)offset); - else if (!addr && (offset & ~PAGE_MASK)) { + else { poff = offset & PAGE_MASK; len += offset - poff; down(¤t->mm->mmap_sem); - error = do_mmap(file, addr, len, prot, flags, poff); + error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT); up(¤t->mm->mmap_sem); if (!IS_ERR((void *) error)) error += offset - poff; - } else { - down(¤t->mm->mmap_sem); - error = do_mmap(file, addr, len, prot, flags, offset); - up(¤t->mm->mmap_sem); } return error; } @@ -2032,14 +2027,14 @@ ret = sys_times(tbuf ? &t : NULL); set_fs (old_fs); if (tbuf) { - err = put_user (t.tms_utime, &tbuf->tms_utime); - err |= __put_user (t.tms_stime, &tbuf->tms_stime); - err |= __put_user (t.tms_cutime, &tbuf->tms_cutime); - err |= __put_user (t.tms_cstime, &tbuf->tms_cstime); + err = put_user (IA32_TICK(t.tms_utime), &tbuf->tms_utime); + err |= __put_user (IA32_TICK(t.tms_stime), &tbuf->tms_stime); + err |= __put_user (IA32_TICK(t.tms_cutime), &tbuf->tms_cutime); + err |= __put_user (IA32_TICK(t.tms_cstime), &tbuf->tms_cstime); if (err) ret = -EFAULT; } - return ret; + return IA32_TICK(ret); } unsigned int @@ -2617,6 +2612,45 @@ * manipulating the page protections... */ return(sys_iopl(3, 0, 0, 0)); +} + +typedef struct { + unsigned int ss_sp; + unsigned int ss_flags; + unsigned int ss_size; +} ia32_stack_t; + +asmlinkage long +sys32_sigaltstack (const ia32_stack_t *uss32, ia32_stack_t *uoss32, +long arg2, long arg3, long arg4, +long arg5, long arg6, long arg7, +long stack) +{ + struct pt_regs *pt = (struct pt_regs *) &stack; + stack_t uss, uoss; + ia32_stack_t buf32; + int ret; + mm_segment_t old_fs = get_fs(); + + if (uss32) + if (copy_from_user(&buf32, (void *)A(uss32), sizeof(ia32_stack_t))) + return(-EFAULT); + uss.ss_sp = (void *) (long) buf32.ss_sp; + uss.ss_flags = buf32.ss_flags; + uss.ss_size = buf32.ss_size; + set_fs(KERNEL_DS); + ret = do_sigaltstack(uss32 ? &uss : NULL, &uoss, pt->r12); + set_fs(old_fs); + if (ret < 0) + return(ret); + if (uoss32) { + buf32.ss_sp = (long) uoss.ss_sp; + buf32.ss_flags = uoss.ss_flags; + buf32.ss_size = uoss.ss_size; + if (copy_to_user((void*)A(uoss32), &buf32, sizeof(ia32_stack_t))) + return(-EFAULT); + } + return(ret); } #ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */ diff -urN linux-2.4.0-test12/arch/ia64/kernel/Makefile linux-2.4.0-test12-lia/arch/ia64/kernel/Makefile --- linux-2.4.0-test12/arch/ia64/kernel/Makefile Mon Oct 9 17:54:53 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/Makefile Thu Dec 14 14:08:10 2000 @@ -10,10 +10,11 @@ all: kernel.o head.o init_task.o obj-y := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \ - machvec.o pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \ + machvec.o pal.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \ signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o -obj-$(CONFIG_IA64_GENERIC) += machvec.o +obj-$(CONFIG_IA64_GENERIC) += machvec.o iosapic.o +obj-$(CONFIG_IA64_DIG) += iosapic.o obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_SMP) += smp.o smpboot.o @@ -21,7 +22,7 @@ obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o O_TARGET := kernel.o -O_OBJS := $(obj-y) +O_OBJS := $(obj-y) OX_OBJS := ia64_ksyms.o clean:: diff -urN linux-2.4.0-test12/arch/ia64/kernel/acpi.c linux-2.4.0-test12-lia/arch/ia64/kernel/acpi.c --- linux-2.4.0-test12/arch/ia64/kernel/acpi.c Mon Oct 9 17:54:53 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/acpi.c Wed Dec 6 22:18:40 2000 @@ -6,6 +6,12 @@ * * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999,2000 Walt Drummond + * Copyright (C) 2000 Hewlett-Packard Co. + * Copyright (C) 2000 David Mosberger-Tang + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + * ACPI based kernel configuration manager. + * ACPI 2.0 & IA64 ext 0.71 */ #include @@ -36,29 +42,87 @@ void (*pm_idle)(void); +asm (".weak iosapic_register_legacy_irq"); +asm (".weak iosapic_init"); + +const char * +acpi_get_sysname (void) +{ + /* the following should go away once we have an ACPI parser: */ +#ifdef CONFIG_IA64_GENERIC + return "hpsim"; +#else +# if defined (CONFIG_IA64_HP_SIM) + return "hpsim"; +# elif defined (CONFIG_IA64_SGI_SN1) + return "sn1"; +# elif defined (CONFIG_IA64_DIG) + return "dig"; +# else +# error Unknown platform. Fix acpi.c. +# endif +#endif + +} + /* - * Identify usable CPU's and remember them for SMP bringup later. + * Configure legacy IRQ information. */ static void __init -acpi_lsapic(char *p) +acpi_legacy_irq (char *p) { - int add = 1; - - acpi_entry_lsapic_t *lsapic = (acpi_entry_lsapic_t *) p; + acpi_entry_int_override_t *legacy = (acpi_entry_int_override_t *) p; + unsigned long polarity = 0, edge_triggered = 0; - if ((lsapic->flags & LSAPIC_PRESENT) == 0) + /* + * If the platform we're running doesn't define + * iosapic_register_legacy_irq(), we ignore this info... + */ + if (!iosapic_register_legacy_irq) return; + switch (legacy->flags) { + case 0x5: polarity = 1; edge_triggered = 1; break; + case 0x7: polarity = 0; edge_triggered = 1; break; + case 0xd: polarity = 1; edge_triggered = 0; break; + case 0xf: polarity = 0; edge_triggered = 0; break; + default: + printk(" ACPI Legacy IRQ 0x%02x: Unknown flags 0x%x\n", legacy->isa_irq, + legacy->flags); + break; + } + iosapic_register_legacy_irq(legacy->isa_irq, legacy->pin, polarity, edge_triggered); +} + +/* + * ACPI 2.0 tables parsing functions + */ + +static unsigned long +readl_unaligned(void *p) +{ + unsigned long ret; + + memcpy(&ret, p, sizeof(long)); + return ret; +} + +/* + * Identify usable CPU's and remember them for SMP bringup later. + */ +static void __init +acpi20_lsapic (char *p) +{ + int add = 1; + + acpi20_entry_lsapic_t *lsapic = (acpi20_entry_lsapic_t *) p; printk(" CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id); if ((lsapic->flags & LSAPIC_ENABLED) == 0) { printk("Disabled.\n"); add = 0; - } else if (lsapic->flags & LSAPIC_PERFORMANCE_RESTRICTED) { - printk("Performance Restricted; ignoring.\n"); - add = 0; } - + #ifdef CONFIG_SMP smp_boot_data.cpu_phys_id[total_cpus] = -1; #endif @@ -73,87 +137,234 @@ } /* - * Configure legacy IRQ information in iosapic_vector + * Info on platform interrupt sources: NMI. PMI, INIT, etc. */ static void __init -acpi_legacy_irq(char *p) +acpi20_platform (char *p) { - /* - * This is not good. ACPI is not necessarily limited to CONFIG_IA64_DIG, yet - * ACPI does not necessarily imply IOSAPIC either. Perhaps there should be - * a means for platform_setup() to register ACPI handlers? - */ -#ifdef CONFIG_IA64_IRQ_ACPI - acpi_entry_int_override_t *legacy = (acpi_entry_int_override_t *) p; - unsigned char vector; - int i; + acpi20_entry_platform_src_t *plat = (acpi20_entry_platform_src_t *) p; + + printk("PLATFORM: IOSAPIC %x -> Vector %x on CPU %.04u:%.04u\n", + plat->iosapic_vector, plat->global_vector, plat->eid, plat->id); +} - vector = isa_irq_to_vector(legacy->isa_irq); +/* + * Override the physical address of the local APIC in the MADT stable header. + */ +static void __init +acpi20_lapic_addr_override (char *p) +{ + acpi20_entry_lapic_addr_override_t * lapic = (acpi20_entry_lapic_addr_override_t *) p; + + if (lapic->lapic_address) { + iounmap((void *)ipi_base_addr); + ipi_base_addr = (unsigned long) ioremap(lapic->lapic_address, 0); + + printk("LOCAL ACPI override to 0x%lx(p=0x%lx)\n", + ipi_base_addr, lapic->lapic_address); + } +} + +/* + * Parse the ACPI Multiple APIC Description Table + */ +static void __init +acpi20_parse_madt (acpi_madt_t *madt) +{ + acpi_entry_iosapic_t *iosapic; + char *p, *end; + + /* Base address of IPI Message Block */ + if (madt->lapic_address) { + ipi_base_addr = (unsigned long) ioremap(madt->lapic_address, 0); + printk("Lapic address set to 0x%lx\n", ipi_base_addr); + } else + printk("Lapic address set to default 0x%lx\n", ipi_base_addr); + + p = (char *) (madt + 1); + end = p + (madt->header.length - sizeof(acpi_madt_t)); /* - * Clobber any old pin mapping. It may be that it gets replaced later on - */ - for (i = 0; i < IA64_MAX_VECTORED_IRQ; i++) { - if (i == vector) - continue; - if (iosapic_pin(i) == iosapic_pin(vector)) - iosapic_pin(i) = 0xff; - } - - iosapic_pin(vector) = legacy->pin; - iosapic_bus(vector) = BUS_ISA; /* This table only overrides the ISA devices */ - iosapic_busdata(vector) = 0; - - /* - * External timer tick is special... + * Splitted entry parsing to ensure ordering. */ - if (vector != TIMER_IRQ) - iosapic_dmode(vector) = IO_SAPIC_LOWEST_PRIORITY; - else - iosapic_dmode(vector) = IO_SAPIC_FIXED; + + while (p < end) { + switch (*p) { + case ACPI20_ENTRY_LOCAL_APIC_ADDR_OVERRIDE: + printk("ACPI 2.0 MADT: LOCAL APIC Override\n"); + acpi20_lapic_addr_override(p); + break; + + case ACPI20_ENTRY_LOCAL_SAPIC: + printk("ACPI 2.0 MADT: LOCAL SAPIC\n"); + acpi20_lsapic(p); + break; - /* See MPS 1.4 section 4.3.4 */ - switch (legacy->flags) { - case 0x5: - iosapic_polarity(vector) = IO_SAPIC_POL_HIGH; - iosapic_trigger(vector) = IO_SAPIC_EDGE; - break; - case 0x8: - iosapic_polarity(vector) = IO_SAPIC_POL_LOW; - iosapic_trigger(vector) = IO_SAPIC_EDGE; - break; - case 0xd: - iosapic_polarity(vector) = IO_SAPIC_POL_HIGH; - iosapic_trigger(vector) = IO_SAPIC_LEVEL; - break; - case 0xf: - iosapic_polarity(vector) = IO_SAPIC_POL_LOW; - iosapic_trigger(vector) = IO_SAPIC_LEVEL; - break; - default: - printk(" ACPI Legacy IRQ 0x%02x: Unknown flags 0x%x\n", legacy->isa_irq, - legacy->flags); - break; + case ACPI20_ENTRY_IO_SAPIC: + iosapic = (acpi_entry_iosapic_t *) p; + if (iosapic_init) + iosapic_init(iosapic->address, iosapic->irq_base); + break; + + case ACPI20_ENTRY_PLATFORM_INT_SOURCE: + printk("ACPI 2.0 MADT: PLATFORM INT SOUCE\n"); + acpi20_platform(p); + break; + + case ACPI20_ENTRY_LOCAL_APIC: + printk("ACPI 2.0 MADT: LOCAL APIC entry\n"); break; + case ACPI20_ENTRY_IO_APIC: + printk("ACPI 2.0 MADT: IO APIC entry\n"); break; + case ACPI20_ENTRY_NMI_SOURCE: + printk("ACPI 2.0 MADT: NMI SOURCE entry\n"); break; + case ACPI20_ENTRY_LOCAL_APIC_NMI: + printk("ACPI 2.0 MADT: LOCAL APIC NMI entry\n"); break; + case ACPI20_ENTRY_INT_SRC_OVERRIDE: + break; + default: + printk("ACPI 2.0 MADT: unknown entry skip\n"); break; + break; + } + + p += p[1]; } -# ifdef ACPI_DEBUG - printk("Legacy ISA IRQ %x -> IA64 Vector %x IOSAPIC Pin %x Active %s %s Trigger\n", - legacy->isa_irq, vector, iosapic_pin(vector), - ((iosapic_polarity(vector) == IO_SAPIC_POL_LOW) ? "Low" : "High"), - ((iosapic_trigger(vector) == IO_SAPIC_LEVEL) ? "Level" : "Edge")); -# endif /* ACPI_DEBUG */ -#endif /* CONFIG_IA64_IRQ_ACPI */ + p = (char *) (madt + 1); + end = p + (madt->header.length - sizeof(acpi_madt_t)); + + while (p < end) { + + switch (*p) { + case ACPI20_ENTRY_INT_SRC_OVERRIDE: + printk("ACPI 2.0 MADT: INT SOURCE Override\n"); + acpi_legacy_irq(p); + break; + default: + break; + } + + p += p[1]; + } + + /* Make bootup pretty */ + printk(" %d CPUs available, %d CPUs total\n", + available_cpus, total_cpus); +} + +int __init +acpi20_parse (acpi20_rsdp_t *rsdp20) +{ + acpi_xsdt_t *xsdt; + acpi_desc_table_hdr_t *hdrp; + int tables, i; + + if (strncmp(rsdp20->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) { + printk("ACPI 2.0 RSDP signature incorrect!\n"); + return 0; + } else { + printk("ACPI 2.0 Root System Description Ptr at 0x%lx\n", + (unsigned long)rsdp20); + } + + xsdt = __va(rsdp20->xsdt); + hdrp = &xsdt->header; + if (strncmp(hdrp->signature, + ACPI_XSDT_SIG, ACPI_XSDT_SIG_LEN)) { + printk("ACPI 2.0 XSDT signature incorrect. Trying RSDT\n"); + /* RSDT parsing here */ + return 0; + } else { + printk("ACPI 2.0 XSDT at 0x%lx (p=0x%lx)\n", + (unsigned long)xsdt, (unsigned long)rsdp20->xsdt); + } + + printk("ACPI 2.0: %.6s %.8s %d.%d\n", + hdrp->oem_id, + hdrp->oem_table_id, + hdrp->oem_revision >> 16, + hdrp->oem_revision & 0xffff); + +#ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_init((void *)rsdp20); +#endif + + tables =(hdrp->length -sizeof(acpi_desc_table_hdr_t))>>3; + + for (i = 0; i < tables; i++) { + hdrp = (acpi_desc_table_hdr_t *) __va(readl_unaligned(&xsdt->entry_ptrs[i])); + printk(" :table %4.4s found\n", hdrp->signature); + + /* Only interested int the MADT table for now ... */ + if (strncmp(hdrp->signature, + ACPI_MADT_SIG, ACPI_MADT_SIG_LEN) != 0) + continue; + + acpi20_parse_madt((acpi_madt_t *) hdrp); + } + +#ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_terminate(); +#endif + +#ifdef CONFIG_SMP + if (available_cpus == 0) { + printk("ACPI: Found 0 CPUS; assuming 1\n"); + available_cpus = 1; /* We've got at least one of these, no? */ + } + smp_boot_data.cpu_count = available_cpus; +#endif + return 1; +} +/* + * ACPI 1.0b with 0.71 IA64 extensions functions; should be removed once all + * platforms start supporting ACPI 2.0 + */ + +/* + * Identify usable CPU's and remember them for SMP bringup later. + */ +static void __init +acpi_lsapic (char *p) +{ + int add = 1; + + acpi_entry_lsapic_t *lsapic = (acpi_entry_lsapic_t *) p; + + if ((lsapic->flags & LSAPIC_PRESENT) == 0) + return; + + printk(" CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id); + + if ((lsapic->flags & LSAPIC_ENABLED) == 0) { + printk("Disabled.\n"); + add = 0; + } else if (lsapic->flags & LSAPIC_PERFORMANCE_RESTRICTED) { + printk("Performance Restricted; ignoring.\n"); + add = 0; + } + +#ifdef CONFIG_SMP + smp_boot_data.cpu_phys_id[total_cpus] = -1; +#endif + if (add) { + printk("Available.\n"); + available_cpus++; +#ifdef CONFIG_SMP + smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid; +#endif /* CONFIG_SMP */ + } + total_cpus++; } /* * Info on platform interrupt sources: NMI. PMI, INIT, etc. */ static void __init -acpi_platform(char *p) +acpi_platform (char *p) { acpi_entry_platform_src_t *plat = (acpi_entry_platform_src_t *) p; - printk("PLATFORM: IOSAPIC %x -> Vector %lx on CPU %.04u:%.04u\n", + printk("PLATFORM: IOSAPIC %x -> Vector %x on CPU %.04u:%.04u\n", plat->iosapic_vector, plat->global_vector, plat->eid, plat->id); } @@ -161,8 +372,9 @@ * Parse the ACPI Multiple SAPIC Table */ static void __init -acpi_parse_msapic(acpi_sapic_t *msapic) +acpi_parse_msapic (acpi_sapic_t *msapic) { + acpi_entry_iosapic_t *iosapic; char *p, *end; /* Base address of IPI Message Block */ @@ -172,41 +384,31 @@ end = p + (msapic->header.length - sizeof(acpi_sapic_t)); while (p < end) { - switch (*p) { - case ACPI_ENTRY_LOCAL_SAPIC: + case ACPI_ENTRY_LOCAL_SAPIC: acpi_lsapic(p); break; - case ACPI_ENTRY_IO_SAPIC: - platform_register_iosapic((acpi_entry_iosapic_t *) p); + case ACPI_ENTRY_IO_SAPIC: + iosapic = (acpi_entry_iosapic_t *) p; + if (iosapic_init) + iosapic_init(iosapic->address, iosapic->irq_base); break; - case ACPI_ENTRY_INT_SRC_OVERRIDE: + case ACPI_ENTRY_INT_SRC_OVERRIDE: acpi_legacy_irq(p); break; - - case ACPI_ENTRY_PLATFORM_INT_SOURCE: + + case ACPI_ENTRY_PLATFORM_INT_SOURCE: acpi_platform(p); break; - - default: + + default: break; } /* Move to next table entry. */ -#define BAD_ACPI_TABLE -#ifdef BAD_ACPI_TABLE - /* - * Some prototype Lion's have a bad ACPI table - * requiring this fix. Without this fix, those - * machines crash during bootup. - */ - if (p[1] == 0) - p = end; - else -#endif - p += p[1]; + p += p[1]; } /* Make bootup pretty */ @@ -214,24 +416,18 @@ } int __init -acpi_parse(acpi_rsdp_t *rsdp) +acpi_parse (acpi_rsdp_t *rsdp) { acpi_rsdt_t *rsdt; acpi_desc_table_hdr_t *hdrp; long tables, i; - if (!rsdp) { - printk("Uh-oh, no ACPI Root System Description Pointer table!\n"); - return 0; - } - if (strncmp(rsdp->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) { printk("Uh-oh, ACPI RSDP signature incorrect!\n"); return 0; } - rsdp->rsdt = __va(rsdp->rsdt); - rsdt = rsdp->rsdt; + rsdt = __va(rsdp->rsdt); if (strncmp(rsdt->header.signature, ACPI_RSDT_SIG, ACPI_RSDT_SIG_LEN)) { printk("Uh-oh, ACPI RDST signature incorrect!\n"); return 0; @@ -256,7 +452,7 @@ } #ifdef CONFIG_ACPI_KERNEL_CONFIG - acpi_cf_terminate(); + acpi_cf_terminate(); #endif #ifdef CONFIG_SMP @@ -267,23 +463,4 @@ smp_boot_data.cpu_count = available_cpus; #endif return 1; -} - -const char * -acpi_get_sysname (void) -{ - /* the following should go away once we have an ACPI parser: */ -#ifdef CONFIG_IA64_GENERIC - return "hpsim"; -#else -# if defined (CONFIG_IA64_HP_SIM) - return "hpsim"; -# elif defined (CONFIG_IA64_SGI_SN1) - return "sn1"; -# elif defined (CONFIG_IA64_DIG) - return "dig"; -# else -# error Unknown platform. Fix acpi.c. -# endif -#endif } diff -urN linux-2.4.0-test12/arch/ia64/kernel/efi.c linux-2.4.0-test12-lia/arch/ia64/kernel/efi.c --- linux-2.4.0-test12/arch/ia64/kernel/efi.c Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/efi.c Wed Dec 6 22:20:03 2000 @@ -18,7 +18,6 @@ * Goutham Rao: * Skip non-WB memory and ignore empty memory ranges. */ -#include #include #include #include @@ -333,6 +332,9 @@ if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) { efi.mps = __va(config_tables[i].table); printk(" MPS=0x%lx", config_tables[i].table); + } else if (efi_guidcmp(config_tables[i].guid, ACPI_20_TABLE_GUID) == 0) { + efi.acpi20 = __va(config_tables[i].table); + printk(" ACPI 2.0=0x%lx", config_tables[i].table); } else if (efi_guidcmp(config_tables[i].guid, ACPI_TABLE_GUID) == 0) { efi.acpi = __va(config_tables[i].table); printk(" ACPI=0x%lx", config_tables[i].table); @@ -364,7 +366,7 @@ #if EFI_DEBUG /* print EFI memory map: */ { - efi_memory_desc_t *md = p; + efi_memory_desc_t *md; void *p; for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) { diff -urN linux-2.4.0-test12/arch/ia64/kernel/entry.S linux-2.4.0-test12-lia/arch/ia64/kernel/entry.S --- linux-2.4.0-test12/arch/ia64/kernel/entry.S Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/entry.S Wed Nov 15 17:52:56 2000 @@ -11,6 +11,17 @@ * Copyright (C) 1999 Don Dugger */ /* + * ia64_switch_to now places correct virtual mapping in in TR2 for + * kernel stack. This allows us to handle interrupts without changing + * to physical mode. + * + * ar.k4 is now used to hold last virtual map address + * + * Jonathan Nickin + * Patrick O'Rourke + * 11/07/2000 + / +/* * Global (preserved) predicate usage on syscall entry/exit path: * * pKern: See entry.h. @@ -27,7 +38,8 @@ #include #include #include - +#include + #include "entry.h" .text @@ -98,6 +110,8 @@ br.ret.sptk.many rp END(sys_clone) +#define KSTACK_TR 2 + /* * prev_task <- ia64_switch_to(struct task_struct *next) */ @@ -108,22 +122,55 @@ UNW(.body) adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13 - dep r18=-1,r0,0,61 // build mask 0x1fffffffffffffff + mov r27=ar.k4 + dep r20=0,in0,61,3 // physical address of "current" + ;; + st8 [r22]=sp // save kernel stack pointer of old task + shr.u r26=r20,_PAGE_SIZE_256M + ;; + cmp.eq p7,p6=r26,r0 // check < 256M adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 ;; - st8 [r22]=sp // save kernel stack pointer of old task - ld8 sp=[r21] // load kernel stack pointer of new task - and r20=in0,r18 // physical address of "current" - ;; - mov ar.k6=r20 // copy "current" into ar.k6 - mov r8=r13 // return pointer to previously running task - mov r13=in0 // set "current" pointer + /* + * If we've already mapped this task's page, we can skip doing it + * again. + */ +(p6) cmp.eq p7,p6=r26,r27 +(p6) br.cond.dpnt.few .map + ;; +.done: ld8 sp=[r21] // load kernel stack pointer of new task +(p6) ssm psr.ic // if we we had to map, renable the psr.ic bit FIRST!!! ;; +(p6) srlz.d + mov ar.k6=r20 // copy "current" into ar.k6 + mov r8=r13 // return pointer to previously running task + mov r13=in0 // set "current" pointer + ;; +(p6) ssm psr.i // renable psr.i AFTER the ic bit is serialized DO_LOAD_SWITCH_STACK( ) + #ifdef CONFIG_SMP - sync.i // ensure "fc"s done by this CPU are visible on other CPUs -#endif - br.ret.sptk.few rp + sync.i // ensure "fc"s done by this CPU are visible on other CPUs +#endif + br.ret.sptk.few rp // boogie on out in new context + +.map: + rsm psr.i | psr.ic + movl r25=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX + ;; + srlz.d + or r23=r25,r20 // construct PA | page properties + mov r25=_PAGE_SIZE_256M<<2 + ;; + mov cr.itir=r25 + mov cr.ifa=in0 // VA of next task... + ;; + mov r25=KSTACK_TR // use tr entry #2... + mov ar.k4=r26 // remember last page we mapped... + ;; + itr.d dtr[r25]=r23 // wire in new mapping... + br.cond.sptk.many .done + ;; END(ia64_switch_to) #ifndef CONFIG_IA64_NEW_UNWIND @@ -503,7 +550,7 @@ ;; ld4 r2=[r2] ;; - shl r2=r2,SMP_LOG_CACHE_BYTES // can't use shladd here... + shl r2=r2,SMP_CACHE_SHIFT // can't use shladd here... ;; add r3=r2,r3 #else @@ -611,14 +658,13 @@ mov ar.ccv=r1 mov ar.fpsr=r13 mov b0=r14 - // turn off interrupts, interrupt collection, & data translation - rsm psr.i | psr.ic | psr.dt + // turn off interrupts, interrupt collection + rsm psr.i | psr.ic ;; srlz.i // EAS 2.5 mov b7=r15 ;; invala // invalidate ALAT - dep r12=0,r12,61,3 // convert sp to physical address bsw.0;; // switch back to bank 0 (must be last in insn group) ;; #ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC @@ -1091,7 +1137,7 @@ data8 sys_setpriority data8 sys_statfs data8 sys_fstatfs - data8 ia64_ni_syscall + data8 ia64_ni_syscall // 1105 data8 sys_semget data8 sys_semop data8 sys_semctl diff -urN linux-2.4.0-test12/arch/ia64/kernel/fw-emu.c linux-2.4.0-test12-lia/arch/ia64/kernel/fw-emu.c --- linux-2.4.0-test12/arch/ia64/kernel/fw-emu.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/fw-emu.c Wed Nov 15 17:53:32 2000 @@ -402,7 +402,6 @@ sal_systab->sal_rev_minor = 1; sal_systab->sal_rev_major = 0; sal_systab->entry_count = 1; - sal_systab->ia32_bios_present = 0; #ifdef CONFIG_IA64_GENERIC strcpy(sal_systab->oem_id, "Generic"); diff -urN linux-2.4.0-test12/arch/ia64/kernel/head.S linux-2.4.0-test12-lia/arch/ia64/kernel/head.S --- linux-2.4.0-test12/arch/ia64/kernel/head.S Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/head.S Wed Nov 15 17:54:03 2000 @@ -74,8 +74,8 @@ ;; #ifdef CONFIG_IA64_EARLY_PRINTK - mov r2=6 - mov r3=(8<<8) | (28<<2) + mov r3=(6<<8) | (28<<2) + movl r2=6<<61 ;; mov rr[r2]=r3 ;; @@ -168,6 +168,11 @@ add r19=IA64_NUM_DBG_REGS*8,in0 ;; 1: mov r16=dbr[r18] +#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC) \ + || defined(CONFIG_ITANIUM_C0_SPECIFIC) + ;; + srlz.d +#endif mov r17=ibr[r18] add r18=1,r18 ;; @@ -181,7 +186,8 @@ GLOBAL_ENTRY(ia64_load_debug_regs) alloc r16=ar.pfs,1,0,0,0 -#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) +#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \ + || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC)) lfetch.nta [in0] #endif mov r20=ar.lc // preserve ar.lc @@ -194,6 +200,11 @@ add r18=1,r18 ;; mov dbr[r18]=r16 +#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC) \ + || defined(CONFIG_ITANIUM_C0_SPECIFIC) + ;; + srlz.d +#endif mov ibr[r18]=r17 br.cloop.sptk.few 1b ;; @@ -754,7 +765,7 @@ mov tmp=ar.itc (p15) br.cond.sptk .wait ;; - ld1 tmp=[r31] + ld4 tmp=[r31] ;; cmp.ne p15,p0=tmp,r0 mov tmp=ar.itc @@ -764,7 +775,7 @@ mov tmp=1 ;; IA64_SEMFIX_INSN - cmpxchg1.acq tmp=[r31],tmp,ar.ccv + cmpxchg4.acq tmp=[r31],tmp,ar.ccv ;; cmp.eq p15,p0=tmp,r0 diff -urN linux-2.4.0-test12/arch/ia64/kernel/ia64_ksyms.c linux-2.4.0-test12-lia/arch/ia64/kernel/ia64_ksyms.c --- linux-2.4.0-test12/arch/ia64/kernel/ia64_ksyms.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/ia64_ksyms.c Thu Dec 14 14:08:47 2000 @@ -24,10 +24,6 @@ EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strtok); -#include -EXPORT_SYMBOL(pci_alloc_consistent); -EXPORT_SYMBOL(pci_free_consistent); - #include #include /* not coded yet?? EXPORT_SYMBOL(csum_ipv6_magic); */ @@ -49,14 +45,6 @@ #include EXPORT_SYMBOL(clear_page); -#include -EXPORT_SYMBOL(pci_dma_sync_sg); -EXPORT_SYMBOL(pci_dma_sync_single); -EXPORT_SYMBOL(pci_map_sg); -EXPORT_SYMBOL(pci_map_single); -EXPORT_SYMBOL(pci_unmap_sg); -EXPORT_SYMBOL(pci_unmap_single); - #include EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(kernel_thread); @@ -92,6 +80,9 @@ #include EXPORT_SYMBOL(__copy_user); EXPORT_SYMBOL(__do_clear_user); +EXPORT_SYMBOL(__strlen_user); +EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(__strnlen_user); #include EXPORT_SYMBOL(__ia64_syscall); diff -urN linux-2.4.0-test12/arch/ia64/kernel/iosapic.c linux-2.4.0-test12-lia/arch/ia64/kernel/iosapic.c --- linux-2.4.0-test12/arch/ia64/kernel/iosapic.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/iosapic.c Wed Dec 6 22:22:38 2000 @@ -0,0 +1,498 @@ +/* + * I/O SAPIC support. + * + * Copyright (C) 1999 Intel Corp. + * Copyright (C) 1999 Asit Mallick + * Copyright (C) 1999-2000 Hewlett-Packard Co. + * Copyright (C) 1999-2000 David Mosberger-Tang + * Copyright (C) 1999 VA Linux Systems + * Copyright (C) 1999,2000 Walt Drummond + * + * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code. + * In particular, we now have separate handlers for edge + * and level triggered interrupts. + * 00/10/27 Asit Mallick, Goutham Rao IRQ vector allocation + * PCI to vector mapping, shared PCI interrupts. + * 00/10/27 D. Mosberger Document things a bit more to make them more understandable. + * Clean up much of the old IOSAPIC cruft. + */ +/* + * Here is what the interrupt logic between a PCI device and the CPU looks like: + * + * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD). The + * device is uniquely identified by its bus-, device-, and slot-number (the function + * number does not matter here because all functions share the same interrupt + * lines). + * + * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller. + * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level + * triggered and use the same polarity). Each interrupt line has a unique IOSAPIC + * irq number which can be calculated as the sum of the controller's base irq number + * and the IOSAPIC pin number to which the line connects. + * + * (3) The IOSAPIC uses an internal table to map the IOSAPIC pin into the IA-64 interrupt + * vector. This interrupt vector is then sent to the CPU. + * + * In other words, there are two levels of indirections involved: + * + * pci pin -> iosapic irq -> IA-64 vector + * + * Note: outside this module, IA-64 vectors are called "irqs". This is because that's + * the traditional name Linux uses for interrupt vectors. + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ACPI_KERNEL_CONFIG +# include +#endif + +#undef DEBUG_IRQ_ROUTING + +static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; + +/* PCI pin to IOSAPIC irq routing information. This info typically comes from ACPI. */ + +static struct { + int num_routes; + struct pci_vector_struct *route; +} pci_irq; + +/* This tables maps IA-64 vectors to the IOSAPIC pin that generates this vector. */ + +static struct iosapic_irq { + char *addr; /* base address of IOSAPIC */ + unsigned char base_irq; /* first irq assigned to this IOSAPIC */ + char pin; /* IOSAPIC pin (-1 => not an IOSAPIC irq) */ + unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ + unsigned char polarity : 1; /* interrupt polarity (see iosapic.h) */ + unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ +} iosapic_irq[NR_IRQS]; + +/* + * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector. If no + * entry exists, return -1. + */ +static int +iosapic_irq_to_vector (int irq) +{ + int vector; + + for (vector = 0; vector < NR_IRQS; ++vector) + if (iosapic_irq[vector].base_irq + iosapic_irq[vector].pin == irq) + return vector; + return -1; +} + +/* + * Map PCI pin to the corresponding IA-64 interrupt vector. If no such mapping exists, + * return -1. + */ +static int +pci_pin_to_vector (int bus, int slot, int pci_pin) +{ + struct pci_vector_struct *r; + + for (r = pci_irq.route; r < pci_irq.route + pci_irq.num_routes; ++r) + if (r->bus == bus && (r->pci_id >> 16) == slot && r->pin == pci_pin) + return iosapic_irq_to_vector(r->irq); + return -1; +} + +static void +set_rte (unsigned int vector, unsigned long dest) +{ + unsigned long pol, trigger, dmode; + u32 low32, high32; + char *addr; + int pin; + + pin = iosapic_irq[vector].pin; + if (pin < 0) + return; /* not an IOSAPIC interrupt */ + + addr = iosapic_irq[vector].addr; + pol = iosapic_irq[vector].polarity; + trigger = iosapic_irq[vector].trigger; + dmode = iosapic_irq[vector].dmode; + + low32 = ((pol << IOSAPIC_POLARITY_SHIFT) | + (trigger << IOSAPIC_TRIGGER_SHIFT) | + (dmode << IOSAPIC_DELIVERY_SHIFT) | + vector); + +#ifdef CONFIG_IA64_AZUSA_HACKS + /* set Flush Disable bit */ + if (addr != (char *) 0xc0000000fec00000) + low32 |= (1 << 17); +#endif + + /* dest contains both id and eid */ + high32 = (dest << IOSAPIC_DEST_SHIFT); + + writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT); + writel(high32, addr + IOSAPIC_WINDOW); + writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + writel(low32, addr + IOSAPIC_WINDOW); +} + +static void +nop (unsigned int vector) +{ + /* do nothing... */ +} + +static void +mask_irq (unsigned int vector) +{ + unsigned long flags; + char *addr; + u32 low32; + int pin; + + addr = iosapic_irq[vector].addr; + pin = iosapic_irq[vector].pin; + + if (pin < 0) + return; /* not an IOSAPIC interrupt! */ + + spin_lock_irqsave(&iosapic_lock, flags); + { + writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + low32 = readl(addr + IOSAPIC_WINDOW); + + low32 |= (1 << IOSAPIC_MASK_SHIFT); /* set only the mask bit */ + writel(low32, addr + IOSAPIC_WINDOW); + } + spin_unlock_irqrestore(&iosapic_lock, flags); +} + +static void +unmask_irq (unsigned int vector) +{ + unsigned long flags; + char *addr; + u32 low32; + int pin; + + addr = iosapic_irq[vector].addr; + pin = iosapic_irq[vector].pin; + if (pin < 0) + return; /* not an IOSAPIC interrupt! */ + + spin_lock_irqsave(&iosapic_lock, flags); + { + writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT); + low32 = readl(addr + IOSAPIC_WINDOW); + + low32 &= ~(1 << IOSAPIC_MASK_SHIFT); /* clear only the mask bit */ + writel(low32, addr + IOSAPIC_WINDOW); + } + spin_unlock_irqrestore(&iosapic_lock, flags); +} + + +static void +iosapic_set_affinity (unsigned int vector, unsigned long mask) +{ + printk("iosapic_set_affinity: not implemented yet\n"); +} + +/* + * Handlers for level-triggered interrupts. + */ + +static unsigned int +iosapic_startup_level_irq (unsigned int vector) +{ + unmask_irq(vector); + return 0; +} + +static void +iosapic_end_level_irq (unsigned int vector) +{ + writel(vector, iosapic_irq[vector].addr + IOSAPIC_EOI); +} + +#define iosapic_shutdown_level_irq mask_irq +#define iosapic_enable_level_irq unmask_irq +#define iosapic_disable_level_irq mask_irq +#define iosapic_ack_level_irq nop + +struct hw_interrupt_type irq_type_iosapic_level = { + typename: "IO-SAPIC-level", + startup: iosapic_startup_level_irq, + shutdown: iosapic_shutdown_level_irq, + enable: iosapic_enable_level_irq, + disable: iosapic_disable_level_irq, + ack: iosapic_ack_level_irq, + end: iosapic_end_level_irq, + set_affinity: iosapic_set_affinity +}; + +/* + * Handlers for edge-triggered interrupts. + */ + +static unsigned int +iosapic_startup_edge_irq (unsigned int vector) +{ + unmask_irq(vector); + /* + * IOSAPIC simply drops interrupts pended while the + * corresponding pin was masked, so we can't know if an + * interrupt is pending already. Let's hope not... + */ + return 0; +} + +static void +iosapic_ack_edge_irq (unsigned int vector) +{ + /* + * Once we have recorded IRQ_PENDING already, we can mask the + * interrupt for real. This prevents IRQ storms from unhandled + * devices. + */ + if ((irq_desc[vector].status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED)) + mask_irq(vector); +} + +#define iosapic_enable_edge_irq unmask_irq +#define iosapic_disable_edge_irq nop +#define iosapic_end_edge_irq nop + +struct hw_interrupt_type irq_type_iosapic_edge = { + typename: "IO-SAPIC-edge", + startup: iosapic_startup_edge_irq, + shutdown: iosapic_disable_edge_irq, + enable: iosapic_enable_edge_irq, + disable: iosapic_disable_edge_irq, + ack: iosapic_ack_edge_irq, + end: iosapic_end_edge_irq, + set_affinity: iosapic_set_affinity +}; + +static unsigned int +iosapic_version (char *addr) +{ + /* + * IOSAPIC Version Register return 32 bit structure like: + * { + * unsigned int version : 8; + * unsigned int reserved1 : 8; + * unsigned int pins : 8; + * unsigned int reserved2 : 8; + * } + */ + writel(IOSAPIC_VERSION, addr + IOSAPIC_REG_SELECT); + return readl(IOSAPIC_WINDOW + addr); +} + +/* + * ACPI calls this when it finds an entry for a legacy ISA interrupt. Note that the + * irq_base and IOSAPIC address must be set in iosapic_init(). + */ +void +iosapic_register_legacy_irq (unsigned long irq, + unsigned long pin, unsigned long polarity, + unsigned long edge_triggered) +{ + unsigned int vector = isa_irq_to_vector(irq); + +#ifdef DEBUG_IRQ_ROUTING + printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (%s, %s) -> vector %02x\n", + (unsigned) irq, (unsigned) pin, + polarity ? "high" : "low", edge_triggered ? "edge" : "level", + vector); +#endif + + iosapic_irq[vector].pin = pin; + iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY; + iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW; + iosapic_irq[vector].trigger = edge_triggered ? IOSAPIC_EDGE : IOSAPIC_LEVEL; +} + +void __init +iosapic_init (unsigned long phys_addr, unsigned int base_irq) +{ + struct hw_interrupt_type *irq_type; + int i, irq, max_pin, vector; + unsigned int ver; + char *addr; + static int first_time = 1; + + if (first_time) { + first_time = 0; + + for (vector = 0; vector < NR_IRQS; ++vector) + iosapic_irq[vector].pin = -1; /* mark as unused */ + + /* + * Fetch the PCI interrupt routing table: + */ +#ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_get_pci_vectors(&pci_irq.route, &pci_irq.num_routes); +#else + pci_irq.route = + (struct pci_vector_struct *) __va(ia64_boot_param.pci_vectors); + pci_irq.num_routes = ia64_boot_param.num_pci_vectors; +#endif + } + + addr = ioremap(phys_addr, 0); + + ver = iosapic_version(addr); + max_pin = (ver >> 16) & 0xff; + + printk("IOSAPIC: version %x.%x, address 0x%lx, IRQs 0x%02x-0x%02x\n", + (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, base_irq, base_irq + max_pin); + + if (base_irq == 0) + /* + * Map the legacy ISA devices into the IOSAPIC data. Some of these may + * get reprogrammed later on with data from the ACPI Interrupt Source + * Override table. + */ + for (irq = 0; irq < 16; ++irq) { + vector = isa_irq_to_vector(irq); + iosapic_irq[vector].addr = addr; + iosapic_irq[vector].base_irq = 0; + if (iosapic_irq[vector].pin == -1) + iosapic_irq[vector].pin = irq; + iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY; + iosapic_irq[vector].trigger = IOSAPIC_EDGE; + iosapic_irq[vector].polarity = IOSAPIC_POL_HIGH; +#ifdef DEBUG_IRQ_ROUTING + printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (high, edge) -> vector 0x%02x\n", + irq, iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, + vector); +#endif + irq_type = &irq_type_iosapic_edge; + if (irq_desc[vector].handler != irq_type) { + if (irq_desc[vector].handler != &no_irq_type) + printk("iosapic_init: changing vector 0x%02x from %s to " + "%s\n", irq, irq_desc[vector].handler->typename, + irq_type->typename); + irq_desc[vector].handler = irq_type; + } + + /* program the IOSAPIC routing table: */ + set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); + } + +#ifndef CONFIG_IA64_SOFTSDV_HACKS + for (i = 0; i < pci_irq.num_routes; i++) { + irq = pci_irq.route[i].irq; + + if ((unsigned) (irq - base_irq) > max_pin) + /* the interrupt route is for another controller... */ + continue; + + if (irq < 16) + vector = isa_irq_to_vector(irq); + else { + vector = iosapic_irq_to_vector(irq); + if (vector < 0) + /* new iosapic irq: allocate a vector for it */ + vector = ia64_alloc_irq(); + } + + iosapic_irq[vector].addr = addr; + iosapic_irq[vector].base_irq = base_irq; + iosapic_irq[vector].pin = (irq - base_irq); + iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY; + iosapic_irq[vector].trigger = IOSAPIC_LEVEL; + iosapic_irq[vector].polarity = IOSAPIC_POL_LOW; + +# ifdef DEBUG_IRQ_ROUTING + printk("PCI: (B%d,I%d,P%d) -> IOSAPIC irq 0x%02x -> vector 0x%02x\n", + pci_irq.route[i].bus, pci_irq.route[i].pci_id>>16, pci_irq.route[i].pin, + iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector); +# endif + irq_type = &irq_type_iosapic_level; + if (irq_desc[vector].handler != irq_type){ + if (irq_desc[vector].handler != &no_irq_type) + printk("iosapic_init: changing vector 0x%02x from %s to %s\n", + vector, irq_desc[vector].handler->typename, + irq_type->typename); + irq_desc[vector].handler = irq_type; + } + + /* program the IOSAPIC routing table: */ + set_rte(vector, (ia64_get_lid() >> 16) & 0xffff); + } +#endif /* !CONFIG_IA64_SOFTSDV_HACKS */ +} + +void +iosapic_pci_fixup (int phase) +{ + struct pci_dev *dev; + unsigned char pin; + int vector; + + if (phase != 1) + return; + + pci_for_each_dev(dev) { + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin) { + pin--; /* interrupt pins are numbered starting from 1 */ + vector = pci_pin_to_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + if (vector < 0 && dev->bus->parent) { + /* go back to the bridge */ + struct pci_dev *bridge = dev->bus->self; + + if (bridge) { + /* allow for multiple bridges on an adapter */ + do { + /* do the bridge swizzle... */ + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + vector = pci_pin_to_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), + pin); + } while (vector < 0 && (bridge = bridge->bus->self)); + } + if (vector >= 0) + printk(KERN_WARNING + "PCI: using PPB(B%d,I%d,P%d) to get vector %02x\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), + pin, vector); + else + printk(KERN_WARNING + "PCI: Couldn't map irq for (B%d,I%d,P%d)o\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), + pin); + } + if (vector >= 0) { + printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> 0x%02x\n", + dev->bus->number, PCI_SLOT(dev->devfn), pin, vector); + dev->irq = vector; + } + } + /* + * Nothing to fixup + * Fix out-of-range IRQ numbers + */ + if (dev->irq >= NR_IRQS) + dev->irq = 15; /* Spurious interrupts */ + } +} diff -urN linux-2.4.0-test12/arch/ia64/kernel/irq.c linux-2.4.0-test12-lia/arch/ia64/kernel/irq.c --- linux-2.4.0-test12/arch/ia64/kernel/irq.c Wed Dec 13 17:29:20 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/irq.c Thu Dec 14 14:09:00 2000 @@ -541,6 +541,18 @@ spin_unlock_irqrestore(&desc->lock, flags); } +void do_IRQ_per_cpu(unsigned long irq, struct pt_regs *regs) +{ + irq_desc_t *desc = irq_desc + irq; + int cpu = smp_processor_id(); + + kstat.irqs[cpu][irq]++; + + desc->handler->ack(irq); + handle_IRQ_event(irq, regs, desc->action); + desc->handler->end(irq); +} + /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -581,8 +593,7 @@ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { action = desc->action; status &= ~IRQ_PENDING; /* we commit to handling */ - if (!(status & IRQ_PER_CPU)) - status |= IRQ_INPROGRESS; /* we are handling it */ + status |= IRQ_INPROGRESS; /* we are handling it */ } desc->status = status; diff -urN linux-2.4.0-test12/arch/ia64/kernel/irq_ia64.c linux-2.4.0-test12-lia/arch/ia64/kernel/irq_ia64.c --- linux-2.4.0-test12/arch/ia64/kernel/irq_ia64.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/irq_ia64.c Thu Dec 14 14:09:33 2000 @@ -7,6 +7,9 @@ * * 6/10/99: Updated to bring in sync with x86 version to facilitate * support for SMP and different interrupt controllers. + * + * 09/15/00 Goutham Rao Implemented pci_irq_to_vector + * PCI to vector allocation routine. */ #include @@ -35,38 +38,28 @@ #define IRQ_DEBUG 0 -#ifdef CONFIG_ITANIUM_A1_SPECIFIC -spinlock_t ivr_read_lock; -#endif - /* default base addr of IPI table */ unsigned long ipi_base_addr = (__IA64_UNCACHED_OFFSET | IPI_DEFAULT_BASE_ADDR); /* - * Legacy IRQ to IA-64 vector translation table. Any vector not in - * this table maps to itself (ie: irq 0x30 => IA64 vector 0x30) + * Legacy IRQ to IA-64 vector translation table. */ __u8 isa_irq_to_vector_map[16] = { /* 8259 IRQ translation, first 16 entries */ - 0x60, 0x50, 0x10, 0x51, 0x52, 0x53, 0x43, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x40, 0x41 + 0x2f, 0x20, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, + 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21 }; -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - -int usbfix; - -static int __init -usbfix_option (char *str) +int +ia64_alloc_irq (void) { - printk("irq: enabling USB workaround\n"); - usbfix = 1; - return 1; -} - -__setup("usbfix", usbfix_option); + static int next_irq = FIRST_DEVICE_IRQ; -#endif /* CONFIG_ITANIUM_A1_SPECIFIC */ + if (next_irq > LAST_DEVICE_IRQ) + /* XXX could look for sharable vectors instead of panic'ing... */ + panic("ia64_alloc_irq: out of interrupt vectors!"); + return next_irq++; +} /* * That's where the IVT branches when we get an external @@ -77,42 +70,6 @@ ia64_handle_irq (unsigned long vector, struct pt_regs *regs) { unsigned long saved_tpr; -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - unsigned long eoi_ptr; - -# ifdef CONFIG_USB - extern void reenable_usb (void); - extern void disable_usb (void); - - if (usbfix) - disable_usb(); -# endif - /* - * Stop IPIs by getting the ivr_read_lock - */ - spin_lock(&ivr_read_lock); - { - unsigned int tmp; - /* - * Disable PCI writes - */ - outl(0x80ff81c0, 0xcf8); - tmp = inl(0xcfc); - outl(tmp | 0x400, 0xcfc); - eoi_ptr = inl(0xcfc); - vector = ia64_get_ivr(); - /* - * Enable PCI writes - */ - outl(tmp, 0xcfc); - } - spin_unlock(&ivr_read_lock); - -# ifdef CONFIG_USB - if (usbfix) - reenable_usb(); -# endif -#endif /* CONFIG_ITANIUM_A1_SPECIFIC */ #if IRQ_DEBUG { @@ -161,7 +118,10 @@ ia64_set_tpr(vector); ia64_srlz_d(); - do_IRQ(vector, regs); + if ((irq_desc[vector].status & IRQ_PER_CPU) != 0) + do_IRQ_per_cpu(vector, regs); + else + do_IRQ(vector, regs); /* * Disable interrupts and send EOI: @@ -169,9 +129,6 @@ local_irq_disable(); ia64_set_tpr(saved_tpr); ia64_eoi(); -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - break; -#endif vector = ia64_get_ivr(); } while (vector != IA64_SPURIOUS_INT); } @@ -194,8 +151,8 @@ * Disable all local interrupts */ ia64_set_itv(0, 1); - ia64_set_lrr0(0, 1); - ia64_set_lrr1(0, 1); + ia64_set_lrr0(0, 1); + ia64_set_lrr1(0, 1); irq_desc[IA64_SPURIOUS_INT].handler = &irq_type_ia64_sapic; #ifdef CONFIG_SMP @@ -217,14 +174,11 @@ } void -ipi_send (int cpu, int vector, int delivery_mode, int redirect) +ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect) { unsigned long ipi_addr; unsigned long ipi_data; unsigned long phys_cpu_id; -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - unsigned long flags; -#endif #ifdef CONFIG_SMP phys_cpu_id = cpu_physical_id(cpu); @@ -239,13 +193,5 @@ ipi_data = (delivery_mode << 8) | (vector & 0xff); ipi_addr = ipi_base_addr | (phys_cpu_id << 4) | ((redirect & 1) << 3); -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - spin_lock_irqsave(&ivr_read_lock, flags); -#endif - writeq(ipi_data, ipi_addr); - -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - spin_unlock_irqrestore(&ivr_read_lock, flags); -#endif } diff -urN linux-2.4.0-test12/arch/ia64/kernel/ivt.S linux-2.4.0-test12-lia/arch/ia64/kernel/ivt.S --- linux-2.4.0-test12/arch/ia64/kernel/ivt.S Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/ivt.S Thu Dec 14 20:11:48 2000 @@ -44,20 +44,10 @@ #include #include -#define MINSTATE_START_SAVE_MIN /* no special action needed */ -#define MINSTATE_END_SAVE_MIN \ - or r2=r2,r14; /* make first base a kernel virtual address */ \ - or r12=r12,r14; /* make sp a kernel virtual address */ \ - or r13=r13,r14; /* make `current' a kernel virtual address */ \ - bsw.1; /* switch back to bank 1 (must be last in insn group) */ \ - ;; - +#define MINSTATE_VIRT /* needed by minstate.h */ #include "minstate.h" #define FAULT(n) \ - rsm psr.dt; /* avoid nested faults due to TLB misses... */ \ - ;; \ - srlz.d; /* ensure everyone knows psr.dt is off... */ \ mov r31=pr; \ mov r19=n;; /* prepare to save predicates */ \ br.cond.sptk.many dispatch_to_fault_handler @@ -122,15 +112,14 @@ (p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d // ensure "rsm psr.dt" has taken effect (p6) movl r19=__pa(SWAPPER_PGD_ADDR) // region 5 is rooted at swapper_pg_dir -(p6) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-1 -(p7) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-4 +(p6) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT +(p7) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 ;; (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) cmp.eq p7,p6=0,r21 // unused address bits all zeroes? shr.u r18=r16,PMD_SHIFT // shift L2 index into position ;; -(p6) cmp.eq p7,p6=-1,r21 // unused address bits all ones? ld8 r17=[r17] // fetch the L1 entry (may be 0) ;; (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? @@ -232,15 +221,14 @@ (p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d // ensure "rsm psr.dt" has taken effect (p6) movl r19=__pa(SWAPPER_PGD_ADDR) // region 5 is rooted at swapper_pg_dir -(p6) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-1 -(p7) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-4 +(p6) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT +(p7) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 ;; (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) cmp.eq p7,p6=0,r21 // unused address bits all zeroes? shr.u r18=r16,PMD_SHIFT // shift L2 index into position ;; -(p6) cmp.eq p7,p6=-1,r21 // unused address bits all ones? ld8 r17=[r17] // fetch the L1 entry (may be 0) ;; (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? @@ -319,15 +307,14 @@ (p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place srlz.d // ensure "rsm psr.dt" has taken effect (p6) movl r19=__pa(SWAPPER_PGD_ADDR) // region 5 is rooted at swapper_pg_dir -(p6) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-1 -(p7) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-4 +(p6) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT +(p7) shr r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 ;; (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) cmp.eq p7,p6=0,r21 // unused address bits all zeroes? shr.u r18=r16,PMD_SHIFT // shift L2 index into position ;; -(p6) cmp.eq p7,p6=-1,r21 // unused address bits all ones? ld8 r17=[r17] // fetch the L1 entry (may be 0) ;; (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? @@ -361,34 +348,37 @@ ///////////////////////////////////////////////////////////////////////////////////////// // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) mov r16=cr.ifa // get address that caused the TLB miss -#ifdef CONFIG_DISABLE_VHPT + movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX + mov r21=cr.ipsr mov r31=pr ;; - shr.u r21=r16,61 // get the region number into r21 - ;; - cmp.gt p6,p0=6,r21 // user mode -(p6) br.cond.dptk.many itlb_fault +#ifdef CONFIG_DISABLE_VHPT + shr.u r22=r16,61 // get the region number into r21 ;; - mov pr=r31,-1 + cmp.gt p8,p0=6,r22 // user mode +(p8) br.cond.dptk.many itlb_fault #endif - movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RX - ;; + extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl shr.u r18=r16,57 // move address bit 61 to bit 4 - dep r16=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits + dep r19=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits ;; andcm r18=0x10,r18 // bit 4=~address-bit(61) - dep r16=r17,r16,0,12 // insert PTE control bits into r16 + cmp.ne p8,p0=r0,r23 // psr.cpl != 0? + dep r19=r17,r19,0,12 // insert PTE control bits into r19 ;; - or r16=r16,r18 // set bit 4 (uncached) if the access was to region 6 + or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 +(p8) br.cond.spnt.many page_fault ;; - itc.i r16 // insert the TLB entry + itc.i r19 // insert the TLB entry + mov pr=r31,-1 rfi + ;; .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) mov r16=cr.ifa // get address that caused the TLB miss - movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW + movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX mov r20=cr.isr mov r21=cr.ipsr mov r31=pr @@ -399,26 +389,33 @@ cmp.gt p8,p0=6,r22 // user mode (p8) br.cond.dptk.many dtlb_fault #endif + extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? shr.u r18=r16,57 // move address bit 61 to bit 4 - dep r16=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits + dep r19=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits ;; - dep r21=-1,r21,IA64_PSR_ED_BIT,1 andcm r18=0x10,r18 // bit 4=~address-bit(61) - dep r16=r17,r16,0,12 // insert PTE control bits into r16 + cmp.ne p8,p0=r0,r23 +(p8) br.cond.spnt.many page_fault + + dep r21=-1,r21,IA64_PSR_ED_BIT,1 + dep r19=r17,r19,0,12 // insert PTE control bits into r19 ;; - or r16=r16,r18 // set bit 4 (uncached) if the access was to region 6 + or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 (p6) mov cr.ipsr=r21 ;; -(p7) itc.d r16 // insert the TLB entry +(p7) itc.d r19 // insert the TLB entry mov pr=r31,-1 rfi - ;; //----------------------------------------------------------------------------------- // call do_page_fault (predicates are in r31, psr.dt is off, r16 is faulting address) page_fault: + ssm psr.dt + ;; + srlz.i + ;; SAVE_MIN_WITH_COVER // // Copy control registers to temporary registers, then turn on psr bits, @@ -430,7 +427,7 @@ mov r9=cr.isr adds r3=8,r2 // set up second base pointer ;; - ssm psr.ic | psr.dt + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled ;; @@ -535,7 +532,7 @@ ;; 1: ld8 r18=[r17] ;; // avoid RAW on r18 - or r18=_PAGE_D,r18 // set the dirty bit + or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits mov b0=r29 // restore b0 ;; st8 [r17]=r18 // store back updated PTE @@ -552,7 +549,7 @@ 1: ld8 r18=[r17] ;; // avoid RAW on r18 mov ar.ccv=r18 // set compare value for cmpxchg - or r25=_PAGE_D,r18 // set the dirty bit + or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits ;; cmpxchg8.acq r26=[r17],r25,ar.ccv mov r24=PAGE_SHIFT<<2 @@ -725,16 +722,14 @@ mov r16=cr.iim mov r17=__IA64_BREAK_SYSCALL mov r31=pr // prepare to save predicates - rsm psr.dt // avoid nested faults due to TLB misses... ;; - srlz.d // ensure everyone knows psr.dt is off... cmp.eq p0,p7=r16,r17 // is this a system call? (p7 <- false, if so) (p7) br.cond.spnt.many non_syscall SAVE_MIN // uses r31; defines r2: - // turn interrupt collection and data translation back on: - ssm psr.ic | psr.dt + // turn interrupt collection back on: + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 @@ -746,14 +741,13 @@ adds r3=8,r2 // set up second base pointer for SAVE_REST ;; SAVE_REST - ;; // avoid WAW on r2 & r3 + br.call.sptk rp=demine_args // clear NaT bits in (potential) syscall args mov r3=255 adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = ¤t->ptrace - ;; - cmp.geu.unc p6,p7=r3,r15 // (syscall > 0 && syscall <= 1024+255) ? + cmp.geu p6,p7=r3,r15 // (syscall > 0 && syscall <= 1024+255) ? movl r16=sys_call_table ;; (p6) shladd r16=r15,3,r16 @@ -792,29 +786,49 @@ br.call.sptk.few rp=ia64_trace_syscall // rp will be overwritten (ignored) // NOT REACHED + .proc demine_args +demine_args: + alloc r2=ar.pfs,8,0,0,0 + tnat.nz p8,p0=in0 + tnat.nz p9,p0=in1 + ;; +(p8) mov in0=-1 + tnat.nz p10,p0=in2 + tnat.nz p11,p0=in3 + +(p9) mov in1=-1 + tnat.nz p12,p0=in4 + tnat.nz p13,p0=in5 + ;; +(p10) mov in2=-1 + tnat.nz p14,p0=in6 + tnat.nz p15,p0=in7 + +(p11) mov in3=-1 +(p12) mov in4=-1 +(p13) mov in5=-1 + ;; +(p14) mov in6=-1 +(p15) mov in7=-1 + br.ret.sptk.few rp + .endp demine_args + .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) - rsm psr.dt // avoid nested faults due to TLB misses... - ;; - srlz.d // ensure everyone knows psr.dt is off... mov r31=pr // prepare to save predicates ;; SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 - ssm psr.ic | psr.dt // turn interrupt collection and data translation back on + ssm psr.ic // turn interrupt collection ;; adds r3=8,r2 // set up second base pointer for SAVE_REST - srlz.i // ensure everybody knows psr.ic and psr.dt are back on + srlz.i // ensure everybody knows psr.ic is back on ;; SAVE_REST ;; alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - mov out0=r0 // defer reading of cr.ivr to handle_irq... -#else mov out0=cr.ivr // pass cr.ivr as first arg -#endif add out1=16,sp // pass pointer to pt_regs as second arg ;; srlz.d // make sure we see the effect of cr.ivr @@ -855,7 +869,7 @@ // The "alloc" can cause a mandatory store which could lead to // an "Alt DTLB" fault which we can handle only if psr.ic is on. // - ssm psr.ic | psr.dt + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled ;; @@ -881,6 +895,7 @@ cmp.ne p6,p0=0,r8 (p6) br.call.dpnt b6=b6 // call returns to ia64_leave_kernel br.sptk ia64_leave_kernel + ;; .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// @@ -900,7 +915,7 @@ SAVE_MIN ;; mov r14=cr.isr - ssm psr.ic | psr.dt + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled ;; @@ -924,7 +939,7 @@ alloc r15=ar.pfs,0,0,6,0 // must first in an insn group ;; ld4 r8=[r14],8 // r8 == EAX (syscall number) - mov r15=190 // sys_vfork - last implemented system call + mov r15=222 // sys_vfork - last implemented system call ;; cmp.leu.unc p6,p7=r8,r15 ld4 out1=[r14],8 // r9 == ecx @@ -985,8 +1000,8 @@ mov r8=cr.iim // get break immediate (must be done while psr.ic is off) adds r3=8,r2 // set up second base pointer for SAVE_REST - // turn interrupt collection and data translation back on: - ssm psr.ic | psr.dt + // turn interrupt collection back on: + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled ;; @@ -1023,7 +1038,7 @@ // wouldn't get the state to recover. // mov r15=cr.ifa - ssm psr.ic | psr.dt + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled ;; @@ -1055,7 +1070,6 @@ // // Input: // psr.ic: off - // psr.dt: off // r19: fault vector number (e.g., 24 for General Exception) // r31: contains saved predicates (pr) // @@ -1071,7 +1085,7 @@ mov r10=cr.iim mov r11=cr.itir ;; - ssm psr.ic | psr.dt + ssm psr.ic ;; srlz.i // guarantee that interrupt collection is enabled ;; @@ -1099,12 +1113,11 @@ // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) mov r16=cr.ifa rsm psr.dt -#if 1 - // If you disable this, you MUST re-enable to update_mmu_cache() code in pgtable.h + // The Linux page fault handler doesn't expect non-present pages to be in + // the TLB. Flush the existing entry now, so we meet that expectation. mov r17=_PAGE_SIZE_4K<<2 ;; ptc.l r16,r17 -#endif ;; mov r31=pr srlz.d @@ -1145,9 +1158,7 @@ // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) mov r16=cr.isr mov r31=pr - rsm psr.dt // avoid nested faults due to TLB misses... ;; - srlz.d // ensure everyone knows psr.dt is off... cmp4.eq p6,p0=0,r16 (p6) br.sptk dispatch_illegal_op_fault ;; @@ -1157,7 +1168,7 @@ .align 256 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) - rsm psr.dt | psr.dfh // ensure we can access fph + rsm psr.dfh // ensure we can access fph ;; srlz.d mov r31=pr @@ -1218,11 +1229,9 @@ .align 256 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) - rsm psr.dt // avoid nested faults due to TLB misses... mov r16=cr.ipsr mov r31=pr // prepare to save predicates ;; - srlz.d // ensure everyone knows psr.dt is off br.cond.sptk.many dispatch_unaligned_handler .align 256 @@ -1304,9 +1313,6 @@ ///////////////////////////////////////////////////////////////////////////////////////// // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) #ifdef CONFIG_IA32_SUPPORT - rsm psr.dt - ;; - srlz.d mov r31=pr mov r16=cr.isr ;; @@ -1334,9 +1340,6 @@ ///////////////////////////////////////////////////////////////////////////////////////// // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) #ifdef CONFIG_IA32_SUPPORT - rsm psr.dt - ;; - srlz.d mov r31=pr br.cond.sptk.many dispatch_to_ia32_handler #else diff -urN linux-2.4.0-test12/arch/ia64/kernel/machvec.c linux-2.4.0-test12-lia/arch/ia64/kernel/machvec.c --- linux-2.4.0-test12/arch/ia64/kernel/machvec.c Sun Aug 13 10:17:16 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/machvec.c Wed Nov 15 17:57:18 2000 @@ -1,10 +1,12 @@ #include + +#ifdef CONFIG_IA64_GENERIC + #include +#include #include #include - -#ifdef CONFIG_IA64_GENERIC struct ia64_machine_vector ia64_mv; diff -urN linux-2.4.0-test12/arch/ia64/kernel/mca.c linux-2.4.0-test12-lia/arch/ia64/kernel/mca.c --- linux-2.4.0-test12/arch/ia64/kernel/mca.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/mca.c Wed Nov 15 17:57:31 2000 @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -365,7 +366,7 @@ void ia64_mca_wakeup(int cpu) { - ipi_send(cpu, IA64_MCA_WAKEUP_INT_VECTOR, IA64_IPI_DM_INT, 0); + platform_send_ipi(cpu, IA64_MCA_WAKEUP_INT_VECTOR, IA64_IPI_DM_INT, 0); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; } diff -urN linux-2.4.0-test12/arch/ia64/kernel/mca_asm.S linux-2.4.0-test12-lia/arch/ia64/kernel/mca_asm.S --- linux-2.4.0-test12/arch/ia64/kernel/mca_asm.S Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/mca_asm.S Wed Nov 15 17:57:45 2000 @@ -3,11 +3,10 @@ // // Mods by cfleck to integrate into kernel build // 00/03/15 davidm Added various stop bits to get a clean compile -// 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp kstack, -// switch modes, jump to C INIT handler // -#include - +// 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp +// kstack, switch modes, jump to C INIT handler +// #include #include #include @@ -17,14 +16,7 @@ * When we get an machine check, the kernel stack pointer is no longer * valid, so we need to set a new stack pointer. */ -#define MINSTATE_START_SAVE_MIN \ -(pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE; \ - ;; - -#define MINSTATE_END_SAVE_MIN \ - or r12=r12,r14; /* make sp a kernel virtual address */ \ - or r13=r13,r14; /* make `current' a kernel virtual address */ \ - ;; +#define MINSTATE_PHYS /* Make sure stack access is physical for MINSTATE */ #include "minstate.h" diff -urN linux-2.4.0-test12/arch/ia64/kernel/minstate.h linux-2.4.0-test12-lia/arch/ia64/kernel/minstate.h --- linux-2.4.0-test12/arch/ia64/kernel/minstate.h Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/minstate.h Wed Dec 6 22:46:31 2000 @@ -20,6 +20,72 @@ #define rR1 r20 /* + * Here start the source dependent macros. + */ + +/* + * For ivt.s we want to access the stack virtually so we dont have to disable translation + * on interrupts. + */ +#define MINSTATE_START_SAVE_MIN_VIRT \ + dep r1=-1,r1,61,3; /* r1 = current (virtual) */ \ +(p7) mov ar.rsc=r0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ + ;; \ +(p7) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ +(p7) mov rARRNAT=ar.rnat; \ +(pKern) mov r1=sp; /* get sp */ \ + ;; \ +(p7) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ +(p7) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ + ;; \ +(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ +(p7) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ + ;; \ +(p7) mov r18=ar.bsp; \ +(p7) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ + +#define MINSTATE_END_SAVE_MIN_VIRT \ + or r13=r13,r14; /* make `current' a kernel virtual address */ \ + bsw.1; /* switch back to bank 1 (must be last in insn group) */ \ + ;; + +/* + * For mca_asm.S we want to access the stack physically since the state is saved before we + * go virtual and dont want to destroy the iip or ipsr. + */ +#define MINSTATE_START_SAVE_MIN_PHYS \ +(pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE; \ +(p7) mov ar.rsc=r0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ +(p7) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ + ;; \ +(p7) mov rARRNAT=ar.rnat; \ +(pKern) dep r1=0,sp,61,3; /* compute physical addr of sp */ \ +(p7) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ +(p7) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ +(p7) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */\ + ;; \ +(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ +(p7) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ + ;; \ +(p7) mov r18=ar.bsp; \ +(p7) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ + +#define MINSTATE_END_SAVE_MIN_PHYS \ + or r12=r12,r14; /* make sp a kernel virtual address */ \ + or r13=r13,r14; /* make `current' a kernel virtual address */ \ + ;; + +#ifdef MINSTATE_VIRT +# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_VIRT +# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_VIRT +#endif + +#ifdef MINSTATE_PHYS +# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_PHYS +# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_PHYS +#endif + +/* * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves * the minimum state necessary that allows us to turn psr.ic back * on. @@ -31,7 +97,6 @@ * * Upon exit, the state is as follows: * psr.ic: off - * psr.dt: off * r2 = points to &pt_regs.r16 * r12 = kernel sp (kernel virtual address) * r13 = points to current task_struct (kernel virtual address) @@ -50,7 +115,7 @@ mov rCRIPSR=cr.ipsr; \ mov rB6=b6; /* rB6 = branch reg 6 */ \ mov rCRIIP=cr.iip; \ - mov r1=ar.k6; /* r1 = current */ \ + mov r1=ar.k6; /* r1 = current (physical) */ \ ;; \ invala; \ extr.u r16=rCRIPSR,32,2; /* extract psr.cpl */ \ @@ -58,25 +123,11 @@ cmp.eq pKern,p7=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ \ /* switch from user to kernel RBS: */ \ COVER; \ - ;; \ - MINSTATE_START_SAVE_MIN \ -(p7) mov ar.rsc=r0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ -(p7) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ - ;; \ -(p7) mov rARRNAT=ar.rnat; \ -(pKern) dep r1=0,sp,61,3; /* compute physical addr of sp */ \ -(p7) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ -(p7) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ -(p7) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */ \ ;; \ -(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ -(p7) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ + MINSTATE_START_SAVE_MIN \ ;; \ -(p7) mov r18=ar.bsp; \ -(p7) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ - \ - mov r16=r1; /* initialize first base pointer */ \ - adds r17=8,r1; /* initialize second base pointer */ \ + mov r16=r1; /* initialize first base pointer */ \ + adds r17=8,r1; /* initialize second base pointer */ \ ;; \ st8 [r16]=rCRIPSR,16; /* save cr.ipsr */ \ st8 [r17]=rCRIIP,16; /* save cr.iip */ \ diff -urN linux-2.4.0-test12/arch/ia64/kernel/pal.S linux-2.4.0-test12-lia/arch/ia64/kernel/pal.S --- linux-2.4.0-test12/arch/ia64/kernel/pal.S Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/pal.S Wed Nov 15 17:58:01 2000 @@ -52,10 +52,9 @@ /* * Make a PAL call using the static calling convention. * - * in0 Pointer to struct ia64_pal_retval - * in1 Index of PAL service - * in2 - in4 Remaining PAL arguments - * in5 1 ==> clear psr.ic, 0 ==> don't clear psr.ic + * in0 Index of PAL service + * in1 - in3 Remaining PAL arguments + * in4 1 ==> clear psr.ic, 0 ==> don't clear psr.ic * */ GLOBAL_ENTRY(ia64_pal_call_static) @@ -69,7 +68,7 @@ } ;; ld8 loc2 = [loc2] // loc2 <- entry point - tbit.nz p6,p7 = in5, 0 + tbit.nz p6,p7 = in4, 0 adds r8 = 1f-1b,r8 ;; mov loc3 = psr diff -urN linux-2.4.0-test12/arch/ia64/kernel/palinfo.c linux-2.4.0-test12-lia/arch/ia64/kernel/palinfo.c --- linux-2.4.0-test12/arch/ia64/kernel/palinfo.c Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/palinfo.c Mon Oct 30 22:17:11 2000 @@ -16,7 +16,6 @@ * - as of 2.2.9/2.2.12, the following values are still wrong * PAL_VM_SUMMARY: key & rid sizes */ -#include #include #include #include diff -urN linux-2.4.0-test12/arch/ia64/kernel/pci-dma.c linux-2.4.0-test12-lia/arch/ia64/kernel/pci-dma.c --- linux-2.4.0-test12/arch/ia64/kernel/pci-dma.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/pci-dma.c Wed Dec 31 16:00:00 1969 @@ -1,517 +0,0 @@ -/* - * Dynamic DMA mapping support. - * - * This implementation is for IA-64 platforms that do not support - * I/O TLBs (aka DMA address translation hardware). - * Copyright (C) 2000 Asit Mallick - * Copyright (C) 2000 Goutham Rao - */ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef CONFIG_SWIOTLB - -#include -#include - -#define ALIGN(val, align) ((unsigned long) (((unsigned long) (val) + ((align) - 1)) & ~((align) - 1))) - -/* - * log of the size of each IO TLB slab. The number of slabs is command line - * controllable. - */ -#define IO_TLB_SHIFT 11 - -/* - * Used to do a quick range check in pci_unmap_single and pci_sync_single, to see if the - * memory was in fact allocated by this API. - */ -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. - * This is command line adjustable via setup_io_tlb_npages. - */ -unsigned long io_tlb_nslabs = 1024; - -/* - * This is a free list describing the number of free entries available from each index - */ -static unsigned int *io_tlb_list; -static unsigned int io_tlb_index; - -/* - * We need to save away the original address corresponding to a mapped entry for the sync - * operations. - */ -static unsigned char **io_tlb_orig_addr; - -/* - * Protect the above data structures in the map and unmap calls - */ -spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED; - -static int __init -setup_io_tlb_npages (char *str) -{ - io_tlb_nslabs = simple_strtoul(str, NULL, 0) << (PAGE_SHIFT - IO_TLB_SHIFT); - return 1; -} -__setup("swiotlb=", setup_io_tlb_npages); - -/* - * Statically reserve bounce buffer space and initialize bounce buffer - * data structures for the software IO TLB used to implement the PCI DMA API - */ -void -setup_swiotlb (void) -{ - int i; - - /* - * Get IO TLB memory from the low pages - */ - io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); - if (!io_tlb_start) - BUG(); - io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); - - /* - * Allocate and initialize the free list array. This array is used - * to find contiguous free memory regions of size 2^IO_TLB_SHIFT between - * io_tlb_start and io_tlb_end. - */ - io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); - for (i = 0; i < io_tlb_nslabs; i++) - io_tlb_list[i] = io_tlb_nslabs - i; - io_tlb_index = 0; - io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); - - printk("Placing software IO TLB between 0x%p - 0x%p\n", - (void *) io_tlb_start, (void *) io_tlb_end); -} - -/* - * Allocates bounce buffer and returns its kernel virtual address. - */ -static void * -__pci_map_single (struct pci_dev *hwdev, char *buffer, size_t size, int direction) -{ - unsigned long flags; - char *dma_addr; - unsigned int i, nslots, stride, index, wrap; - - /* - * For mappings greater than a page size, we limit the stride (and hence alignment) - * to a page size. - */ - nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; - if (size > (1 << PAGE_SHIFT)) - stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT)); - else - stride = nslots; - - if (!nslots) - BUG(); - - /* - * Find suitable number of IO TLB entries size that will fit this request and allocate a buffer - * from that IO TLB pool. - */ - spin_lock_irqsave(&io_tlb_lock, flags); - { - wrap = index = ALIGN(io_tlb_index, stride); - do { - /* - * If we find a slot that indicates we have 'nslots' number of - * contiguous buffers, we allocate the buffers from that slot and mark the - * entries as '0' indicating unavailable. - */ - if (io_tlb_list[index] >= nslots) { - for (i = index; i < index + nslots; i++) - io_tlb_list[i] = 0; - dma_addr = io_tlb_start + (index << IO_TLB_SHIFT); - - /* - * Update the indices to avoid searching in the next round. - */ - io_tlb_index = (index + nslots) < io_tlb_nslabs ? (index + nslots) : 0; - - goto found; - } - index += stride; - if (index >= io_tlb_nslabs) - 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("__pci_map_single: could not allocate software IO TLB (%ld bytes)", size); -found: - } - spin_unlock_irqrestore(&io_tlb_lock, flags); - - /* - * Save away the mapping from the original address to the DMA address. This is needed - * when we sync the memory. Then we sync the buffer if needed. - */ - io_tlb_orig_addr[index] = buffer; - if (direction == PCI_DMA_TODEVICE || direction == PCI_DMA_BIDIRECTIONAL) - memcpy(dma_addr, buffer, size); - - return dma_addr; -} - -/* - * dma_addr is the kernel virtual address of the bounce buffer to unmap. - */ -static void -__pci_unmap_single (struct pci_dev *hwdev, char *dma_addr, size_t size, int direction) -{ - unsigned long flags; - int i, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; - int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - char *buffer = io_tlb_orig_addr[index]; - - /* - * First, sync the memory before unmapping the entry - */ - if ((direction == PCI_DMA_FROMDEVICE) || (direction == PCI_DMA_BIDIRECTIONAL)) - /* - * bounce... copy the data back into the original buffer - * and delete the bounce buffer. - */ - memcpy(buffer, dma_addr, size); - - /* - * Return the buffer to the free list by setting the corresponding entries to indicate - * the number of contigous entries available. - * While returning the entries to the free list, we merge the entries with slots below - * and above the pool being returned. - */ - spin_lock_irqsave(&io_tlb_lock, flags); - { - int count = ((index + nslots) < io_tlb_nslabs ? io_tlb_list[index + nslots] : 0); - /* - * Step 1: return the slots to the free list, merging the slots with superceeding slots - */ - for (i = index + nslots - 1; i >= index; i--) - io_tlb_list[i] = ++count; - /* - * Step 2: merge the returned slots with the preceeding slots, if available (non zero) - */ - for (i = index - 1; (i >= 0) && io_tlb_list[i]; i--) - io_tlb_list[i] += io_tlb_list[index]; - } - spin_unlock_irqrestore(&io_tlb_lock, flags); -} - -static void -__pci_sync_single (struct pci_dev *hwdev, char *dma_addr, size_t size, int direction) -{ - int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; - char *buffer = io_tlb_orig_addr[index]; - - /* - * bounce... copy the data back into/from the original buffer - * XXX How do you handle PCI_DMA_BIDIRECTIONAL here ? - */ - if (direction == PCI_DMA_FROMDEVICE) - memcpy(buffer, dma_addr, size); - else if (direction == PCI_DMA_TODEVICE) - memcpy(dma_addr, buffer, size); - else - BUG(); -} - -/* - * Map a single buffer of the indicated size for DMA in streaming mode. - * The PCI address to use is returned. - * - * Once the device is given the dma address, the device owns this memory - * until either pci_unmap_single or pci_dma_sync_single is performed. - */ -dma_addr_t -pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) -{ - unsigned long pci_addr = virt_to_phys(ptr); - - if (direction == PCI_DMA_NONE) - BUG(); - /* - * Check if the PCI device can DMA to ptr... if so, just return ptr - */ - if ((pci_addr & ~hwdev->dma_mask) == 0) - /* - * Device is bit capable of DMA'ing to the - * buffer... just return the PCI address of ptr - */ - return pci_addr; - - /* - * get a bounce buffer: - */ - pci_addr = virt_to_phys(__pci_map_single(hwdev, ptr, size, direction)); - - /* - * Ensure that the address returned is DMA'ble: - */ - if ((pci_addr & ~hwdev->dma_mask) != 0) - panic("__pci_map_single: bounce buffer is not DMA'ble"); - - return pci_addr; -} - -/* - * Unmap a single streaming mode DMA translation. The dma_addr and size - * must match what was provided for in a previous pci_map_single call. All - * other usages are undefined. - * - * After this call, reads by the cpu to the buffer are guarenteed to see - * whatever the device wrote there. - */ -void -pci_unmap_single (struct pci_dev *hwdev, dma_addr_t pci_addr, size_t size, int direction) -{ - char *dma_addr = phys_to_virt(pci_addr); - - if (direction == PCI_DMA_NONE) - BUG(); - if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) - __pci_unmap_single(hwdev, dma_addr, size, direction); -} - -/* - * Make physical memory consistent for a single - * streaming mode DMA translation after a transfer. - * - * If you perform a pci_map_single() but wish to interrogate the - * buffer using the cpu, yet do not wish to teardown the PCI dma - * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, the - * device again owns the buffer. - */ -void -pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t pci_addr, size_t size, int direction) -{ - char *dma_addr = phys_to_virt(pci_addr); - - if (direction == PCI_DMA_NONE) - BUG(); - if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) - __pci_sync_single(hwdev, dma_addr, size, direction); -} - -/* - * Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scather-gather version of the - * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). - * - * NOTE: An implementation may be able to use a smaller number of - * DMA address/length pairs than there are SG table elements. - * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. - * - * Device ownership issues as mentioned above for pci_map_single are - * the same here. - */ -int -pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) -{ - int i; - - if (direction == PCI_DMA_NONE) - BUG(); - - for (i = 0; i < nelems; i++, sg++) { - sg->orig_address = sg->address; - if ((virt_to_phys(sg->address) & ~hwdev->dma_mask) != 0) { - sg->address = __pci_map_single(hwdev, sg->address, sg->length, direction); - } - } - return nelems; -} - -/* - * Unmap a set of streaming mode DMA translations. - * Again, cpu read rules concerning calls here are the same as for - * pci_unmap_single() above. - */ -void -pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) -{ - int i; - - if (direction == PCI_DMA_NONE) - BUG(); - - for (i = 0; i < nelems; i++, sg++) - if (sg->orig_address != sg->address) { - __pci_unmap_single(hwdev, sg->address, sg->length, direction); - sg->address = sg->orig_address; - } -} - -/* - * Make physical memory consistent for a set of streaming mode DMA - * translations after a transfer. - * - * The same as pci_dma_sync_single but for a scatter-gather list, - * same rules and usage. - */ -void -pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) -{ - int i; - - if (direction == PCI_DMA_NONE) - BUG(); - - for (i = 0; i < nelems; i++, sg++) - if (sg->orig_address != sg->address) - __pci_sync_single(hwdev, sg->address, sg->length, direction); -} - -#else -/* - * Map a single buffer of the indicated size for DMA in streaming mode. - * The 32-bit bus address to use is returned. - * - * Once the device is given the dma address, the device owns this memory - * until either pci_unmap_single or pci_dma_sync_single is performed. - */ -dma_addr_t -pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - return virt_to_bus(ptr); -} - -/* - * Unmap a single streaming mode DMA translation. The dma_addr and size - * must match what was provided for in a previous pci_map_single call. All - * other usages are undefined. - * - * After this call, reads by the cpu to the buffer are guarenteed to see - * whatever the device wrote there. - */ -void -pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - /* Nothing to do */ -} -/* - * Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scather-gather version of the - * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). - * - * NOTE: An implementation may be able to use a smaller number of - * DMA address/length pairs than there are SG table elements. - * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. - * - * Device ownership issues as mentioned above for pci_map_single are - * the same here. - */ -int -pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - return nents; -} - -/* - * Unmap a set of streaming mode DMA translations. - * Again, cpu read rules concerning calls here are the same as for - * pci_unmap_single() above. - */ -void -pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - /* Nothing to do */ -} -/* - * Make physical memory consistent for a single - * streaming mode DMA translation after a transfer. - * - * If you perform a pci_map_single() but wish to interrogate the - * buffer using the cpu, yet do not wish to teardown the PCI dma - * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, the - * device again owns the buffer. - */ -void -pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - /* Nothing to do */ -} - -/* - * Make physical memory consistent for a set of streaming mode DMA - * translations after a transfer. - * - * The same as pci_dma_sync_single but for a scatter-gather list, - * same rules and usage. - */ -void -pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - /* Nothing to do */ -} - -#endif /* CONFIG_SWIOTLB */ - -void * -pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) -{ - unsigned long pci_addr; - int gfp = GFP_ATOMIC; - void *ret; - - if (!hwdev || hwdev->dma_mask <= 0xffffffff) - gfp |= GFP_DMA; /* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */ - ret = (void *)__get_free_pages(gfp, get_order(size)); - if (!ret) - return NULL; - - memset(ret, 0, size); - pci_addr = virt_to_phys(ret); - if ((pci_addr & ~hwdev->dma_mask) != 0) - panic("pci_alloc_consistent: allocated memory is out of range for PCI device"); - *dma_handle = pci_addr; - return ret; -} - -void -pci_free_consistent (struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long) vaddr, get_order(size)); -} diff -urN linux-2.4.0-test12/arch/ia64/kernel/pci.c linux-2.4.0-test12-lia/arch/ia64/kernel/pci.c --- linux-2.4.0-test12/arch/ia64/kernel/pci.c Mon Aug 7 14:31:40 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/pci.c Wed Dec 6 22:23:15 2000 @@ -1,10 +1,8 @@ /* - * pci.c - Low-Level PCI Access in IA64 + * pci.c - Low-Level PCI Access in IA-64 * * Derived from bios32.c of i386 tree. - * */ - #include #include @@ -44,19 +42,16 @@ * This interrupt-safe spinlock protects all accesses to PCI * configuration space. */ - spinlock_t pci_lock = SPIN_LOCK_UNLOCKED; -struct pci_fixup pcibios_fixups[] = { { 0 } }; - -#define PCI_NO_CHECKS 0x400 -#define PCI_NO_PEER_FIXUP 0x800 - -static unsigned int pci_probe = PCI_NO_CHECKS; +struct pci_fixup pcibios_fixups[] = { + { 0 } +}; /* Macro to build a PCI configuration address to be passed as a parameter to SAL. */ -#define PCI_CONFIG_ADDRESS(dev, where) (((u64) dev->bus->number << 16) | ((u64) (dev->devfn & 0xff) << 8) | (where & 0xff)) +#define PCI_CONFIG_ADDRESS(dev, where) \ + (((u64) dev->bus->number << 16) | ((u64) (dev->devfn & 0xff) << 8) | (where & 0xff)) static int pci_conf_read_config_byte(struct pci_dev *dev, int where, u8 *value) @@ -109,8 +104,7 @@ return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS(dev, where), 4, value); } - -static struct pci_ops pci_conf = { +struct pci_ops pci_conf = { pci_conf_read_config_byte, pci_conf_read_config_word, pci_conf_read_config_dword, @@ -120,36 +114,21 @@ }; /* - * Try to find PCI BIOS. This will always work for IA64. - */ - -static struct pci_ops * __init -pci_find_bios(void) -{ - return &pci_conf; -} - -/* * Initialization. Uses the SAL interface */ - -#define PCI_BUSES_TO_SCAN 255 - void __init -pcibios_init(void) +pcibios_init (void) { - struct pci_ops *ops = NULL; +# define PCI_BUSES_TO_SCAN 255 int i; - if ((ops = pci_find_bios()) == NULL) { - printk("PCI: No PCI bus detected\n"); - return; - } + platform_pci_fixup(0); /* phase 0 initialization (before PCI bus has been scanned) */ printk("PCI: Probing PCI hardware\n"); for (i = 0; i < PCI_BUSES_TO_SCAN; i++) - pci_scan_bus(i, ops, NULL); - platform_pci_fixup(); + pci_scan_bus(i, &pci_conf, NULL); + + platform_pci_fixup(1); /* phase 1 initialization (after PCI bus has been scanned) */ return; } @@ -157,16 +136,15 @@ * Called after each bus is probed, but before its children * are examined. */ - void __init -pcibios_fixup_bus(struct pci_bus *b) +pcibios_fixup_bus (struct pci_bus *b) { return; } void __init -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) +pcibios_update_resource (struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) { unsigned long where, size; u32 reg; @@ -181,7 +159,7 @@ } void __init -pcibios_update_irq(struct pci_dev *dev, int irq) +pcibios_update_irq (struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); @@ -204,18 +182,16 @@ return 0; } +void +pcibios_align_resource (void *data, struct resource *res, unsigned long size) +{ +} + /* * PCI BIOS setup, always defaults to SAL interface */ - char * __init -pcibios_setup(char *str) +pcibios_setup (char *str) { - pci_probe = PCI_NO_CHECKS; return NULL; -} - -void -pcibios_align_resource (void *data, struct resource *res, unsigned long size) -{ } diff -urN linux-2.4.0-test12/arch/ia64/kernel/perfmon.c linux-2.4.0-test12-lia/arch/ia64/kernel/perfmon.c --- linux-2.4.0-test12/arch/ia64/kernel/perfmon.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/perfmon.c Mon Oct 30 22:37:23 2000 @@ -4,18 +4,20 @@ * * Originaly Written by Ganesh Venkitachalam, IBM Corp. * Modifications by David Mosberger-Tang, Hewlett-Packard Co. + * Modifications by Stephane Eranian, Hewlett-Packard Co. * Copyright (C) 1999 Ganesh Venkitachalam * Copyright (C) 1999 David Mosberger-Tang + * Copyright (C) 2000 Stephane Eranian */ #include + #include #include #include #include #include #include -#include #include #include @@ -58,19 +60,51 @@ #define MAX_PERF_COUNTER 4 /* true for Itanium, at least */ #define PMU_FIRST_COUNTER 4 /* first generic counter */ -#define WRITE_PMCS_AND_START 0xa0 -#define WRITE_PMCS 0xa1 -#define READ_PMDS 0xa2 -#define STOP_PMCS 0xa3 +#define PFM_WRITE_PMCS 0xa0 +#define PFM_WRITE_PMDS 0xa1 +#define PFM_READ_PMDS 0xa2 +#define PFM_STOP 0xa3 +#define PFM_START 0xa4 +#define PFM_ENABLE 0xa5 /* unfreeze only */ +#define PFM_DISABLE 0xa6 /* freeze only */ +/* + * Those 2 are just meant for debugging. I considered using sysctl() for + * that but it is a little bit too pervasive. This solution is at least + * self-contained. + */ +#define PFM_DEBUG_ON 0xe0 +#define PFM_DEBUG_OFF 0xe1 + +#ifdef CONFIG_SMP +#define cpu_is_online(i) (cpu_online_map & (1UL << i)) +#else +#define cpu_is_online(i) 1 +#endif +#define PMC_IS_IMPL(i) (pmu_conf.impl_regs[i>>6] & (1<< (i&~(64-1)))) +#define PMD_IS_IMPL(i) (pmu_conf.impl_regs[4+(i>>6)] & (1<< (i&~(64-1)))) +#define PMD_IS_COUNTER(i) (i>=PMU_FIRST_COUNTER && i < (PMU_FIRST_COUNTER+pmu_conf.max_counters)) +#define PMC_IS_COUNTER(i) (i>=PMU_FIRST_COUNTER && i < (PMU_FIRST_COUNTER+pmu_conf.max_counters)) /* * this structure needs to be enhanced */ typedef struct { + unsigned long pfr_reg_num; /* which register */ + unsigned long pfr_reg_value; /* configuration (PMC) or initial value (PMD) */ + unsigned long pfr_reg_reset; /* reset value on overflow (PMD) */ + void *pfr_smpl_buf; /* pointer to user buffer for EAR/BTB */ + unsigned long pfr_smpl_size; /* size of user buffer for EAR/BTB */ + pid_t pfr_notify_pid; /* process to notify */ + int pfr_notify_sig; /* signal for notification, 0=no notification */ +} perfmon_req_t; + +#if 0 +typedef struct { unsigned long pmu_reg_data; /* generic PMD register */ unsigned long pmu_reg_num; /* which register number */ } perfmon_reg_t; +#endif /* * This structure is initialize at boot time and contains @@ -78,86 +112,141 @@ * by PAL */ typedef struct { - unsigned long perf_ovfl_val; /* overflow value for generic counters */ - unsigned long max_pmc; /* highest PMC */ - unsigned long max_pmd; /* highest PMD */ - unsigned long max_counters; /* number of generic counter pairs (PMC/PMD) */ + unsigned long perf_ovfl_val; /* overflow value for generic counters */ + unsigned long max_counters; /* upper limit on counter pair (PMC/PMD) */ + unsigned long impl_regs[16]; /* buffer used to hold implememted PMC/PMD mask */ } pmu_config_t; -/* XXX will go static when ptrace() is cleaned */ -unsigned long perf_ovfl_val; /* overflow value for generic counters */ - static pmu_config_t pmu_conf; +/* for debug only */ +static unsigned long pfm_debug=1; /* 0= nodebug, >0= debug output on */ +#define DBprintk(a) {\ + if (pfm_debug >0) { printk a; } \ +} + /* - * could optimize to avoid cache conflicts in SMP + * could optimize to avoid cache line conflicts in SMP */ -unsigned long pmds[NR_CPUS][MAX_PERF_COUNTER]; +static struct task_struct *pmu_owners[NR_CPUS]; -asmlinkage unsigned long -sys_perfmonctl (int cmd, int count, void *ptr, long arg4, long arg5, long arg6, long arg7, long arg8, long stack) +static int +do_perfmonctl (struct task_struct *task, int cmd, int flags, perfmon_req_t *req, int count, struct pt_regs *regs) { - struct pt_regs *regs = (struct pt_regs *) &stack; - perfmon_reg_t tmp, *cptr = ptr; - unsigned long cnum; + perfmon_req_t tmp; int i; switch (cmd) { - case WRITE_PMCS: /* Writes to PMC's and clears PMDs */ - case WRITE_PMCS_AND_START: /* Also starts counting */ + case PFM_WRITE_PMCS: + /* we don't quite support this right now */ + if (task != current) return -EINVAL; + + if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT; + + for (i = 0; i < count; i++, req++) { + copy_from_user(&tmp, req, sizeof(tmp)); + + /* XXX needs to check validity of the data maybe */ + + if (!PMC_IS_IMPL(tmp.pfr_reg_num)) { + DBprintk((__FUNCTION__ " invalid pmc[%ld]\n", tmp.pfr_reg_num)); + return -EINVAL; + } + + /* XXX: for counters, need to some checks */ + if (PMC_IS_COUNTER(tmp.pfr_reg_num)) { + current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].sig = tmp.pfr_notify_sig; + current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].pid = tmp.pfr_notify_pid; + + DBprintk((__FUNCTION__" setting PMC[%ld] send sig %d to %d\n",tmp.pfr_reg_num, tmp.pfr_notify_sig, tmp.pfr_notify_pid)); + } + ia64_set_pmc(tmp.pfr_reg_num, tmp.pfr_reg_value); + + DBprintk((__FUNCTION__" setting PMC[%ld]=0x%lx\n", tmp.pfr_reg_num, tmp.pfr_reg_value)); + } + /* + * we have to set this here event hough we haven't necessarily started monitoring + * because we may be context switched out + */ + current->thread.flags |= IA64_THREAD_PM_VALID; + break; + + case PFM_WRITE_PMDS: + /* we don't quite support this right now */ + if (task != current) return -EINVAL; + + if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT; + + for (i = 0; i < count; i++, req++) { + copy_from_user(&tmp, req, sizeof(tmp)); + + if (!PMD_IS_IMPL(tmp.pfr_reg_num)) return -EINVAL; + + /* update virtualized (64bits) counter */ + if (PMD_IS_COUNTER(tmp.pfr_reg_num)) { + current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].val = tmp.pfr_reg_value & ~pmu_conf.perf_ovfl_val; + current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].rval = tmp.pfr_reg_reset; + } + /* writes to unimplemented part is ignored, so this is safe */ + ia64_set_pmd(tmp.pfr_reg_num, tmp.pfr_reg_value); + /* to go away */ + ia64_srlz_d(); + DBprintk((__FUNCTION__" setting PMD[%ld]: pmod.val=0x%lx pmd=0x%lx rval=0x%lx\n", tmp.pfr_reg_num, current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].val, ia64_get_pmd(tmp.pfr_reg_num),current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].rval)); + } + /* + * we have to set this here event hough we haven't necessarily started monitoring + * because we may be context switched out + */ + current->thread.flags |= IA64_THREAD_PM_VALID; + break; + + case PFM_START: + /* we don't quite support this right now */ + if (task != current) return -EINVAL; - if (!access_ok(VERIFY_READ, cptr, sizeof(struct perfmon_reg_t)*count)) - return -EFAULT; + pmu_owners[smp_processor_id()] = current; - for (i = 0; i < count; i++, cptr++) { + /* will start monitoring right after rfi */ + ia64_psr(regs)->up = 1; - copy_from_user(&tmp, cptr, sizeof(tmp)); + /* + * mark the state as valid. + * this will trigger save/restore at context switch + */ + current->thread.flags |= IA64_THREAD_PM_VALID; - /* XXX need to check validity of pmu_reg_num and perhaps data!! */ + ia64_set_pmc(0, 0); - if (tmp.pmu_reg_num > pmu_conf.max_pmc || tmp.pmu_reg_num == 0) return -EFAULT; + break; - ia64_set_pmc(tmp.pmu_reg_num, tmp.pmu_reg_data); + case PFM_ENABLE: + /* we don't quite support this right now */ + if (task != current) return -EINVAL; - /* to go away */ - if (tmp.pmu_reg_num >= PMU_FIRST_COUNTER && tmp.pmu_reg_num < PMU_FIRST_COUNTER+pmu_conf.max_counters) { - ia64_set_pmd(tmp.pmu_reg_num, 0); - pmds[smp_processor_id()][tmp.pmu_reg_num - PMU_FIRST_COUNTER] = 0; + pmu_owners[smp_processor_id()] = current; - printk(__FUNCTION__" setting PMC/PMD[%ld] es=0x%lx pmd[%ld]=%lx\n", tmp.pmu_reg_num, (tmp.pmu_reg_data>>8) & 0x7f, tmp.pmu_reg_num, ia64_get_pmd(tmp.pmu_reg_num)); - } else - printk(__FUNCTION__" setting PMC[%ld]=0x%lx\n", tmp.pmu_reg_num, tmp.pmu_reg_data); - } - - if (cmd == WRITE_PMCS_AND_START) { -#if 0 -/* irrelevant with user monitors */ - local_irq_save(flags); - - dcr = ia64_get_dcr(); - dcr |= IA64_DCR_PP; - ia64_set_dcr(dcr); - - local_irq_restore(flags); -#endif + /* + * mark the state as valid. + * this will trigger save/restore at context switch + */ + current->thread.flags |= IA64_THREAD_PM_VALID; + /* simply unfreeze */ ia64_set_pmc(0, 0); + break; - /* will start monitoring right after rfi */ - ia64_psr(regs)->up = 1; - } - /* - * mark the state as valid. - * this will trigger save/restore at context switch - */ - current->thread.flags |= IA64_THREAD_PM_VALID; - break; - - case READ_PMDS: - if (count <= 0 || count > MAX_PERF_COUNTER) - return -EINVAL; - if (!access_ok(VERIFY_WRITE, cptr, sizeof(struct perfmon_reg_t)*count)) - return -EFAULT; + case PFM_DISABLE: + /* we don't quite support this right now */ + if (task != current) return -EINVAL; + + /* simply unfreeze */ + ia64_set_pmc(0, 1); + ia64_srlz_d(); + break; + + case PFM_READ_PMDS: + if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT; + if (!access_ok(VERIFY_WRITE, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT; /* This looks shady, but IMHO this will work fine. This is * the sequence that I could come up with to avoid races @@ -187,16 +276,31 @@ * is the irq_save/restore needed? */ + for (i = 0; i < count; i++, req++) { + unsigned long val=0; - /* XXX: This needs to change to read more than just the counters */ - for (i = 0, cnum = PMU_FIRST_COUNTER;i < count; i++, cnum++, cptr++) { + copy_from_user(&tmp, req, sizeof(tmp)); - tmp.pmu_reg_data = (pmds[smp_processor_id()][i] - + (ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val)); + if (!PMD_IS_IMPL(tmp.pfr_reg_num)) return -EINVAL; - tmp.pmu_reg_num = cnum; + if (PMD_IS_COUNTER(tmp.pfr_reg_num)) { + if (task == current){ + val = ia64_get_pmd(tmp.pfr_reg_num) & pmu_conf.perf_ovfl_val; + } else { + val = task->thread.pmd[tmp.pfr_reg_num - PMU_FIRST_COUNTER] & pmu_conf.perf_ovfl_val; + } + val += task->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].val; + } else { + /* for now */ + if (task != current) return -EINVAL; + + val = ia64_get_pmd(tmp.pfr_reg_num); + } + tmp.pfr_reg_value = val; - if (copy_to_user(cptr, &tmp, sizeof(tmp))) return -EFAULT; +DBprintk((__FUNCTION__" reading PMD[%ld]=0x%lx\n", tmp.pfr_reg_num, val)); + + if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT; } #if 0 /* irrelevant with user monitors */ @@ -209,11 +313,18 @@ #endif break; - case STOP_PMCS: + case PFM_STOP: + /* we don't quite support this right now */ + if (task != current) return -EINVAL; + ia64_set_pmc(0, 1); ia64_srlz_d(); - for (i = 0; i < MAX_PERF_COUNTER; ++i) - ia64_set_pmc(4+i, 0); + + ia64_psr(regs)->up = 0; + + current->thread.flags &= ~IA64_THREAD_PM_VALID; + + pmu_owners[smp_processor_id()] = NULL; #if 0 /* irrelevant with user monitors */ @@ -225,48 +336,140 @@ ia64_psr(regs)->up = 0; #endif - current->thread.flags &= ~(IA64_THREAD_PM_VALID); - break; + case PFM_DEBUG_ON: + printk(__FUNCTION__" debuggin on\n"); + pfm_debug = 1; + break; + + case PFM_DEBUG_OFF: + printk(__FUNCTION__" debuggin off\n"); + pfm_debug = 0; + break; + default: + DBprintk((__FUNCTION__" UNknown command 0x%x\n", cmd)); return -EINVAL; break; } return 0; } -static inline void -update_counters (void) +asmlinkage int +sys_perfmonctl (int pid, int cmd, int flags, perfmon_req_t *req, int count, long arg6, long arg7, long arg8, long stack) { - unsigned long mask, i, cnum, val; + struct pt_regs *regs = (struct pt_regs *) &stack; + struct task_struct *child = current; + int ret; - mask = ia64_get_pmc(0) >> 4; - for (i = 0, cnum = PMU_FIRST_COUNTER ; i < pmu_conf.max_counters; cnum++, i++, mask >>= 1) { + if (pid != current->pid) { + read_lock(&tasklist_lock); + { + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + } + if (!child) { + read_unlock(&tasklist_lock); + return -ESRCH; + } + /* + * XXX: need to do more checking here + */ + if (child->state != TASK_ZOMBIE) { + DBprintk((__FUNCTION__" warning process %d not in stable state %ld\n", pid, child->state)); + } + } + ret = do_perfmonctl(child, cmd, flags, req, count, regs); + if (child != current) read_unlock(&tasklist_lock); - val = mask & 0x1 ? pmu_conf.perf_ovfl_val + 1 : 0; + return ret; +} - if (mask & 0x1) - printk(__FUNCTION__ " PMD%ld overflowed pmd=%lx pmod=%lx\n", cnum, ia64_get_pmd(cnum), pmds[smp_processor_id()][i]); - /* since we got an interrupt, might as well clear every pmd. */ - val += ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val; +static inline int +update_counters (u64 pmc0) +{ + unsigned long mask, i, cnum; + struct thread_struct *th; + struct task_struct *ta; + + if (pmu_owners[smp_processor_id()] == NULL) { + DBprintk((__FUNCTION__" Spurious overflow interrupt: PMU not owned\n")); + return 0; + } + + /* + * It is never safe to access the task for which the overflow interrupt is destinated + * using the current variable as the interrupt may occur in the middle of a context switch + * where current does not hold the task that is running yet. + * + * For monitoring, however, we do need to get access to the task which caused the overflow + * to account for overflow on the counters. + * We accomplish this by maintaining a current owner of the PMU per CPU. During context + * switch the ownership is changed in a way such that the reflected owner is always the + * valid one, i.e. the one that caused the interrupt. + */ + ta = pmu_owners[smp_processor_id()]; + th = &pmu_owners[smp_processor_id()]->thread; - printk(__FUNCTION__ " adding val=%lx to pmod[%ld]=%lx \n", val, i, pmds[smp_processor_id()][i]); + /* + * Don't think this could happen given first test. Keep as sanity check + */ + if ((th->flags & IA64_THREAD_PM_VALID) == 0) { + DBprintk((__FUNCTION__" Spurious overflow interrupt: process %d not using perfmon\n", ta->pid)); + return 0; + } + + /* + * if PMU not frozen: spurious from previous context + * if PMC[0] = 0x1 : frozen but no overflow reported: leftover from previous context + * + * in either case we don't touch the state upon return from handler + */ + if ((pmc0 & 0x1) == 0 || pmc0 == 0x1) { + DBprintk((__FUNCTION__" Spurious overflow interrupt: process %d freeze=0\n",ta->pid)); + return 0; + } - pmds[smp_processor_id()][i] += val; + mask = pmc0 >> 4; - ia64_set_pmd(cnum, 0); + for (i = 0, cnum = PMU_FIRST_COUNTER; i < pmu_conf.max_counters; cnum++, i++, mask >>= 1) { + + if (mask & 0x1) { + DBprintk((__FUNCTION__ " PMD[%ld] overflowed pmd=0x%lx pmod.val=0x%lx\n", cnum, ia64_get_pmd(cnum), th->pmu_counters[i].val)); + + /* + * Because we somtimes (EARS/BTB) reset to a specific value, we cannot simply use + * val to count the number of times we overflowed. Otherwise we would loose the value + * current in the PMD (which can be >0). So to make sure we don't loose + * the residual counts we set val to contain full 64bits value of the counter. + */ + th->pmu_counters[i].val += 1+pmu_conf.perf_ovfl_val+(ia64_get_pmd(cnum) &pmu_conf.perf_ovfl_val); + + /* writes to upper part are ignored, so this is safe */ + ia64_set_pmd(cnum, th->pmu_counters[i].rval); + + DBprintk((__FUNCTION__ " pmod[%ld].val=0x%lx pmd=0x%lx\n", i, th->pmu_counters[i].val, ia64_get_pmd(cnum)&pmu_conf.perf_ovfl_val)); + + if (th->pmu_counters[i].pid != 0 && th->pmu_counters[i].sig>0) { + DBprintk((__FUNCTION__ " shouild notify process %d with signal %d\n",th->pmu_counters[i].pid, th->pmu_counters[i].sig)); + } + } } + return 1; } static void perfmon_interrupt (int irq, void *arg, struct pt_regs *regs) { - update_counters(); - ia64_set_pmc(0, 0); - ia64_srlz_d(); + /* unfreeze if not spurious */ + if ( update_counters(ia64_get_pmc(0)) ) { + ia64_set_pmc(0, 0); + ia64_srlz_d(); + } } static struct irqaction perfmon_irqaction = { @@ -280,9 +483,13 @@ { char *p = page; u64 pmc0 = ia64_get_pmc(0); + int i; - p += sprintf(p, "PMC[0]=%lx\n", pmc0); - + p += sprintf(p, "PMC[0]=%lx\nPerfmon debug: %s\n", pmc0, pfm_debug ? "On" : "Off"); + for(i=0; i < NR_CPUS; i++) { + if (cpu_is_online(i)) + p += sprintf(p, "CPU%d.PMU %d\n", i, pmu_owners[i] ? pmu_owners[i]->pid: -1); + } return p - page; } @@ -308,7 +515,6 @@ perfmon_init (void) { pal_perf_mon_info_u_t pm_info; - u64 pm_buffer[16]; s64 status; irq_desc[PERFMON_IRQ].status |= IRQ_PER_CPU; @@ -320,15 +526,13 @@ printk("perfmon: Initialized vector to %u\n",PERFMON_IRQ); - if ((status=ia64_pal_perf_mon_info(pm_buffer, &pm_info)) != 0) { + if ((status=ia64_pal_perf_mon_info(pmu_conf.impl_regs, &pm_info)) != 0) { printk(__FUNCTION__ " pal call failed (%ld)\n", status); return; } - pmu_conf.perf_ovfl_val = perf_ovfl_val = (1L << pm_info.pal_perf_mon_info_s.width) - 1; + pmu_conf.perf_ovfl_val = (1L << pm_info.pal_perf_mon_info_s.width) - 1; /* XXX need to use PAL instead */ - pmu_conf.max_pmc = 13; - pmu_conf.max_pmd = 17; pmu_conf.max_counters = pm_info.pal_perf_mon_info_s.generic; printk("perfmon: Counters are %d bits\n", pm_info.pal_perf_mon_info_s.width); @@ -347,36 +551,137 @@ ia64_srlz_d(); } +/* + * XXX: for system wide this function MUST never be called + */ void -ia64_save_pm_regs (struct thread_struct *t) +ia64_save_pm_regs (struct task_struct *ta) { - int i; + struct thread_struct *t = &ta->thread; + u64 pmc0, psr; + int i,j; + + /* + * We must maek sure that we don't loose any potential overflow + * interrupt while saving PMU context. In this code, external + * interrupts are always enabled. + */ + + /* + * save current PSR: needed because we modify it + */ + __asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory"); + + /* + * stop monitoring: + * This is the only way to stop monitoring without destroying overflow + * information in PMC[0..3]. + * This is the last instruction which can cause overflow when monitoring + * in kernel. + * By now, we could still have an overflow interrupt in flight. + */ + __asm__ __volatile__ ("rsm psr.up;;"::: "memory"); + + /* + * read current overflow status: + * + * We may be reading stale information at this point, if we got interrupt + * just before the read(pmc0) but that's all right. However, if we did + * not get the interrupt before, this read reflects LAST state. + * + */ + pmc0 = ia64_get_pmc(0); + /* + * freeze PMU: + * + * This destroys the overflow information. This is required to make sure + * next process does not start with monitoring on if not requested + * (PSR.up may not be enough). + * + * We could still get an overflow interrupt by now. However the handler + * will not do anything if is sees PMC[0].fr=1 but no overflow bits + * are set. So PMU will stay in frozen state. This implies that pmc0 + * will still be holding the correct unprocessed information. + * + */ ia64_set_pmc(0, 1); ia64_srlz_d(); + + /* + * check for overflow bits set: + * + * If pmc0 reports PMU frozen, this means we have a pending overflow, + * therefore we invoke the handler. Handler is reentrant with regards + * to PMC[0] so it is safe to call it twice. + * + * IF pmc0 reports overflow, we need to reread current PMC[0] value + * in case the handler was invoked right after the first pmc0 read. + * it is was not invoked then pmc0==PMC[0], otherwise it's been invoked + * and overflow information has been processed, so we don't need to call. + * + * Test breakdown: + * - pmc0 & ~0x1: test if overflow happened + * - second part: check if current register reflects this as well. + * + * NOTE: testing for pmc0 & 0x1 is not enough has it would trigger call + * when PM_VALID and PMU.fr which is common when setting up registers + * just before actually starting monitors. + * + */ + if ((pmc0 & ~0x1) && ((pmc0=ia64_get_pmc(0)) &~0x1) ) { + printk(__FUNCTION__" Warning: pmc[0]=0x%lx\n", pmc0); + update_counters(pmc0); + /* + * XXX: not sure that's enough. the next task may still get the + * interrupt. + */ + } + + /* + * restore PSR for context switch to save + */ + __asm__ __volatile__ ("mov psr.l=%0;;"::"r"(psr): "memory"); + /* * XXX: this will need to be extended beyong just counters */ - for (i=0; i< IA64_NUM_PM_REGS; i++) { - t->pmd[i] = ia64_get_pmd(4+i); - t->pmod[i] = pmds[smp_processor_id()][i]; - t->pmc[i] = ia64_get_pmc(4+i); + for (i=0,j=4; i< IA64_NUM_PMD_COUNTERS; i++,j++) { + t->pmd[i] = ia64_get_pmd(j); + t->pmc[i] = ia64_get_pmc(j); } + /* + * PMU is frozen, PMU context is saved: nobody owns the PMU on this CPU + * At this point, we should not receive any pending interrupt from the + * 'switched out' task + */ + pmu_owners[smp_processor_id()] = NULL; } void -ia64_load_pm_regs (struct thread_struct *t) +ia64_load_pm_regs (struct task_struct *ta) { - int i; + struct thread_struct *t = &ta->thread; + int i,j; + + /* + * we first restore ownership of the PMU to the 'soon to be current' + * context. This way, if, as soon as we unfreeze the PMU at the end + * of this function, we get an interrupt, we attribute it to the correct + * task + */ + pmu_owners[smp_processor_id()] = ta; /* * XXX: this will need to be extended beyong just counters */ - for (i=0; i< IA64_NUM_PM_REGS ; i++) { - ia64_set_pmd(4+i, t->pmd[i]); - pmds[smp_processor_id()][i] = t->pmod[i]; - ia64_set_pmc(4+i, t->pmc[i]); + for (i=0,j=4; i< IA64_NUM_PMD_COUNTERS; i++,j++) { + ia64_set_pmd(j, t->pmd[i]); + ia64_set_pmc(j, t->pmc[i]); } + /* + * unfreeze PMU + */ ia64_set_pmc(0, 0); ia64_srlz_d(); } diff -urN linux-2.4.0-test12/arch/ia64/kernel/process.c linux-2.4.0-test12-lia/arch/ia64/kernel/process.c --- linux-2.4.0-test12/arch/ia64/kernel/process.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/process.c Mon Oct 30 22:38:03 2000 @@ -164,7 +164,7 @@ ia64_save_debug_regs(&task->thread.dbr[0]); #ifdef CONFIG_PERFMON if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) - ia64_save_pm_regs(&task->thread); + ia64_save_pm_regs(task); #endif if (IS_IA32_PROCESS(ia64_task_regs(task))) ia32_save_state(&task->thread); @@ -177,7 +177,7 @@ ia64_load_debug_regs(&task->thread.dbr[0]); #ifdef CONFIG_PERFMON if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) - ia64_load_pm_regs(&task->thread); + ia64_load_pm_regs(task); #endif if (IS_IA32_PROCESS(ia64_task_regs(task))) ia32_load_state(&task->thread); @@ -299,6 +299,14 @@ # define THREAD_FLAGS_TO_SET 0 p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR) | THREAD_FLAGS_TO_SET); +#ifdef CONFIG_IA32_SUPPORT + /* + * If we're cloning an IA32 task then save the IA32 extra + * state from the current task to the new task + */ + if (IS_IA32_PROCESS(ia64_task_regs(current))) + ia32_save_state(&p->thread); +#endif return 0; } @@ -554,7 +562,7 @@ * we garantee no race. this call we also stop * monitoring */ - ia64_save_pm_regs(¤t->thread); + ia64_save_pm_regs(current); /* * make sure that switch_to() will not save context again */ diff -urN linux-2.4.0-test12/arch/ia64/kernel/ptrace.c linux-2.4.0-test12-lia/arch/ia64/kernel/ptrace.c --- linux-2.4.0-test12/arch/ia64/kernel/ptrace.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/ptrace.c Wed Nov 15 17:58:36 2000 @@ -617,7 +617,6 @@ struct switch_stack *sw; struct unw_frame_info info; struct pt_regs *pt; - unsigned long pmd_tmp; pt = ia64_task_regs(child); sw = (struct switch_stack *) (child->thread.ksp + 16); @@ -794,11 +793,7 @@ addr); return -1; } - } else -#ifdef CONFIG_PERFMON - if (addr < PT_PMD) -#endif - { + } else { /* access debug registers */ if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) { @@ -820,33 +815,14 @@ } ptr += regnum; - } -#ifdef CONFIG_PERFMON - else { - /* - * XXX: will eventually move back to perfmonctl() - */ - unsigned long pmd = (addr - PT_PMD) >> 3; - extern unsigned long perf_ovfl_val; - - /* we just use ptrace to read */ - if (write_access) return -1; - - if (pmd > 3) { - printk("ptrace: rejecting access to PMD[%ld] address 0x%lx\n", pmd, addr); - return -1; - } - /* - * We always need to mask upper 32bits of pmd because value is random - */ - pmd_tmp = child->thread.pmod[pmd]+(child->thread.pmd[pmd]& perf_ovfl_val); - - /*printk(__FUNCTION__" child=%d reading pmd[%ld]=%lx\n", child->pid, pmd, pmd_tmp);*/ - - ptr = &pmd_tmp; + if (write_access) + /* don't let the user set kernel-level breakpoints... */ + *ptr = *data & ~(7UL << 56); + else + *data = *ptr; + return 0; } -#endif if (write_access) *ptr = *data; else @@ -861,7 +837,6 @@ { unsigned long *ptr = NULL, *rbs, *bspstore, ndirty, regnum; struct switch_stack *sw; - unsigned long pmd_tmp; struct pt_regs *pt; if ((addr & 0x7) != 0) @@ -977,11 +952,7 @@ /* disallow accessing anything else... */ return -1; } - } else -#ifdef CONFIG_PERFMON - if (addr < PT_PMD) -#endif - { + } else { /* access debug registers */ @@ -1002,34 +973,14 @@ return -1; ptr += regnum; - } -#ifdef CONFIG_PERFMON - else { - /* - * XXX: will eventually move back to perfmonctl() - */ - unsigned long pmd = (addr - PT_PMD) >> 3; - extern unsigned long perf_ovfl_val; - /* we just use ptrace to read */ - if (write_access) return -1; - - if (pmd > 3) { - printk("ptrace: rejecting access to PMD[%ld] address 0x%lx\n", pmd, addr); - return -1; - } - - /* - * We always need to mask upper 32bits of pmd because value is random - */ - pmd_tmp = child->thread.pmod[pmd]+(child->thread.pmd[pmd]& perf_ovfl_val); - - /*printk(__FUNCTION__" child=%d reading pmd[%ld]=%lx\n", child->pid, pmd, pmd_tmp);*/ - - ptr = &pmd_tmp; + if (write_access) + /* don't let the user set kernel-level breakpoints... */ + *ptr = *data & ~(7UL << 56); + else + *data = *ptr; + return 0; } -#endif - if (write_access) *ptr = *data; else @@ -1107,7 +1058,7 @@ goto out_tsk; if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL && request != PTRACE_PEEKUSR) + if (request != PTRACE_KILL) goto out_tsk; } diff -urN linux-2.4.0-test12/arch/ia64/kernel/sal.c linux-2.4.0-test12-lia/arch/ia64/kernel/sal.c --- linux-2.4.0-test12/arch/ia64/kernel/sal.c Mon Oct 9 17:54:54 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/sal.c Wed Nov 15 17:58:45 2000 @@ -104,9 +104,11 @@ if (strncmp(systab->signature, "SST_", 4) != 0) printk("bad signature in system table!"); - printk("SAL v%u.%02u: ia32bios=%s, oem=%.32s, product=%.32s\n", + /* + * revisions are coded in BCD, so %x does the job for us + */ + printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n", systab->sal_rev_major, systab->sal_rev_minor, - systab->ia32_bios_present ? "present" : "absent", systab->oem_id, systab->product_id); min = ~0UL; diff -urN linux-2.4.0-test12/arch/ia64/kernel/setup.c linux-2.4.0-test12-lia/arch/ia64/kernel/setup.c --- linux-2.4.0-test12/arch/ia64/kernel/setup.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/setup.c Thu Dec 14 14:12:41 2000 @@ -235,6 +235,12 @@ machvec_init(acpi_get_sysname()); #endif +#ifdef CONFIG_ACPI20 + if (efi.acpi20) { + /* Parse the ACPI 2.0 tables */ + acpi20_parse(efi.acpi20); + } else +#endif if (efi.acpi) { /* Parse the ACPI tables */ acpi_parse(efi.acpi); @@ -255,13 +261,6 @@ paging_init(); platform_setup(cmdline_p); - -#ifdef CONFIG_SWIOTLB - { - extern void setup_swiotlb (void); - setup_swiotlb(); - } -#endif } /* @@ -376,15 +375,7 @@ status = ia64_pal_vm_summary(&vm1, &vm2); if (status == PAL_STATUS_SUCCESS) { -#if 1 - /* - * XXX the current PAL code returns IMPL_VA_MSB==60, which is dead-wrong. - * --davidm 00/05/26 - s*/ - impl_va_msb = 50; -#else impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb; -#endif phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size; } printk("CPU %d: %lu virtual and %lu physical address bits\n", @@ -408,6 +399,8 @@ { extern void __init ia64_rid_init (void); extern void __init ia64_tlb_init (void); + pal_vm_info_2_u_t vmi; + unsigned int max_ctx; identify_cpu(&my_cpu_data); @@ -415,15 +408,12 @@ memset(ia64_task_regs(current), 0, sizeof(struct pt_regs)); /* - * Initialize default control register to defer speculative - * faults. On a speculative load, we want to defer access - * right, key miss, and key permission faults. We currently - * do NOT defer TLB misses, page-not-present, access bit, or - * debug faults but kernel code should not rely on any - * particular setting of these bits. - ia64_set_dcr(IA64_DCR_DR | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_PP); + * Initialize default control register to defer all speculative faults. The + * kernel MUST NOT depend on a particular setting of these bits (in other words, + * the kernel must have recovery code for all speculative accesses). */ - ia64_set_dcr(IA64_DCR_DR | IA64_DCR_DK | IA64_DCR_DX ); + ia64_set_dcr( IA64_DCR_DM | IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR + | IA64_DCR_DA | IA64_DCR_DD); #ifndef CONFIG_SMP ia64_set_fpu_owner(0); /* initialize ar.k5 */ #endif @@ -444,4 +434,17 @@ #ifdef CONFIG_SMP normal_xtp(); #endif + + /* set ia64_ctx.max_rid to the maximum RID that is supported by all CPUs: */ + if (ia64_pal_vm_summary(NULL, &vmi) == 0) + max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1; + else { + printk("ia64_rid_init: PAL VM summary failed, assuming 18 RID bits\n"); + max_ctx = (1U << 15) - 1; /* use architected minimum */ + } + while (max_ctx < ia64_ctx.max_ctx) { + unsigned int old = ia64_ctx.max_ctx; + if (cmpxchg(&ia64_ctx.max_ctx, old, max_ctx) == old) + break; + } } diff -urN linux-2.4.0-test12/arch/ia64/kernel/signal.c linux-2.4.0-test12-lia/arch/ia64/kernel/signal.c --- linux-2.4.0-test12/arch/ia64/kernel/signal.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/signal.c Wed Nov 15 18:03:14 2000 @@ -91,7 +91,7 @@ scr->pt.r10 = -1; } while (1) { - set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; schedule(); if (ia64_do_signal(&oldset, scr, 1)) return -EINTR; @@ -499,9 +499,10 @@ /* Let the debugger run. */ current->exit_code = signr; current->thread.siginfo = &info; - set_current_state(TASK_STOPPED); + current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); + signr = current->exit_code; current->thread.siginfo = 0; @@ -557,7 +558,7 @@ /* FALLTHRU */ case SIGSTOP: - set_current_state(TASK_STOPPED); + current->state = TASK_STOPPED; current->exit_code = signr; if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) diff -urN linux-2.4.0-test12/arch/ia64/kernel/smp.c linux-2.4.0-test12-lia/arch/ia64/kernel/smp.c --- linux-2.4.0-test12/arch/ia64/kernel/smp.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/smp.c Thu Dec 14 20:11:27 2000 @@ -11,6 +11,8 @@ * 00/03/31 Rohit Seth Fixes for Bootstrap Processor & cpu_online_map * now gets done here (instead of setup.c) * 99/10/05 davidm Update to bring it in sync with new command-line processing scheme. + * 10/13/00 Goutham Rao Updated smp_call_function and + * smp_call_function_single to resend IPI on timeouts */ #define __KERNEL_SYSCALLS__ @@ -30,6 +32,7 @@ #include #include #include +#include #include #include @@ -78,10 +81,6 @@ }; static volatile struct smp_call_struct *smp_call_function_data; -#ifdef CONFIG_ITANIUM_A1_SPECIFIC -extern spinlock_t ivr_read_lock; -#endif - #define IPI_RESCHEDULE 0 #define IPI_CALL_FUNC 1 #define IPI_CPU_STOP 2 @@ -276,7 +275,7 @@ return; set_bit(op, &ipi_op[dest_cpu]); - ipi_send(dest_cpu, IPI_IRQ, IA64_IPI_DM_INT, 0); + platform_send_ipi(dest_cpu, IPI_IRQ, IA64_IPI_DM_INT, 0); } static inline void @@ -358,6 +357,7 @@ if (pointer_lock(&smp_call_function_data, &data, retry)) return -EBUSY; +resend: /* Send a message to all other CPUs and wait for them to respond */ send_IPI_single(cpuid, IPI_CALL_FUNC); @@ -366,8 +366,12 @@ while ((atomic_read(&data.unstarted_count) > 0) && time_before(jiffies, timeout)) barrier(); if (atomic_read(&data.unstarted_count) > 0) { +#if (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) + goto resend; +#else smp_call_function_data = NULL; return -ETIMEDOUT; +#endif } if (wait) while (atomic_read(&data.unfinished_count) > 0) @@ -411,13 +415,23 @@ /* Send a message to all other CPUs and wait for them to respond */ send_IPI_allbutself(IPI_CALL_FUNC); +retry: /* Wait for response */ timeout = jiffies + HZ; while ((atomic_read(&data.unstarted_count) > 0) && time_before(jiffies, timeout)) barrier(); if (atomic_read(&data.unstarted_count) > 0) { +#if (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) + int i; + for (i = 0; i < smp_num_cpus; i++) { + if (i != smp_processor_id()) + platform_send_ipi(i, IPI_IRQ, IA64_IPI_DM_INT, 0); + } + goto retry; +#else smp_call_function_data = NULL; return -ETIMEDOUT; +#endif } if (wait) while (atomic_read(&data.unfinished_count) > 0) @@ -569,7 +583,7 @@ cpu_now_booting = cpu; /* Kick the AP in the butt */ - ipi_send(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0); + platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0); /* wait up to 10s for the AP to start */ for (timeout = 0; timeout < 100000; timeout++) { diff -urN linux-2.4.0-test12/arch/ia64/kernel/smpboot.c linux-2.4.0-test12-lia/arch/ia64/kernel/smpboot.c --- linux-2.4.0-test12/arch/ia64/kernel/smpboot.c Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/smpboot.c Mon Oct 30 22:17:11 2000 @@ -4,6 +4,8 @@ * Application processor startup code, moved from smp.c to better support kernel profile */ +#include + #include #include #include diff -urN linux-2.4.0-test12/arch/ia64/kernel/sys_ia64.c linux-2.4.0-test12-lia/arch/ia64/kernel/sys_ia64.c --- linux-2.4.0-test12/arch/ia64/kernel/sys_ia64.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/sys_ia64.c Wed Dec 6 22:24:07 2000 @@ -95,10 +95,10 @@ static inline unsigned long do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff) { - unsigned long loff, hoff; + unsigned long roff; struct file *file = 0; /* the virtual address space that is mappable in each region: */ -# define OCTANT_SIZE ((PTRS_PER_PGD<= OCTANT_SIZE/2 - && (len | hoff | (hoff + len)) >= OCTANT_SIZE/2) + /* don't permit mappings into unmapped space or the virtual page table of a region: */ + roff = rgn_offset(addr); + if ((len | roff | (roff + len)) >= OCTANT_SIZE) return -EINVAL; - /* Don't permit mappings that would cross a region boundary: */ - + /* don't permit mappings that would cross a region boundary: */ if (rgn_index(addr) != rgn_index(addr + len)) return -EINVAL; diff -urN linux-2.4.0-test12/arch/ia64/kernel/time.c linux-2.4.0-test12-lia/arch/ia64/kernel/time.c --- linux-2.4.0-test12/arch/ia64/kernel/time.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/time.c Wed Dec 6 22:24:20 2000 @@ -152,19 +152,7 @@ { int cpu = smp_processor_id(); unsigned long new_itm; -#if 0 - static unsigned long last_time; - static unsigned char count; - int printed = 0; -#endif - /* - * Here we are in the timer irq handler. We have irqs locally - * disabled, but we don't know if the timer_bh is running on - * another CPU. We need to avoid to SMP race by acquiring the - * xtime_lock. - */ - write_lock(&xtime_lock); new_itm = itm.next[cpu].count; if (!time_after(ia64_get_itc(), new_itm)) @@ -173,48 +161,33 @@ while (1) { /* - * Do kernel PC profiling here. We multiply the - * instruction number by four so that we can use a - * prof_shift of 2 to get instruction-level instead of - * just bundle-level accuracy. + * Do kernel PC profiling here. We multiply the instruction number by + * four so that we can use a prof_shift of 2 to get instruction-level + * instead of just bundle-level accuracy. */ if (!user_mode(regs)) do_profile(regs->cr_iip + 4*ia64_psr(regs)->ri); #ifdef CONFIG_SMP smp_do_timer(regs); - if (smp_processor_id() == 0) - do_timer(regs); -#else - do_timer(regs); #endif + if (smp_processor_id() == 0) { + /* + * Here we are in the timer irq handler. We have irqs locally + * disabled, but we don't know if the timer_bh is running on + * another CPU. We need to avoid to SMP race by acquiring the + * xtime_lock. + */ + write_lock(&xtime_lock); + do_timer(regs); + write_unlock(&xtime_lock); + } new_itm += itm.delta; itm.next[cpu].count = new_itm; if (time_after(new_itm, ia64_get_itc())) break; - -#if 0 - /* - * SoftSDV in SMP mode is _slow_, so we do "lose" ticks, - * but it's really OK... - */ - if (count > 0 && jiffies - last_time > 5*HZ) - count = 0; - if (count++ == 0) { - last_time = jiffies; - if (!printed) { - printk("Lost clock tick on CPU %d (now=%lx, next=%lx)!!\n", - cpu, ia64_get_itc(), itm.next[cpu].count); - printed = 1; -# ifdef CONFIG_IA64_DEBUG_IRQ - printk("last_cli_ip=%lx\n", last_cli_ip); -# endif - } - } -#endif } - write_unlock(&xtime_lock); /* * If we're too close to the next clock tick for comfort, we diff -urN linux-2.4.0-test12/arch/ia64/kernel/traps.c linux-2.4.0-test12-lia/arch/ia64/kernel/traps.c --- linux-2.4.0-test12/arch/ia64/kernel/traps.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/traps.c Wed Dec 6 22:24:51 2000 @@ -78,7 +78,7 @@ die_if_kernel (char *str, struct pt_regs *regs, long err) { if (user_mode(regs)) { -#if 1 +#if 0 /* XXX for debugging only */ printk ("!!die_if_kernel: %s(%d): %s %ld\n", current->comm, current->pid, str, err); @@ -484,6 +484,20 @@ sprintf(buf, "Disabled FPL fault---not supposed to happen!"); break; + case 26: /* NaT Consumption */ + case 31: /* Unsupported Data Reference */ + if (user_mode(regs)) { + siginfo.si_signo = SIGILL; + siginfo.si_code = ILL_ILLOPN; + siginfo.si_errno = 0; + siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); + siginfo.si_imm = vector; + force_sig_info(SIGILL, &siginfo, current); + return; + } + sprintf(buf, (vector == 26) ? "NaT consumption" : "Unsupported data reference"); + break; + case 29: /* Debug */ case 35: /* Taken Branch Trap */ case 36: /* Single Step Trap */ @@ -522,10 +536,10 @@ case 34: /* Unimplemented Instruction Address Trap */ if (user_mode(regs)) { - printk("Woah! Unimplemented Instruction Address Trap!\n"); - siginfo.si_code = ILL_BADIADDR; siginfo.si_signo = SIGILL; + siginfo.si_code = ILL_BADIADDR; siginfo.si_errno = 0; + siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); force_sig_info(SIGILL, &siginfo, current); return; } @@ -544,7 +558,8 @@ case 46: printk("Unexpected IA-32 intercept trap (Trap 46)\n"); - printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr); + printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", + regs->cr_iip, ifa, isr, iim); force_sig(SIGSEGV, current); return; diff -urN linux-2.4.0-test12/arch/ia64/kernel/unaligned.c linux-2.4.0-test12-lia/arch/ia64/kernel/unaligned.c --- linux-2.4.0-test12/arch/ia64/kernel/unaligned.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/unaligned.c Wed Nov 15 18:08:22 2000 @@ -572,7 +572,8 @@ */ if (regnum == 0) { *val = 0; - *nat = 0; + if (nat) + *nat = 0; return; } @@ -1563,9 +1564,13 @@ DPRINT(("ret=%d\n", ret)); if (ret) { - lock_kernel(); - force_sig(SIGSEGV, current); - unlock_kernel(); + struct siginfo si; + + si.si_signo = SIGBUS; + si.si_errno = 0; + si.si_code = BUS_ADRALN; + si.si_addr = (void *) ifa; + force_sig_info(SIGBUS, &si, current); } else { /* * given today's architecture this case is not likely to happen diff -urN linux-2.4.0-test12/arch/ia64/kernel/unwind.c linux-2.4.0-test12-lia/arch/ia64/kernel/unwind.c --- linux-2.4.0-test12/arch/ia64/kernel/unwind.c Mon Oct 9 17:54:55 2000 +++ linux-2.4.0-test12-lia/arch/ia64/kernel/unwind.c Thu Dec 14 14:14:49 2000 @@ -46,16 +46,6 @@ #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define p5 5 -/* - * The unwind tables are supposed to be sorted, but the GNU toolchain - * currently fails to produce a sorted table in the presence of - * functions that go into sections other than .text. For example, the - * kernel likes to put initialization code into .text.init, which - * messes up the sort order. Hopefully, this will get fixed sometime - * soon. --davidm 00/05/23 - */ -#define UNWIND_TABLE_SORT_BUG - #define UNW_LOG_CACHE_SIZE 7 /* each unw_script is ~256 bytes in size */ #define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE) @@ -531,6 +521,10 @@ struct unw_reg_state *rs; rs = alloc_reg_state(); + if (!rs) { + printk("unwind: cannot stack reg state!\n"); + return; + } memcpy(rs, &sr->curr, sizeof(*rs)); rs->next = sr->stack; sr->stack = rs; @@ -1964,23 +1958,6 @@ { struct unw_table_entry *start = table_start, *end = table_end; -#ifdef UNWIND_TABLE_SORT_BUG - { - struct unw_table_entry *e1, *e2, tmp; - - /* stupid bubble sort... */ - - for (e1 = start; e1 < end; ++e1) { - for (e2 = e1 + 1; e2 < end; ++e2) { - if (e2->start_offset < e1->start_offset) { - tmp = *e1; - *e1 = *e2; - *e2 = tmp; - } - } - } - } -#endif table->name = name; table->segment_base = segment_base; table->gp = gp; @@ -2023,8 +2000,8 @@ void unw_remove_unwind_table (void *handle) { - struct unw_table *table, *prevt; - struct unw_script *tmp, *prev; + struct unw_table *table, *prev; + struct unw_script *tmp; unsigned long flags; long index; @@ -2043,41 +2020,35 @@ { /* first, delete the table: */ - for (prevt = (struct unw_table *) &unw.tables; prevt; prevt = prevt->next) - if (prevt->next == table) + for (prev = (struct unw_table *) &unw.tables; prev; prev = prev->next) + if (prev->next == table) break; - if (!prevt) { + if (!prev) { dprintk("unwind: failed to find unwind table %p\n", (void *) table); spin_unlock_irqrestore(&unw.lock, flags); return; } - prevt->next = table->next; + prev->next = table->next; + } + spin_unlock_irqrestore(&unw.lock, flags); - /* next, remove hash table entries for this table */ + /* next, remove hash table entries for this table */ - for (index = 0; index <= UNW_HASH_SIZE; ++index) { - if (unw.hash[index] >= UNW_CACHE_SIZE) - continue; + for (index = 0; index <= UNW_HASH_SIZE; ++index) { + tmp = unw.cache + unw.hash[index]; + if (unw.hash[index] >= UNW_CACHE_SIZE + || tmp->ip < table->start || tmp->ip >= table->end) + continue; - tmp = unw.cache + unw.hash[index]; - prev = 0; - while (1) { - write_lock(&tmp->lock); - { - if (tmp->ip >= table->start && tmp->ip < table->end) { - if (prev) - prev->coll_chain = tmp->coll_chain; - else - unw.hash[index] = -1; - tmp->ip = 0; - } else - prev = tmp; - } - write_unlock(&tmp->lock); + write_lock(&tmp->lock); + { + if (tmp->ip >= table->start && tmp->ip < table->end) { + unw.hash[index] = tmp->coll_chain; + tmp->ip = 0; } } + write_unlock(&tmp->lock); } - spin_unlock_irqrestore(&unw.lock, flags); kfree(table); } diff -urN linux-2.4.0-test12/arch/ia64/lib/Makefile linux-2.4.0-test12-lia/arch/ia64/lib/Makefile --- linux-2.4.0-test12/arch/ia64/lib/Makefile Mon Oct 9 17:54:56 2000 +++ linux-2.4.0-test12-lia/arch/ia64/lib/Makefile Thu Dec 14 14:15:00 2000 @@ -11,7 +11,8 @@ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ checksum.o clear_page.o csum_partial_copy.o copy_page.o \ copy_user.o clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \ - flush.o do_csum.o + flush.o do_csum.o \ + swiotlb.o ifneq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y) L_OBJS += memcpy.o memset.o strlen.o diff -urN linux-2.4.0-test12/arch/ia64/lib/copy_user.S linux-2.4.0-test12-lia/arch/ia64/lib/copy_user.S --- linux-2.4.0-test12/arch/ia64/lib/copy_user.S Fri Jul 14 16:08:12 2000 +++ linux-2.4.0-test12-lia/arch/ia64/lib/copy_user.S Mon Oct 30 23:45:16 2000 @@ -65,6 +65,12 @@ // // local registers // +#define t1 r2 // rshift in bytes +#define t2 r3 // lshift in bytes +#define rshift r14 // right shift in bits +#define lshift r15 // left shift in bits +#define word1 r16 +#define word2 r17 #define cnt r18 #define len2 r19 #define saved_lc r20 @@ -134,6 +140,190 @@ br.ret.sptk.few rp // end of short memcpy // + // Not 8-byte aligned + // +diff_align_copy_user: + // At this point we know we have more than 16 bytes to copy + // and also that src and dest do _not_ have the same alignment. + and src2=0x7,src1 // src offset + and dst2=0x7,dst1 // dst offset + ;; + // The basic idea is that we copy byte-by-byte at the head so + // that we can reach 8-byte alignment for both src1 and dst1. + // Then copy the body using software pipelined 8-byte copy, + // shifting the two back-to-back words right and left, then copy + // the tail by copying byte-by-byte. + // + // Fault handling. If the byte-by-byte at the head fails on the + // load, then restart and finish the pipleline by copying zeros + // to the dst1. Then copy zeros for the rest of dst1. + // If 8-byte software pipeline fails on the load, do the same as + // failure_in3 does. If the byte-by-byte at the tail fails, it is + // handled simply by failure_in_pipe1. + // + // The case p14 represents the source has more bytes in the + // the first word (by the shifted part), whereas the p15 needs to + // copy some bytes from the 2nd word of the source that has the + // tail of the 1st of the destination. + // + + // + // Optimization. If dst1 is 8-byte aligned (not rarely), we don't need + // to copy the head to dst1, to start 8-byte copy software pipleline. + // We know src1 is not 8-byte aligned in this case. + // + cmp.eq p14,p15=r0,dst2 +(p15) br.cond.spnt.few 1f + ;; + sub t1=8,src2 + mov t2=src2 + ;; + shl rshift=t2,3 + sub len1=len,t1 // set len1 + ;; + sub lshift=64,rshift + ;; + br.cond.spnt.few word_copy_user + ;; +1: + cmp.leu p14,p15=src2,dst2 + sub t1=dst2,src2 + ;; + .pred.rel "mutex", p14, p15 +(p14) sub word1=8,src2 // (8 - src offset) +(p15) sub t1=r0,t1 // absolute value +(p15) sub word1=8,dst2 // (8 - dst offset) + ;; + // For the case p14, we don't need to copy the shifted part to + // the 1st word of destination. + sub t2=8,t1 +(p14) sub word1=word1,t1 + ;; + sub len1=len,word1 // resulting len +(p15) shl rshift=t1,3 // in bits +(p14) shl rshift=t2,3 + ;; +(p14) sub len1=len1,t1 + adds cnt=-1,word1 + ;; + sub lshift=64,rshift + mov ar.ec=PIPE_DEPTH + mov pr.rot=1<<16 // p16=true all others are false + mov ar.lc=cnt + ;; +2: + EX(failure_in_pipe2,(p16) ld1 val1[0]=[src1],1) + ;; + EX(failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1) + br.ctop.dptk.few 2b + ;; + clrrrb + ;; +word_copy_user: + cmp.gtu p9,p0=16,len1 +(p9) br.cond.spnt.few 4f // if (16 > len1) skip 8-byte copy + ;; + shr.u cnt=len1,3 // number of 64-bit words + ;; + adds cnt=-1,cnt + ;; + .pred.rel "mutex", p14, p15 +(p14) sub src1=src1,t2 +(p15) sub src1=src1,t1 + // + // Now both src1 and dst1 point to an 8-byte aligned address. And + // we have more than 8 bytes to copy. + // + mov ar.lc=cnt + mov ar.ec=PIPE_DEPTH + mov pr.rot=1<<16 // p16=true all others are false + ;; +3: + // + // The pipleline consists of 3 stages: + // 1 (p16): Load a word from src1 + // 2 (EPI_1): Shift right pair, saving to tmp + // 3 (EPI): Store tmp to dst1 + // + // To make it simple, use at least 2 (p16) loops to set up val1[n] + // because we need 2 back-to-back val1[] to get tmp. + // Note that this implies EPI_2 must be p18 or greater. + // + +#define EPI_1 p[PIPE_DEPTH-2] +#define SWITCH(pred, shift) cmp.eq pred,p0=shift,rshift +#define CASE(pred, shift) \ + (pred) br.cond.spnt.few copy_user_bit##shift +#define BODY(rshift) \ +copy_user_bit##rshift: \ +1: \ + EX(failure_out,(EPI) st8 [dst1]=tmp,8); \ +(EPI_1) shrp tmp=val1[PIPE_DEPTH-3],val1[PIPE_DEPTH-2],rshift; \ + EX(failure_in2,(p16) ld8 val1[0]=[src1],8); \ + br.ctop.dptk.few 1b; \ + ;; \ + br.cond.spnt.few .diff_align_do_tail + + // + // Since the instruction 'shrp' requires a fixed 128-bit value + // specifying the bits to shift, we need to provide 7 cases + // below. + // + SWITCH(p6, 8) + SWITCH(p7, 16) + SWITCH(p8, 24) + SWITCH(p9, 32) + SWITCH(p10, 40) + SWITCH(p11, 48) + SWITCH(p12, 56) + ;; + CASE(p6, 8) + CASE(p7, 16) + CASE(p8, 24) + CASE(p9, 32) + CASE(p10, 40) + CASE(p11, 48) + CASE(p12, 56) + ;; + BODY(8) + BODY(16) + BODY(24) + BODY(32) + BODY(40) + BODY(48) + BODY(56) + ;; +.diff_align_do_tail: + .pred.rel "mutex", p14, p15 +(p14) sub src1=src1,t1 +(p14) adds dst1=-8,dst1 +(p15) sub dst1=dst1,t1 + ;; +4: + // Tail correction. + // + // The problem with this piplelined loop is that the last word is not + // loaded and thus parf of the last word written is not correct. + // To fix that, we simply copy the tail byte by byte. + + sub len1=endsrc,src1,1 + clrrrb + ;; + mov ar.ec=PIPE_DEPTH + mov pr.rot=1<<16 // p16=true all others are false + mov ar.lc=len1 + ;; +5: + EX(failure_in_pipe1,(p16) ld1 val1[0]=[src1],1) + + EX(failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1) + br.ctop.dptk.few 5b + ;; + mov pr=saved_pr,0xffffffffffff0000 + mov ar.pfs=saved_pfs + br.ret.dptk.few rp + + // // Beginning of long mempcy (i.e. > 16 bytes) // long_copy_user: @@ -142,7 +332,7 @@ ;; cmp.eq p10,p8=r0,tmp mov len1=len // copy because of rotation -(p8) br.cond.dpnt.few 1b // XXX Fixme. memcpy_diff_align +(p8) br.cond.dpnt.few diff_align_copy_user ;; // At this point we know we have more than 16 bytes to copy // and also that both src and dest have the same alignment @@ -267,6 +457,21 @@ mov ar.pfs=saved_pfs br.ret.dptk.few rp + // + // This is the case where the byte by byte copy fails on the load + // when we copy the head. We need to finish the pipeline and copy + // zeros for the rest of the destination. Since this happens + // at the top we still need to fill the body and tail. +failure_in_pipe2: + sub ret0=endsrc,src1 // number of bytes to zero, i.e. not copied +2: +(p16) mov val1[0]=r0 +(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1 + br.ctop.dptk.few 2b + ;; + sub len=enddst,dst1,1 // precompute len + br.cond.dptk.few failure_in1bis + ;; // // Here we handle the head & tail part when we check for alignment. @@ -395,6 +600,23 @@ mov ar.pfs=saved_pfs br.ret.dptk.few rp +failure_in2: + sub ret0=endsrc,src1 // number of bytes to zero, i.e. not copied + ;; +3: +(p16) mov val1[0]=r0 +(EPI) st8 [dst1]=val1[PIPE_DEPTH-1],8 + br.ctop.dptk.few 3b + ;; + cmp.ne p6,p0=dst1,enddst // Do we need to finish the tail ? + sub len=enddst,dst1,1 // precompute len +(p6) br.cond.dptk.few failure_in1bis + ;; + mov pr=saved_pr,0xffffffffffff0000 + mov ar.lc=saved_lc + mov ar.pfs=saved_pfs + br.ret.dptk.few rp + // // handling of failures on stores: that's the easy part // diff -urN linux-2.4.0-test12/arch/ia64/lib/flush.S linux-2.4.0-test12-lia/arch/ia64/lib/flush.S --- linux-2.4.0-test12/arch/ia64/lib/flush.S Thu Jun 22 07:09:44 2000 +++ linux-2.4.0-test12-lia/arch/ia64/lib/flush.S Thu Dec 14 14:15:15 2000 @@ -12,29 +12,33 @@ .psr lsb .lsb -GLOBAL_ENTRY(ia64_flush_icache_page) + /* + * flush_icache_range(start,end) + * Must flush range from start to end-1 but nothing else (need to + * be careful not to touch addresses that may be unmapped). + */ +GLOBAL_ENTRY(flush_icache_range) UNW(.prologue) - alloc r2=ar.pfs,1,0,0,0 + alloc r2=ar.pfs,2,0,0,0 + sub r8=in1,in0,1 + ;; + shr.u r8=r8,5 // we flush 32 bytes per iteration UNW(.save ar.lc, r3) mov r3=ar.lc // save ar.lc + ;; .body - mov r8=PAGE_SIZE/64-1 // repeat/until loop - ;; mov ar.lc=r8 - add r8=32,in0 ;; -.Loop1: fc in0 // issuable on M0 only - add in0=64,in0 - fc r8 - add r8=64,r8 - br.cloop.sptk.few .Loop1 +.Loop: fc in0 // issuable on M0 only + add in0=32,in0 + br.cloop.sptk.few .Loop ;; sync.i ;; srlz.i ;; mov ar.lc=r3 // restore ar.lc - br.ret.sptk.few rp -END(ia64_flush_icache_page) + br.ret.sptk.many rp +END(flush_icache_range) diff -urN linux-2.4.0-test12/arch/ia64/lib/io.c linux-2.4.0-test12-lia/arch/ia64/lib/io.c --- linux-2.4.0-test12/arch/ia64/lib/io.c Mon Oct 9 17:54:56 2000 +++ linux-2.4.0-test12-lia/arch/ia64/lib/io.c Thu Dec 14 14:15:32 2000 @@ -1,3 +1,4 @@ +#include #include #include @@ -48,3 +49,54 @@ } } +#ifdef CONFIG_IA64_GENERIC + +unsigned int +ia64_inb (unsigned long port) +{ + return __ia64_inb(port); +} + +unsigned int +ia64_inw (unsigned long port) +{ + return __ia64_inw(port); +} + +unsigned int +ia64_inl (unsigned long port) +{ + return __ia64_inl(port); +} + +void +ia64_outb (unsigned char val, unsigned long port) +{ + __ia64_outb(val, port); +} + +void +ia64_outw (unsigned short val, unsigned long port) +{ + __ia64_outw(val, port); +} + +void +ia64_outl (unsigned int val, unsigned long port) +{ + __ia64_outl(val, port); +} + +/* define aliases: */ + +asm (".global __ia64_inb, __ia64_inw, __ia64_inl"); +asm ("__ia64_inb = ia64_inb"); +asm ("__ia64_inw = ia64_inw"); +asm ("__ia64_inl = ia64_inl"); + +asm (".global __ia64_outb, __ia64_outw, __ia64_outl"); +asm ("__ia64_outb = ia64_outb"); +asm ("__ia64_outw = ia64_outw"); +asm ("__ia64_outl = ia64_outl"); + +#endif /* CONFIG_IA64_GENERIC */ diff -urN linux-2.4.0-test12/arch/ia64/lib/memcpy.S linux-2.4.0-test12-lia/arch/ia64/lib/memcpy.S --- linux-2.4.0-test12/arch/ia64/lib/memcpy.S Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/arch/ia64/lib/memcpy.S Wed Dec 6 22:25:15 2000 @@ -17,17 +17,31 @@ #include +#if defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC) +# define BRP(args...) nop.b 0 +#else +# define BRP(args...) brp.loop.imp args +#endif + GLOBAL_ENTRY(bcopy) .regstk 3,0,0,0 mov r8=in0 mov in0=in1 ;; mov in1=r8 + // gas doesn't handle control flow across procedures, so it doesn't + // realize that a stop bit is needed before the "alloc" instruction + // below +{ + nop.m 0 + nop.f 0 + nop.i 0 +} ;; END(bcopy) // FALL THROUGH GLOBAL_ENTRY(memcpy) -# define MEM_LAT 2 /* latency to L1 cache */ +# define MEM_LAT 21 /* latency to memory */ # define dst r2 # define src r3 @@ -57,20 +71,17 @@ UNW(.prologue) UNW(.save ar.pfs, saved_pfs) alloc saved_pfs=ar.pfs,3,Nrot,0,Nrot -#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) - lfetch [in1] -#else - nop.m 0 -#endif + UNW(.save ar.lc, saved_lc) + mov saved_lc=ar.lc or t0=in0,in1 ;; or t0=t0,in2 - UNW(.save ar.lc, saved_lc) - mov saved_lc=ar.lc UNW(.save pr, saved_pr) mov saved_pr=pr + UNW(.body) + cmp.eq p6,p0=in2,r0 // zero length? mov retval=in0 // return dst (p6) br.ret.spnt.many rp // zero length, return immediately @@ -83,7 +94,6 @@ adds cnt=-1,cnt // br.ctop is repeat/until cmp.gtu p7,p0=16,in2 // copying less than 16 bytes? - UNW(.body) mov ar.ec=N ;; @@ -96,12 +106,26 @@ (p7) br.cond.spnt.few memcpy_short (p6) br.cond.spnt.few memcpy_long ;; + nop.m 0 + ;; + nop.m 0 + nop.i 0 + ;; + nop.m 0 + ;; .rotr val[N] .rotp p[N] -1: + .align 32 +1: { .mib (p[0]) ld8 val[0]=[src],8 + nop.i 0 + BRP(1b, 2f) +} +2: { .mfb (p[N-1])st8 [dst]=val[N-1],8 + nop.f 0 br.ctop.dptk.few 1b +} ;; mov ar.lc=saved_lc mov pr=saved_pr,-1 @@ -118,19 +142,34 @@ memcpy_short: adds cnt=-1,in2 // br.ctop is repeat/until mov ar.ec=MEM_LAT + BRP(1f, 2f) ;; mov ar.lc=cnt ;; + nop.m 0 + ;; + nop.m 0 + nop.i 0 + ;; + nop.m 0 + ;; + nop.m 0 + ;; /* * It is faster to put a stop bit in the loop here because it makes * the pipeline shorter (and latency is what matters on short copies). */ -1: + .align 32 +1: { .mib (p[0]) ld1 val[0]=[src],1 - ;; + nop.i 0 + BRP(1b, 2f) +} ;; +2: { .mfb (p[MEM_LAT-1])st1 [dst]=val[MEM_LAT-1],1 + nop.f 0 br.ctop.dptk.few 1b - ;; +} ;; mov ar.lc=saved_lc mov pr=saved_pr,-1 mov ar.pfs=saved_pfs @@ -227,6 +266,13 @@ mov pr=cnt,0x38 // set (p5,p4,p3) to # of bytes last-word bytes to copy mov ar.lc=t2 ;; + nop.m 0 + ;; + nop.m 0 + nop.i 0 + ;; + nop.m 0 + ;; (p6) ld8 val[1]=[src2],8 // prime the pump... mov b6=t4 br.sptk.few b6 @@ -251,17 +297,16 @@ .align 64 #define COPY(shift,index) \ - 1: \ - { .mfi \ + 1: { .mib \ (p[0]) ld8 val[0]=[src2],8; \ - nop.f 0; \ (p[MEM_LAT+3]) shrp w[0]=val[MEM_LAT+3],val[MEM_LAT+4-index],shift; \ - }; \ - { .mbb \ + BRP(1b, 2f) \ + }; \ + 2: { .mfb \ (p[MEM_LAT+4]) st8 [dst]=w[1],8; \ - nop.b 0; \ + nop.f 0; \ br.ctop.dptk.few 1b; \ - }; \ + }; \ ;; \ ld8 val[N-1]=[src_end]; /* load last word (may be same as val[N]) */ \ ;; \ diff -urN linux-2.4.0-test12/arch/ia64/lib/swiotlb.c linux-2.4.0-test12-lia/arch/ia64/lib/swiotlb.c --- linux-2.4.0-test12/arch/ia64/lib/swiotlb.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/lib/swiotlb.c Thu Dec 14 14:19:36 2000 @@ -0,0 +1,454 @@ +/* + * Dynamic DMA mapping support. + * + * This implementation is for IA-64 platforms that do not support + * I/O TLBs (aka DMA address translation hardware). + * Copyright (C) 2000 Asit Mallick + * Copyright (C) 2000 Goutham Rao + * + * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid + * unnecessary i-cache flushing. + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define ALIGN(val, align) ((unsigned long) \ + (((unsigned long) (val) + ((align) - 1)) & ~((align) - 1))) + +/* + * log of the size of each IO TLB slab. The number of slabs is command line controllable. + */ +#define IO_TLB_SHIFT 11 + +/* + * 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. + */ +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. + * This is command line adjustable via setup_io_tlb_npages. + */ +static unsigned long io_tlb_nslabs = 1024; + +/* + * This is a free list describing the number of free entries available from each index + */ +static unsigned int *io_tlb_list; +static unsigned int io_tlb_index; + +/* + * We need to save away the original address corresponding to a mapped entry for the sync + * operations. + */ +static unsigned char **io_tlb_orig_addr; + +/* + * Protect the above data structures in the map and unmap calls + */ +static spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED; + +static int __init +setup_io_tlb_npages (char *str) +{ + io_tlb_nslabs = simple_strtoul(str, NULL, 0) << (PAGE_SHIFT - IO_TLB_SHIFT); + return 1; +} +__setup("swiotlb=", setup_io_tlb_npages); + +/* + * Statically reserve bounce buffer space and initialize bounce buffer data structures for + * the software IO TLB used to implement the PCI DMA API. + */ +void +swiotlb_init (void) +{ + int i; + + /* + * Get IO TLB memory from the low pages + */ + io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT)); + if (!io_tlb_start) + BUG(); + io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT); + + /* + * Allocate and initialize the free list array. This array is used + * to find contiguous free memory regions of size 2^IO_TLB_SHIFT between + * io_tlb_start and io_tlb_end. + */ + io_tlb_list = alloc_bootmem(io_tlb_nslabs * sizeof(int)); + for (i = 0; i < io_tlb_nslabs; i++) + io_tlb_list[i] = io_tlb_nslabs - i; + io_tlb_index = 0; + io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); + + printk("Placing software IO TLB between 0x%p - 0x%p\n", + (void *) io_tlb_start, (void *) io_tlb_end); +} + +/* + * Allocates bounce buffer and returns its kernel virtual address. + */ +static void * +map_single (struct pci_dev *hwdev, char *buffer, size_t size, int direction) +{ + unsigned long flags; + char *dma_addr; + unsigned int nslots, stride, index, wrap; + int i; + + /* + * For mappings greater than a page size, we limit the stride (and hence alignment) + * to a page size. + */ + nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; + if (size > (1 << PAGE_SHIFT)) + stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT)); + else + stride = nslots; + + if (!nslots) + BUG(); + + /* + * Find suitable number of IO TLB entries size that will fit this request and + * allocate a buffer from that IO TLB pool. + */ + spin_lock_irqsave(&io_tlb_lock, flags); + { + wrap = index = ALIGN(io_tlb_index, stride); + + if (index >= io_tlb_nslabs) + wrap = index = 0; + + do { + /* + * If we find a slot that indicates we have 'nslots' number of + * contiguous buffers, we allocate the buffers from that slot and + * mark the entries as '0' indicating unavailable. + */ + if (io_tlb_list[index] >= nslots) { + int count = 0; + + for (i = index; i < index + nslots; i++) + io_tlb_list[i] = 0; + for (i = index - 1; (i >= 0) && io_tlb_list[i]; i--) + io_tlb_list[i] = ++count; + dma_addr = io_tlb_start + (index << IO_TLB_SHIFT); + + /* + * Update the indices to avoid searching in the next round. + */ + io_tlb_index = ((index + nslots) < io_tlb_nslabs + ? (index + nslots) : 0); + + goto found; + } + index += stride; + if (index >= io_tlb_nslabs) + 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); +found: + } + spin_unlock_irqrestore(&io_tlb_lock, flags); + + /* + * Save away the mapping from the original address to the DMA address. This is + * needed when we sync the memory. Then we sync the buffer if needed. + */ + io_tlb_orig_addr[index] = buffer; + if (direction == PCI_DMA_TODEVICE || direction == PCI_DMA_BIDIRECTIONAL) + memcpy(dma_addr, buffer, size); + + return dma_addr; +} + +/* + * dma_addr is the kernel virtual address of the bounce buffer to unmap. + */ +static void +unmap_single (struct pci_dev *hwdev, char *dma_addr, size_t size, int direction) +{ + unsigned long flags; + int i, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; + int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; + char *buffer = io_tlb_orig_addr[index]; + + /* + * First, sync the memory before unmapping the entry + */ + if ((direction == PCI_DMA_FROMDEVICE) || (direction == PCI_DMA_BIDIRECTIONAL)) + /* + * bounce... copy the data back into the original buffer * and delete the + * bounce buffer. + */ + memcpy(buffer, dma_addr, size); + + /* + * Return the buffer to the free list by setting the corresponding entries to + * indicate the number of contigous entries available. While returning the + * entries to the free list, we merge the entries with slots below and above the + * pool being returned. + */ + spin_lock_irqsave(&io_tlb_lock, flags); + { + int count = ((index + nslots) < io_tlb_nslabs ? io_tlb_list[index + nslots] : 0); + /* + * Step 1: return the slots to the free list, merging the slots with + * superceeding slots + */ + for (i = index + nslots - 1; i >= index; i--) + io_tlb_list[i] = ++count; + /* + * Step 2: merge the returned slots with the preceeding slots, if + * available (non zero) + */ + for (i = index - 1; (i >= 0) && io_tlb_list[i]; i--) + io_tlb_list[i] = ++count; + } + spin_unlock_irqrestore(&io_tlb_lock, flags); +} + +static void +sync_single (struct pci_dev *hwdev, char *dma_addr, size_t size, int direction) +{ + int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; + char *buffer = io_tlb_orig_addr[index]; + + /* + * bounce... copy the data back into/from the original buffer + * XXX How do you handle PCI_DMA_BIDIRECTIONAL here ? + */ + if (direction == PCI_DMA_FROMDEVICE) + memcpy(buffer, dma_addr, size); + else if (direction == PCI_DMA_TODEVICE) + memcpy(dma_addr, buffer, size); + else + BUG(); +} + +void * +swiotlb_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +{ + unsigned long pci_addr; + int gfp = GFP_ATOMIC; + void *ret; + + if (!hwdev || hwdev->dma_mask <= 0xffffffff) + gfp |= GFP_DMA; /* XXX fix me: should change this to GFP_32BIT or ZONE_32BIT */ + ret = (void *)__get_free_pages(gfp, get_order(size)); + if (!ret) + return NULL; + + memset(ret, 0, size); + pci_addr = virt_to_phys(ret); + if ((pci_addr & ~hwdev->dma_mask) != 0) + panic("swiotlb_alloc_consistent: allocated memory is out of range for PCI device"); + *dma_handle = pci_addr; + return ret; +} + +void +swiotlb_free_consistent (struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long) vaddr, get_order(size)); +} + +/* + * Map a single buffer of the indicated size for DMA in streaming mode. The PCI address + * to use is returned. + * + * Once the device is given the dma address, the device owns this memory until either + * swiotlb_unmap_single or swiotlb_dma_sync_single is performed. + */ +dma_addr_t +swiotlb_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + unsigned long pci_addr = virt_to_phys(ptr); + + if (direction == PCI_DMA_NONE) + BUG(); + /* + * Check if the PCI device can DMA to ptr... if so, just return ptr + */ + if ((pci_addr & ~hwdev->dma_mask) == 0) + /* + * Device is bit capable of DMA'ing to the buffer... just return the PCI + * address of ptr + */ + return pci_addr; + + /* + * get a bounce buffer: + */ + pci_addr = virt_to_phys(map_single(hwdev, ptr, size, direction)); + + /* + * Ensure that the address returned is DMA'ble: + */ + if ((pci_addr & ~hwdev->dma_mask) != 0) + panic("map_single: bounce buffer is not DMA'ble"); + + return pci_addr; +} + +/* + * Since DMA is i-cache coherent, any (complete) pages that were written via + * DMA can be marked as "clean" so that update_mmu_cache() doesn't have to + * flush them when they get mapped into an executable vm-area. + */ +static void +mark_clean (void *addr, size_t size) +{ + unsigned long pg_addr, end; + + pg_addr = PAGE_ALIGN((unsigned long) addr); + end = (unsigned long) addr + size; + while (pg_addr + PAGE_SIZE <= end) { + set_bit(PG_arch_1, virt_to_page(pg_addr)); + pg_addr += PAGE_SIZE; + } +} + +/* + * Unmap a single streaming mode DMA translation. The dma_addr and size must match what + * was provided for in a previous swiotlb_map_single call. All other usages are + * undefined. + * + * After this call, reads by the cpu to the buffer are guarenteed to see whatever the + * device wrote there. + */ +void +swiotlb_unmap_single (struct pci_dev *hwdev, dma_addr_t pci_addr, size_t size, int direction) +{ + char *dma_addr = phys_to_virt(pci_addr); + + if (direction == PCI_DMA_NONE) + BUG(); + if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) + unmap_single(hwdev, dma_addr, size, direction); + else if (direction == PCI_DMA_FROMDEVICE) + mark_clean(dma_addr, size); +} + +/* + * Make physical memory consistent for a single streaming mode DMA translation after a + * transfer. + * + * If you perform a swiotlb_map_single() but wish to interrogate the buffer using the cpu, + * yet do not wish to teardown the PCI dma mapping, you must call this function before + * doing so. At the next point you give the PCI dma address back to the card, the device + * again owns the buffer. + */ +void +swiotlb_sync_single (struct pci_dev *hwdev, dma_addr_t pci_addr, size_t size, int direction) +{ + char *dma_addr = phys_to_virt(pci_addr); + + if (direction == PCI_DMA_NONE) + BUG(); + if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end) + sync_single(hwdev, dma_addr, size, direction); + else if (direction == PCI_DMA_FROMDEVICE) + mark_clean(dma_addr, size); +} + +/* + * Map a set of buffers described by scatterlist in streaming mode for DMA. This is the + * scather-gather version of the above swiotlb_map_single interface. Here the scatter + * gather list elements are each tagged with the appropriate dma address and length. They + * are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for swiotlb_map_single are the same here. + */ +int +swiotlb_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) { + sg->orig_address = sg->address; + if ((virt_to_phys(sg->address) & ~hwdev->dma_mask) != 0) { + sg->address = map_single(hwdev, sg->address, sg->length, + direction); + } + } + return nelems; +} + +/* + * Unmap a set of streaming mode DMA translations. Again, cpu read rules concerning calls + * here are the same as for swiotlb_unmap_single() above. + */ +void +swiotlb_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) + if (sg->orig_address != sg->address) { + unmap_single(hwdev, sg->address, sg->length, direction); + sg->address = sg->orig_address; + } else if (direction == PCI_DMA_FROMDEVICE) + mark_clean(sg->address, sg->length); +} + +/* + * Make physical memory consistent for a set of streaming mode DMA translations after a + * transfer. + * + * The same as swiotlb_dma_sync_single but for a scatter-gather list, same rules and + * usage. + */ +void +swiotlb_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + + for (i = 0; i < nelems; i++, sg++) + if (sg->orig_address != sg->address) + sync_single(hwdev, sg->address, sg->length, direction); +} + +unsigned long +swiotlb_dma_address (struct scatterlist *sg) +{ + return virt_to_phys(sg->address); +} diff -urN linux-2.4.0-test12/arch/ia64/mm/fault.c linux-2.4.0-test12-lia/arch/ia64/mm/fault.c --- linux-2.4.0-test12/arch/ia64/mm/fault.c Thu Jun 22 07:09:45 2000 +++ linux-2.4.0-test12-lia/arch/ia64/mm/fault.c Wed Dec 6 22:25:31 2000 @@ -121,17 +121,19 @@ goto bad_area; if (expand_stack(vma, address)) goto bad_area; - } else if (expand_backing_store(prev_vma, address)) - goto bad_area; + } else { + vma = prev_vma; + if (expand_backing_store(vma, address)) + goto bad_area; + } goto good_area; bad_area: up(&mm->mmap_sem); if (isr & IA64_ISR_SP) { /* - * This fault was due to a speculative load set the - * "ed" bit in the psr to ensure forward progress - * (target register will get a NaT). + * This fault was due to a speculative load set the "ed" bit in the psr to + * ensure forward progress (target register will get a NaT). */ ia64_psr(regs)->ed = 1; return; @@ -146,6 +148,15 @@ } no_context: + if (isr & IA64_ISR_SP) { + /* + * This fault was due to a speculative load set the "ed" bit in the psr to + * ensure forward progress (target register will get a NaT). + */ + ia64_psr(regs)->ed = 1; + return; + } + fix = search_exception_table(regs->cr_iip); if (fix) { regs->r8 = -EFAULT; diff -urN linux-2.4.0-test12/arch/ia64/mm/init.c linux-2.4.0-test12-lia/arch/ia64/mm/init.c --- linux-2.4.0-test12/arch/ia64/mm/init.c Wed Dec 13 17:29:20 2000 +++ linux-2.4.0-test12-lia/arch/ia64/mm/init.c Thu Dec 14 14:36:33 2000 @@ -1,8 +1,8 @@ /* * Initialize MMU support. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998-2000 Hewlett-Packard Co + * Copyright (C) 1998-2000 David Mosberger-Tang */ #include #include @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -303,7 +304,7 @@ return 0; } flush_page_to_ram(page); - set_pte(pte, page_pte_prot(page, PAGE_GATE)); + set_pte(pte, mk_pte(page, PAGE_GATE)); /* no need for flush_tlb */ return page; } @@ -311,7 +312,12 @@ void __init ia64_rid_init (void) { - unsigned long flags, rid, pta, impl_va_msb; + unsigned long flags, rid, pta, impl_va_bits; +#ifdef CONFIG_DISABLE_VHPT +# define VHPT_ENABLE_BIT 0 +#else +# define VHPT_ENABLE_BIT 1 +#endif /* Set up the kernel identity mappings (regions 6 & 7) and the vmalloc area (region 5): */ ia64_clear_ic(flags); @@ -328,44 +334,46 @@ __restore_flags(flags); /* - * Check if the virtually mapped linear page table (VMLPT) - * overlaps with a mapped address space. The IA-64 - * architecture guarantees that at least 50 bits of virtual - * address space are implemented but if we pick a large enough - * page size (e.g., 64KB), the VMLPT is big enough that it - * will overlap with the upper half of the kernel mapped - * region. I assume that once we run on machines big enough - * to warrant 64KB pages, IMPL_VA_MSB will be significantly - * bigger, so we can just adjust the number below to get - * things going. Alternatively, we could truncate the upper - * half of each regions address space to not permit mappings - * that would overlap with the VMLPT. --davidm 99/11/13 + * Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped + * address space. The IA-64 architecture guarantees that at least 50 bits of + * virtual address space are implemented but if we pick a large enough page size + * (e.g., 64KB), the mapped address space is big enough that it will overlap with + * VMLPT. I assume that once we run on machines big enough to warrant 64KB pages, + * IMPL_VA_MSB will be significantly bigger, so this is unlikely to become a + * problem in practice. Alternatively, we could truncate the top of the mapped + * address space to not permit mappings that would overlap with the VMLPT. + * --davidm 00/12/06 + */ +# define pte_bits 3 +# define mapped_space_bits (3*(PAGE_SHIFT - pte_bits) + PAGE_SHIFT) + /* + * The virtual page table has to cover the entire implemented address space within + * a region even though not all of this space may be mappable. The reason for + * this is that the Access bit and Dirty bit fault handlers perform + * non-speculative accesses to the virtual page table, so the address range of the + * virtual page table itself needs to be covered by virtual page table. */ -# define ld_pte_size 3 -# define ld_max_addr_space_pages 3*(PAGE_SHIFT - ld_pte_size) /* max # of mappable pages */ -# define ld_max_addr_space_size (ld_max_addr_space_pages + PAGE_SHIFT) -# define ld_max_vpt_size (ld_max_addr_space_pages + ld_pte_size) +# define vmlpt_bits (impl_va_bits - PAGE_SHIFT + pte_bits) # define POW2(n) (1ULL << (n)) - impl_va_msb = ffz(~my_cpu_data.unimpl_va_mask) - 1; - if (impl_va_msb < 50 || impl_va_msb > 60) - panic("Bogus impl_va_msb value of %lu!\n", impl_va_msb); + impl_va_bits = ffz(~my_cpu_data.unimpl_va_mask); + + if (impl_va_bits < 51 || impl_va_bits > 61) + panic("CPU has bogus IMPL_VA_MSB value of %lu!\n", impl_va_bits - 1); + + /* place the VMLPT at the end of each page-table mapped region: */ + pta = POW2(61) - POW2(vmlpt_bits); - if (POW2(ld_max_addr_space_size - 1) + POW2(ld_max_vpt_size) > POW2(impl_va_msb)) + if (POW2(mapped_space_bits) >= pta) panic("mm/init: overlap between virtually mapped linear page table and " "mapped kernel space!"); - pta = POW2(61) - POW2(impl_va_msb); -#ifndef CONFIG_DISABLE_VHPT /* * Set the (virtually mapped linear) page table address. Bit * 8 selects between the short and long format, bits 2-7 the * size of the table, and bit 0 whether the VHPT walker is * enabled. */ - ia64_set_pta(pta | (0<<8) | ((3*(PAGE_SHIFT-3)+3)<<2) | 1); -#else - ia64_set_pta(pta | (0<<8) | ((3*(PAGE_SHIFT-3)+3)<<2) | 0); -#endif + ia64_set_pta(pta | (0 << 8) | (vmlpt_bits << 2) | VHPT_ENABLE_BIT); } /* @@ -420,6 +428,15 @@ { extern char __start_gate_section[]; long reserved_pages, codesize, datasize, initsize; + +#ifdef CONFIG_PCI + /* + * This needs to be called _after_ the command line has been parsed but _before_ + * any drivers that may need the PCI DMA interface are initialized or bootmem has + * been freed. + */ + platform_pci_dma_init(); +#endif if (!mem_map) BUG(); diff -urN linux-2.4.0-test12/arch/ia64/mm/tlb.c linux-2.4.0-test12-lia/arch/ia64/mm/tlb.c --- linux-2.4.0-test12/arch/ia64/mm/tlb.c Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/arch/ia64/mm/tlb.c Wed Dec 6 22:26:48 2000 @@ -6,6 +6,8 @@ * * 08/02/00 A. Mallick * Modified RID allocation for SMP + * Goutham Rao + * IPI based ptc implementation and A-step IPI implementation. */ #include #include @@ -17,6 +19,7 @@ #include #include #include +#include #define SUPPORTED_PGBITS ( \ 1 << _PAGE_SIZE_256M | \ @@ -33,15 +36,10 @@ struct ia64_ctx ia64_ctx = { lock: SPIN_LOCK_UNLOCKED, next: 1, - limit: (1UL << IA64_HW_CONTEXT_BITS) + limit: (1 << 15) - 1, /* start out with the safe (architected) limit */ + max_ctx: ~0U }; - /* - * Put everything in a struct so we avoid the global offset table whenever - * possible. - */ -ia64_ptce_info_t ia64_ptce_info; - /* * Seralize usage of ptc.g */ @@ -99,9 +97,22 @@ /* * Wait for other CPUs to finish purging entries. */ +#if (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)) + { + unsigned long start = ia64_get_itc(); + while (atomic_read(&flush_cpu_count) > 0) { + if ((ia64_get_itc() - start) > 40000UL) { + atomic_set(&flush_cpu_count, smp_num_cpus - 1); + smp_send_flush_tlb(); + start = ia64_get_itc(); + } + } + } +#else while (atomic_read(&flush_cpu_count)) { /* Nothing */ } +#endif if (!(flags & IA64_PSR_I)) { local_irq_disable(); ia64_set_tpr(saved_tpr); @@ -117,12 +128,12 @@ void wrap_mmu_context (struct mm_struct *mm) { + unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx; struct task_struct *tsk; - unsigned long tsk_context; - if (ia64_ctx.next >= (1UL << IA64_HW_CONTEXT_BITS)) + if (ia64_ctx.next > max_ctx) ia64_ctx.next = 300; /* skip daemons */ - ia64_ctx.limit = (1UL << IA64_HW_CONTEXT_BITS); + ia64_ctx.limit = max_ctx + 1; /* * Scan all the task's mm->context and set proper safe range @@ -137,9 +148,9 @@ if (tsk_context == ia64_ctx.next) { if (++ia64_ctx.next >= ia64_ctx.limit) { /* empty range: reset the range limit and start over */ - if (ia64_ctx.next >= (1UL << IA64_HW_CONTEXT_BITS)) + if (ia64_ctx.next > max_ctx) ia64_ctx.next = 300; - ia64_ctx.limit = (1UL << IA64_HW_CONTEXT_BITS); + ia64_ctx.limit = max_ctx + 1; goto repeat; } } @@ -153,12 +164,13 @@ void __flush_tlb_all (void) { - unsigned long i, j, flags, count0, count1, stride0, stride1, addr = ia64_ptce_info.base; + unsigned long i, j, flags, count0, count1, stride0, stride1, addr; - count0 = ia64_ptce_info.count[0]; - count1 = ia64_ptce_info.count[1]; - stride0 = ia64_ptce_info.stride[0]; - stride1 = ia64_ptce_info.stride[1]; + addr = my_cpu_data.ptce_base; + count0 = my_cpu_data.ptce_count[0]; + count1 = my_cpu_data.ptce_count[1]; + stride0 = my_cpu_data.ptce_stride[0]; + stride1 = my_cpu_data.ptce_stride[1]; local_irq_save(flags); for (i = 0; i < count0; ++i) { @@ -182,7 +194,11 @@ if (mm != current->active_mm) { /* this does happen, but perhaps it's not worth optimizing for? */ +#ifdef CONFIG_SMP + flush_tlb_all(); +#else mm->context = 0; +#endif return; } @@ -230,6 +246,14 @@ void __init ia64_tlb_init (void) { - ia64_get_ptce(&ia64_ptce_info); + ia64_ptce_info_t ptce_info; + + ia64_get_ptce(&ptce_info); + my_cpu_data.ptce_base = ptce_info.base; + my_cpu_data.ptce_count[0] = ptce_info.count[0]; + my_cpu_data.ptce_count[1] = ptce_info.count[1]; + my_cpu_data.ptce_stride[0] = ptce_info.stride[0]; + my_cpu_data.ptce_stride[1] = ptce_info.stride[1]; + __flush_tlb_all(); /* nuke left overs from bootstrapping... */ } diff -urN linux-2.4.0-test12/arch/ia64/sn/Makefile linux-2.4.0-test12-lia/arch/ia64/sn/Makefile --- linux-2.4.0-test12/arch/ia64/sn/Makefile Thu Mar 30 16:56:04 2000 +++ linux-2.4.0-test12-lia/arch/ia64/sn/Makefile Wed Dec 6 21:54:08 2000 @@ -5,15 +5,10 @@ # Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com) # -CFLAGS := $(CFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSN -DSOFTSDV \ - -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -AFLAGS := $(AFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSOFTSDV - -.S.s: - $(CPP) $(AFLAGS) -o $*.s $< -.S.o: - $(CC) $(AFLAGS) -c -o $*.o $< - +EXTRA_CFLAGS := -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \ + -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \ + -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \ + -DNEW_INTERRUPTS -DCONFIG_IA64_SGI_IO all: sn.a O_TARGET = sn.a diff -urN linux-2.4.0-test12/arch/ia64/sn/fprom/Makefile linux-2.4.0-test12-lia/arch/ia64/sn/fprom/Makefile --- linux-2.4.0-test12/arch/ia64/sn/fprom/Makefile Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/Makefile Wed Dec 6 21:54:08 2000 @@ -0,0 +1,30 @@ +# +# 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 Silicon Graphics, Inc. +# Copyright (C) Jack Steiner (steiner@sgi.com) +# + +TOPDIR=../../../.. +HPATH = $(TOPDIR)/include + +LIB = ../../lib/lib.a + +OBJ=fpromasm.o main.o fw-emu.o fpmem.o + +fprom: $(OBJ) + $(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB) + +.S.o: + $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< +.c.o: + $(CC) $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $< + +clean: + rm -f *.o fprom + + +include $(TOPDIR)/Rules.make + diff -urN linux-2.4.0-test12/arch/ia64/sn/fprom/README linux-2.4.0-test12-lia/arch/ia64/sn/fprom/README --- linux-2.4.0-test12/arch/ia64/sn/fprom/README Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/README Wed Nov 15 19:11:34 2000 @@ -0,0 +1,85 @@ +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
#(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*, where dn is the digit number. The amount of memory + is 8MB*2**. (If = 0, the memory size is 0). + + SN1 doesnt 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 -urN linux-2.4.0-test12/arch/ia64/sn/fprom/fpmem.c linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fpmem.c --- linux-2.4.0-test12/arch/ia64/sn/fprom/fpmem.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fpmem.c Wed Dec 13 18:59:33 2000 @@ -0,0 +1,200 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +/* + * FPROM EFI memory descriptor build routines + * + * - Routines to build the EFI memory descriptor map + * - Should also be usable by the SGI SN1 prom to convert + * klconfig to efi_memmap + */ + +#include +#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) +#define MD_BANK_SHFT 30 + +#define TO_NODE(_n, _x) (((long)_n<<33L) | (long)_x) + +/* + * 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 SN1, 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 & (1<type = type; + md->phys_addr = paddr; + md->virt_addr = 0; + md->num_pages = numbytes >> 12; + md->attribute = EFI_MEMORY_WB; +} + +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 + +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 -urN linux-2.4.0-test12/arch/ia64/sn/fprom/fprom.lds linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fprom.lds --- linux-2.4.0-test12/arch/ia64/sn/fprom/fprom.lds Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fprom.lds Wed Nov 15 19:11:34 2000 @@ -0,0 +1,96 @@ + +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) } + .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 -urN linux-2.4.0-test12/arch/ia64/sn/fprom/fpromasm.S linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fpromasm.S --- linux-2.4.0-test12/arch/ia64/sn/fprom/fpromasm.S Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fpromasm.S Wed Dec 6 21:54:09 2000 @@ -0,0 +1,314 @@ +/* + * + * 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 + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + + +#define __ASSEMBLY__ 1 +#include "asm/processor.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 + * + * 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 PAGESIZE_256M 28 + +/* + * 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 + */ +#define IOPB_PA 0x00000a0000000000 /* inv swizzle IOSPEC_BASE */ + +#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 + ;; + +// Set CALIAS size to zero. We dont use it. + movl r24=0x80000a0001000028;; // BR_PI_CALIAS_SIZE + st8 [r24]=r0 + +// Isolate node number we are running on. + mov r6 = ip;; + shr r5 = r6,33;; // r5 = node number + shl r6 = r5,33 // r6 = base memory address of node + +// Set & relocate gp. + movl r1= __gp;; // Add base memory address + add r1 = r1,r6 // Relocate to boot node + +// Lets figure out who we are & put it in the LID register. +// 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 + mov cr.lid=r26 // Now put in in the LID register + + movl r2=FPSR_DEFAULT;; + mov ar.fpsr=r2 + movl sp = bootstacke-16;; + add 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 + add 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;; + add 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;; + add 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_;; + add r16 = r16,r6;; // Relocate to boot node +1: ld8 r17 = [r16];; + cmp.eq p6,p7=0,r17 +(p6) br.cond.sptk.few.clr 2f;; + add 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 r0=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 + +// +// Initialize the protection key registers with only pkr[0] = valid. +// +// Should be initialized in accordance with the OS. +// + mov r2 = 1 + mov r3 = r0;; + mov pkr[r3] = r2;; + srlz.d;; + mov r2 = r0 + +1: add r3 = r3, r0, 1;; // increment PKR + cmp.gtu p6, p0 = 16, r3;; +(p6) mov pkr[r3] = r2 +(p6) br.cond.sptk.few.clr 1b + + mov ar.rnat = r0 // clear RNAT register + +// +// Setup system address translation for kernel +// +// Note: The setup of Kernel Virtual address space can be done by the +// C code of the boot loader. +// +// + +#define LINUX_PAGE_OFFSET 0xe000000000000000 +#define ITIR(key, ps) ((key<<8) | (ps<<2)) +#define ITRGR(ed,ar,ma) ((ed<<52) | (ar<<9) | (ma<<2) | 0x61) + +#define AR_RX 1 // RX permission +#define AR_RW 4 // RW permission +#define MA_WB 0 // WRITEBACK memory attribute + +#define TLB_PAGESIZE 28 // Use 256MB pages for now. + mov r16=r5 + +// +// text section +// + movl r2 = LINUX_PAGE_OFFSET;; // Set up IFA with VPN of linux + mov cr.ifa = r2 + movl r3 = ITIR(0,TLB_PAGESIZE);; // Set ITIR to default pagesize + mov cr.itir = r3 + + shl r4 = r16,33;; // physical addr of start of node + movl r5 = ITRGR(1,AR_RX,MA_WB);; // TLB attributes + or r10=r4,r5;; + + itr.i itr[r0] = r10;; // Dropin ITR entry + srlz.i;; + +// +// data section +// + movl r2 = LINUX_PAGE_OFFSET;; // Set up IFA with VPN of linux + mov cr.ifa = r2 + movl r3 = ITIR(0,TLB_PAGESIZE);; // Set ITIR to default pagesize + mov cr.itir = r3 + + shl r4 = r16,33;; // physical addr of start of node + movl r5 = ITRGR(1,AR_RW,MA_WB);; // TLB attributes + or r10=r4,r5;; + + itr.d dtr[r0] = r10;; // Dropin DTR entry + srlz.d;; + + + + +// +// 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_IT | \ + IA64_PSR_DB | \ + IA64_PSR_DA | \ + IA64_PSR_RT | \ + IA64_PSR_DT | \ + 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. + + movl r2=bsp_entry_pc;; + add r2 = r2,r6;; // Relocate to boot node + ld8 r2=[r2];; + 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 + add 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 diff -urN linux-2.4.0-test12/arch/ia64/sn/fprom/fw-emu.c linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fw-emu.c --- linux-2.4.0-test12/arch/ia64/sn/fprom/fw-emu.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/fw-emu.c Wed Dec 13 18:59:33 2000 @@ -0,0 +1,494 @@ +/* + * PAL & SAL emulation. + * + * Copyright (C) 1998-2000 Hewlett-Packard Co + * Copyright (C) 1998-2000 David Mosberger-Tang + * + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ +#include + +#include +#include +#include +#include +#include +#include "fpmem.h" + +#define MB (1024*1024UL) +#define GB (MB*1024UL) + +#define FPROM_BUG() do {while (1);} while (0) +#define MAX_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 + +typedef union ia64_nasid_va { + struct { + unsigned long off : 33; /* intra-region offset */ + unsigned long nasid : 7; /* NASID */ + unsigned long off2 : 21; /* fill */ + unsigned long reg : 3; /* region number */ + } 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))) +#define __fwtab_pa(n,x) ({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;}) + +/* + * 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; + + +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(acpi_rsdp_t) + + sizeof(acpi_rsdt_t) + + sizeof(acpi_sapic_t) + + MAX_LSAPICS*(sizeof(acpi_entry_lsapic_t)) + + (1+8*MAX_NODES)*(sizeof(efi_memory_desc_t)) + + sizeof(ia64_sal_desc_ptc_t) + + + MAX_NODES*sizeof(ia64_sal_ptc_domain_info_t) + + + MAX_CPUS*sizeof(ia64_sal_ptc_domain_proc_entry_t) + + + 1024)] __attribute__ ((aligned (8))); + +/* + * Very ugly, but we need this in the simulator only. Once we run on + * real hw, this can all go away. + */ +extern void pal_emulator_static (void); + +asm (" + .text + .proc pal_emulator_static +pal_emulator_static: + mov r8=-1 + cmp.eq p6,p7=6,r28 /* PAL_PTCE_INFO */ +(p7) br.cond.sptk.few 1f + ;; + mov r8=0 /* status = 0 */ + movl r9=0x500000000 /* tc.base */ + movl r10=0x0000000200000003 /* count[0], count[1] */ + movl r11=0x1000000000002000 /* stride[0], stride[1] */ + br.cond.sptk.few rp + +1: cmp.eq p6,p7=14,r28 /* PAL_FREQ_RATIOS */ +(p7) br.cond.sptk.few 1f + mov 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=22,r28 /* PAL_MC_DRAIN */ +(p7) br.cond.sptk.few 1f + mov r8=0 + br.cond.sptk.few rp + +1: cmp.eq p6,p7=23,r28 /* PAL_MC_EXPECTED */ +(p7) br.cond.sptk.few 1f + mov r8=0 + br.cond.sptk.few rp + +1: br.cond.sptk.few rp + .endp pal_emulator_static\n"); + + +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; +} + +static long +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) +{ + register long r9 asm ("r9") = 0; + register long r10 asm ("r10") = 0; + register long r11 asm ("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 = 1; + 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 { + status = -1; + } + ; + } else if (index == SAL_GET_STATE_INFO) { + ; + } else if (index == SAL_GET_STATE_INFO_SIZE) { + ; + } 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) { + ; + } else { + status = -1; + } + asm volatile ("" :: "r"(r9), "r"(r10), "r"(r11)); + return status; +} + + +/* + * 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 +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 acpi_rsdp_t *acpi_systab; + static acpi_rsdt_t *acpi_rsdt; + static acpi_sapic_t *acpi_sapic; + static acpi_entry_lsapic_t *acpi_lsapic; + static struct ia64_sal_systab *sal_systab; + 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 = 0; + static char *cp, *cmd_line, *vendor; + static int mdsize, domain, last_domain ; + static int cnode, nasid, cpu, num_memmd, cpus_found; + + /* + * Pass the parameter base address to the build_efi_xxx routines. + */ + build_init(8LL*GB*base_nasid); + + num_nodes = GetNumNodes(); + num_cpus = GetNumCpus(); + + + memset(fw_mem, 0, sizeof(fw_mem)); + + pal_desc = (unsigned long *) &pal_emulator_static; + sal_desc = (unsigned long *) &sal_emulator; + fix_function_pointer(&pal_emulator_static); + 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 += sizeof(*efi_systab); + efi_runtime = (void *) cp; cp += sizeof(*efi_runtime); + efi_tables = (void *) cp; cp += NUM_EFI_DESCS*sizeof(*efi_tables); + sal_systab = (void *) cp; cp += sizeof(*sal_systab); + sal_ed = (void *) cp; cp += sizeof(*sal_ed); + sal_ptc = (void *) cp; cp += sizeof(*sal_ptc); + sal_apwake = (void *) cp; cp += sizeof(*sal_apwake); + acpi_systab = (void *) cp; cp += sizeof(*acpi_systab); + acpi_rsdt = (void *) cp; cp += sizeof(*acpi_rsdt); + acpi_sapic = (void *) cp; cp += sizeof(*acpi_sapic); + acpi_lsapic = (void *) cp; cp += num_cpus*sizeof(*acpi_lsapic); + vendor = (char *) cp; cp += 32; + efi_memmap = (void *) cp; cp += 8*32*sizeof(*efi_memmap); + sal_ptcdi = (void *) cp; cp += CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi); + sal_ptclid = (void *) cp; cp += ((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'; +#ifdef BRINGUP + /* for now, just bring up bash */ + strcpy(cmd_line, "init=/bin/bash"); +#else + strcpy(cmd_line, ""); +#endif + + 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", 32); + + 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_success); + 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_TABLE_GUID; + efi_tables->table = __fwtab_pa(base_nasid, acpi_systab); + fix_function_pointer(&efi_unimplemented); + fix_function_pointer(&efi_get_time); + fix_function_pointer(&efi_success); + fix_function_pointer(&efi_reset_system); + + /* fill in the ACPI system table: */ + memcpy(acpi_systab->signature, "RSD PTR ", 8); + acpi_systab->rsdt = (acpi_rsdt_t*)__fwtab_pa(base_nasid, acpi_rsdt); + + memcpy(acpi_rsdt->header.signature, "RSDT",4); + acpi_rsdt->header.length = sizeof(acpi_rsdt_t); + memcpy(acpi_rsdt->header.oem_id, "SGI", 3); + memcpy(acpi_rsdt->header.oem_table_id, "SN1", 3); + acpi_rsdt->header.oem_revision = 0x00010001; + acpi_rsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_sapic); + + memcpy(acpi_sapic->header.signature, "SPIC ", 4); + acpi_sapic->header.length = sizeof(acpi_sapic_t)+num_cpus*sizeof(acpi_entry_lsapic_t); + for (cnode=0; cnodetype = ACPI_ENTRY_LOCAL_SAPIC; + acpi_lsapic->length = sizeof(acpi_entry_lsapic_t); + acpi_lsapic->acpi_processor_id = cnode*4+cpu; + acpi_lsapic->flags = LSAPIC_ENABLED|LSAPIC_PRESENT; + acpi_lsapic->eid = cpu; + acpi_lsapic->id = nasid; + acpi_lsapic++; + } + } + + + /* 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; + + strcpy(sal_systab->oem_id, "SGI"); + strcpy(sal_systab->product_id, "SN1"); + + /* 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; cnodenum_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 (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp) + checksum += *cp; + + sal_systab->checksum = -checksum; + + md = &efi_memmap[0]; + num_memmd = build_efi_memmap((void *)md, mdsize) ; + + bp = id(ZERO_PAGE_ADDR + (((long)base_nasid)<<33)); + 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->num_pci_vectors = 0; + 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 0) + continue; + return; + } + } +} diff -urN linux-2.4.0-test12/arch/ia64/sn/fprom/main.c linux-2.4.0-test12-lia/arch/ia64/sn/fprom/main.c --- linux-2.4.0-test12/arch/ia64/sn/fprom/main.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/fprom/main.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,110 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + + +#include +#include + +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>>24); + syn = (lid>>17)&1; + cpu = (lid>>16)&1; + + /* + * Now pick a synergy master to initialize synergy registers. + */ + if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) { + synergy_init(nasid, syn); + test_and_set_bit(syn+2, &nasidmaster[nasid]); + } else + while (get_bit(syn+2, &nasidmaster[nasid]) == 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 */ +} + + +void +synergy_init(int nasid, int syn) +{ + long *base; + long off; + + /* + * Enable all FSB flashed interrupts. + * ZZZ - 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] <-p> | <-k> [] + -p Create PROM control file & links + -k Create LINUX control file & links + -c Control file name [Default: cf] + 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 ] [-o ] [-M] [] + -c 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 # create control file (cf) & links for prom simulations + sim -k # 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 <>$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 + +# Numalink config +setenv route_enable on +setenv network_type xbar # Select [xbar|router] +setenv network_warning 0xff + +END +} + + +# ------------------ create control file entries for linux simulations ------------- +create_cf_linux() { +cat <>$CF +# Kernel specific options +setenv mca_on_memory_failure off +setenv LOADPC 0x00100000 # FPROM load address/entry point (8 digits!) +sr g 9 0xe000000000520000 # Kernel entry point +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 <>$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 Pr_ivt_gexx all +break Pr_ivt_brk all +break Pr_PROM_Panic_Spin all +break Pr_PROM_Panic all +break Pr_PROM_C_Panic all +break Pr_fled_die all +break Pr_ResetNow all +break Pr_zzzbkpt all + +END +} + + +# ------------------ create control file entries for memory configuration ------------- +create_cf_memory() { +cat <>$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 +# 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 +# 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 <>$CF +setenv node0_nasid 0 # cnode 0 has NASID 0 +setenv node0_memory_config 0xe1 # 32MB +END +else +cat <>$CF +setenv node0_memory_config 0x11 # 64MB +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 ] ; then + D=$D + else + err "cant determine directory for linux binaries" + fi + rm -rf vmlinux vmlinux.sym fprom + ln -s $D/vmlinux vmlinux + ln -s $D/vmlinux.sym vmlinux.sym + 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="$D/../../../../.setup" + grep -q '^ *setenv *PROMSIZE *8MB' $SETUP + if [ $? -eq 0 ] ; then + SIZE="8MB" + else + SIZE="4MB" + fi + grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP + EMBEDDED_LINUX=$? + rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom + SDIR="SN1IA${SIZE}.O" + BIN="SN1IAip37prom${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 + 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,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 +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 -urN linux-2.4.0-test12/arch/ia64/sn/io/Makefile linux-2.4.0-test12-lia/arch/ia64/sn/io/Makefile --- linux-2.4.0-test12/arch/ia64/sn/io/Makefile Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/Makefile Wed Dec 6 21:54:09 2000 @@ -0,0 +1,32 @@ +# +# 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 Silicon Graphics, Inc. +# Copyright (C) Jack Steiner (steiner@sgi.com) +# +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +EXTRA_CFLAGS := -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \ + -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \ + -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \ + -DNEW_INTERRUPTS -DCONFIG_IA64_SGI_IO +O_TARGET := sgiio.o +O_OBJS := stubs.o sgi_if.o pciio.o pcibr.o xtalk.o xbow.o xswitch.o hubspc.o \ + klgraph_hack.o io.o hubdev.o \ + hcl.o labelcl.o invent.o klgraph.o klconflib.o sgi_io_sim.o \ + module.o sgi_io_init.o klgraph_hack.o ml_SN_init.o \ + ml_SN_intr.o ip37.o \ + ml_iograph.o hcl_util.o cdl.o \ + mem_refcnt.o devsupport.o alenlist.o pci_bus_cvlink.o \ + eeprom.o pci.o pci_dma.o l1.o l1_command.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.0-test12/arch/ia64/sn/io/alenlist.c linux-2.4.0-test12-lia/arch/ia64/sn/io/alenlist.c --- linux-2.4.0-test12/arch/ia64/sn/io/alenlist.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/alenlist.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,901 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* Implementation of Address/Length Lists. */ + + +#include +#include +#include +#include +#include +#include + +/* + * Logically, an Address/Length List is a list of Pairs, where each pair + * holds an Address and a Length, all in some Address Space. In this + * context, "Address Space" is a particular Crosstalk Widget address + * space, a PCI device address space, a VME bus address space, a + * physical memory address space, etc. + * + * The main use for these Lists is to provide a single mechanism that + * describes where in an address space a DMA occurs. This allows the + * various I/O Bus support layers to provide a single interface for + * DMA mapping and DMA translation without regard to how the DMA target + * was specified by upper layers. The upper layers commonly specify a + * DMA target via a buf structure page list, a kernel virtual address, + * a user virtual address, a vector of addresses (a la uio and iov), + * or possibly a pfn list. + * + * Address/Length Lists also enable drivers to take advantage of their + * inate scatter/gather capabilities in systems where some address + * translation may be required between bus adapters. The driver forms + * a List that represents physical memory targets. This list is passed + * to the various adapters, which apply various translations. The final + * list that's returned to the driver is in terms of its local address + * address space -- addresses which can be passed off to a scatter/gather + * capable DMA controller. + * + * The current implementation is intended to be useful both in kernels + * that support interrupt threads (INTR_KTHREAD) and in systems that do + * not support interrupt threads. Of course, in the latter case, some + * interfaces can be called only within a suspendable context. + * + * Basic operations on Address/Length Lists include: + * alenlist_create Create a list + * alenlist_clear Clear a list + * alenlist_destroy Destroy a list + * alenlist_append Append a Pair to the end of a list + * alenlist_replace Replace a Pair in the middle of a list + * alenlist_get Get an Address/Length Pair from a list + * alenlist_size Return the number of Pairs in a list + * alenlist_concat Append one list to the end of another + * alenlist_clone Create a new copy of a list + * + * Operations that convert from upper-level specifications to Address/ + * Length Lists currently include: + * kvaddr_to_alenlist Convert from a kernel virtual address + * uvaddr_to_alenlist Convert from a user virtual address + * buf_to_alenlist Convert from a buf structure + * alenlist_done Tell system that we're done with an alenlist + * obtained from a conversion. + * Additional convenience operations: + * alenpair_init Create a list and initialize it with a Pair + * alenpair_get Peek at the first pair on a List + * + * A supporting type for Address/Length Lists is an alenlist_cursor_t. A + * cursor marks a position in a List, and determines which Pair is fetched + * by alenlist_get. + * alenlist_cursor_create Allocate and initialize a cursor + * alenlist_cursor_destroy Free space consumed by a cursor + * alenlist_cursor_init (Re-)Initialize a cursor to point + * to the start of a list + * alenlist_cursor_clone Clone a cursor (at the current offset) + * alenlist_cursor_offset Return the number of bytes into + * a list that this cursor marks + * Multiple cursors can point at various points into a List. Also, each + * list maintains one "internal cursor" which may be updated by alenlist_clear + * and alenlist_get. If calling code simply wishes to scan sequentially + * through a list starting at the beginning, and if it is the only user of + * a list, it can rely on this internal cursor rather than managing a + * separate explicit cursor. + * + * The current implementation allows callers to allocate both cursors and + * the lists as local stack (structure) variables. This allows for some + * extra efficiency at the expense of forward binary compatibility. It + * is recommended that customer drivers refrain from local allocation. + * In fact, we likely will choose to move the structures out of the public + * header file into a private place in order to discourage this usage. + * + * Currently, no locking is provided by the alenlist implementation. + * + * Implementation notes: + * For efficiency, Pairs are grouped into "chunks" of, say, 32 Pairs + * and a List consists of some number of these chunks. Chunks are completely + * invisible to calling code. Chunks should be large enough to hold most + * standard-sized DMA's, but not so large that they consume excessive space. + * + * It is generally expected that Lists will be constructed at one time and + * scanned at a later time. It is NOT expected that drivers will scan + * a List while the List is simultaneously extended, although this is + * theoretically possible with sufficient upper-level locking. + * + * In order to support demands of Real-Time drivers and in order to support + * swapping under low-memory conditions, we support the concept of a + * "pre-allocated fixed-sized List". After creating a List with + * alenlist_create, a driver may explicitly grow the list (via "alenlist_grow") + * to a specific number of Address/Length pairs. It is guaranteed that future + * operations involving this list will never automatically grow the list + * (i.e. if growth is ever required, the operation will fail). Additionally, + * operations that use alenlist's (e.g. DMA operations) accept a flag which + * causes processing to take place "in-situ"; that is, the input alenlist + * entries are replaced with output alenlist entries. The combination of + * pre-allocated Lists and in-situ processing allows us to avoid the + * potential deadlock scenario where we sleep (waiting for memory) in the + * swap out path. + * + * For debugging, we track the number of allocated Lists in alenlist_count + * the number of allocated chunks in alenlist_chunk_count, and the number + * of allocate cursors in alenlist_cursor_count. We also provide a debug + * routine, alenlist_show, which dumps the contents of an Address/Length List. + * + * Currently, Lists are formed by drivers on-demand. Eventually, we may + * associate an alenlist with a buf structure and keep it up to date as + * we go along. In that case, buf_to_alenlist simply returns a pointer + * to the existing List, and increments the Lists's reference count. + * alenlist_done would decrement the reference count and destroys the List + * if it was the last reference. + * + * Eventually alenlist's may allow better support for user-level scatter/ + * gather operations (e.g. via readv/writev): With proper support, we + * could potentially handle a vector of reads with a single scatter/gather + * DMA operation. This could be especially useful on NUMA systems where + * there's more of a reason for users to use vector I/O operations. + * + * Eventually, alenlist's may replace kaio lists, vhand page lists, + * buffer cache pfdat lists, DMA page lists, etc. + */ + +/* Opaque data types */ + +/* An Address/Length pair. */ +typedef struct alen_s { + alenaddr_t al_addr; + size_t al_length; +} alen_t; + +/* + * Number of elements in one chunk of an Address/Length List. + * + * This size should be sufficient to hold at least an "average" size + * DMA request. Must be at least 1, and should be a power of 2, + * for efficiency. + */ +#define ALEN_CHUNK_SZ ((512*1024)/NBPP) + +/* + * A fixed-size set of Address/Length Pairs. Chunks of Pairs are strung together + * to form a complete Address/Length List. Chunking is entirely hidden within the + * alenlist implementation, and it simply makes allocation and growth of lists more + * efficient. + */ +typedef struct alenlist_chunk_s { + alen_t alc_pair[ALEN_CHUNK_SZ];/* list of addr/len pairs */ + struct alenlist_chunk_s *alc_next; /* point to next chunk of pairs */ +} *alenlist_chunk_t; + +/* + * An Address/Length List. An Address/Length List is allocated with alenlist_create. + * Alternatively, a list can be allocated on the stack (local variable of type + * alenlist_t) and initialized with alenpair_init or with a combination of + * alenlist_clear and alenlist_append, etc. Code which statically allocates these + * structures loses forward binary compatibility! + * + * A statically allocated List is sufficiently large to hold ALEN_CHUNK_SZ pairs. + */ +struct alenlist_s { + unsigned short al_flags; + unsigned short al_logical_size; /* logical size of list, in pairs */ + unsigned short al_actual_size; /* actual size of list, in pairs */ + struct alenlist_chunk_s *al_last_chunk; /* pointer to last logical chunk */ + struct alenlist_cursor_s al_cursor; /* internal cursor */ + struct alenlist_chunk_s al_chunk; /* initial set of pairs */ + alenaddr_t al_compaction_address; /* used to compact pairs */ +}; + +/* al_flags field */ +#define AL_FIXED_SIZE 0x1 /* List is pre-allocated, and of fixed size */ + + +zone_t *alenlist_zone = NULL; +zone_t *alenlist_chunk_zone = NULL; +zone_t *alenlist_cursor_zone = NULL; + +#if DEBUG +int alenlist_count=0; /* Currently allocated Lists */ +int alenlist_chunk_count = 0; /* Currently allocated chunks */ +int alenlist_cursor_count = 0; /* Currently allocate cursors */ +#define INCR_COUNT(ptr) atomicAddInt((ptr), 1); +#define DECR_COUNT(ptr) atomicAddInt((ptr), -1); +#else +#define INCR_COUNT(ptr) +#define DECR_COUNT(ptr) +#endif /* DEBUG */ + +#if DEBUG +static void alenlist_show(alenlist_t); +#endif /* DEBUG */ + +/* + * Initialize Address/Length List management. One time initialization. + */ +void +alenlist_init(void) +{ + alenlist_zone = kmem_zone_init(sizeof(struct alenlist_s), "alenlist"); + alenlist_chunk_zone = kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk"); + alenlist_cursor_zone = kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor"); +#if DEBUG + idbg_addfunc("alenshow", alenlist_show); +#endif /* DEBUG */ +} + + +/* + * Initialize an Address/Length List cursor. + */ +static void +do_cursor_init(alenlist_t alenlist, alenlist_cursor_t cursorp) +{ + cursorp->al_alenlist = alenlist; + cursorp->al_offset = 0; + cursorp->al_chunk = &alenlist->al_chunk; + cursorp->al_index = 0; + cursorp->al_bcount = 0; +} + + +/* + * Create an Address/Length List, and clear it. + * Set the cursor to the beginning. + */ +alenlist_t +alenlist_create(unsigned flags) +{ + alenlist_t alenlist; + + alenlist = kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0); + if (alenlist) { + INCR_COUNT(&alenlist_count); + + alenlist->al_flags = 0; + alenlist->al_logical_size = 0; + alenlist->al_actual_size = ALEN_CHUNK_SZ; + alenlist->al_last_chunk = &alenlist->al_chunk; + alenlist->al_chunk.alc_next = NULL; + do_cursor_init(alenlist, &alenlist->al_cursor); + } + + return(alenlist); +} + + +/* + * Grow an Address/Length List so that all resources needed to contain + * the specified number of Pairs are pre-allocated. An Address/Length + * List that has been explicitly "grown" will never *automatically* + * grow, shrink, or be destroyed. + * + * Pre-allocation is useful for Real-Time drivers and for drivers that + * may be used along the swap-out path and therefore cannot afford to + * sleep until memory is freed. + * + * The cursor is set to the beginning of the list. + */ +int +alenlist_grow(alenlist_t alenlist, size_t npairs) +{ + /* + * This interface should be used relatively rarely, so + * the implementation is kept simple: We clear the List, + * then append npairs bogus entries. Finally, we mark + * the list as FIXED_SIZE and re-initialize the internal + * cursor. + */ + + /* + * Temporarily mark as non-fixed size, since we're about + * to shrink and expand it. + */ + alenlist->al_flags &= ~AL_FIXED_SIZE; + + /* Free whatever was in the alenlist. */ + alenlist_clear(alenlist); + + /* Allocate everything that we need via automatic expansion. */ + while (npairs--) + if (alenlist_append(alenlist, 0, 0, AL_NOCOMPACT) == ALENLIST_FAILURE) + return(ALENLIST_FAILURE); + + /* Now, mark as FIXED_SIZE */ + alenlist->al_flags |= AL_FIXED_SIZE; + + /* Clear out bogus entries */ + alenlist_clear(alenlist); + + /* Initialize internal cursor to the beginning */ + do_cursor_init(alenlist, &alenlist->al_cursor); + + return(ALENLIST_SUCCESS); +} + + +/* + * Clear an Address/Length List so that it holds no pairs. + */ +void +alenlist_clear(alenlist_t alenlist) +{ + alenlist_chunk_t chunk, freechunk; + + /* + * If this List is not FIXED_SIZE, free all the + * extra chunks. + */ + if (!(alenlist->al_flags & AL_FIXED_SIZE)) { + /* First, free any extension alenlist chunks */ + chunk = alenlist->al_chunk.alc_next; + while (chunk) { + freechunk = chunk; + chunk = chunk->alc_next; + kmem_zone_free(alenlist_chunk_zone, freechunk); + DECR_COUNT(&alenlist_chunk_count); + } + alenlist->al_actual_size = ALEN_CHUNK_SZ; + alenlist->al_chunk.alc_next = NULL; + } + + alenlist->al_logical_size = 0; + alenlist->al_last_chunk = &alenlist->al_chunk; + do_cursor_init(alenlist, &alenlist->al_cursor); +} + + +/* + * Create and initialize an Address/Length Pair. + * This is intended for degenerate lists, consisting of a single + * address/length pair. + */ +alenlist_t +alenpair_init( alenaddr_t address, + size_t length) +{ + alenlist_t alenlist; + + alenlist = alenlist_create(0); + + alenlist->al_logical_size = 1; + ASSERT(alenlist->al_last_chunk == &alenlist->al_chunk); + alenlist->al_chunk.alc_pair[0].al_length = length; + alenlist->al_chunk.alc_pair[0].al_addr = address; + + return(alenlist); +} + +/* + * Return address/length from a degenerate (1-pair) List, or + * first pair from a larger list. Does NOT update the internal cursor, + * so this is an easy way to peek at a start address. + */ +int +alenpair_get( alenlist_t alenlist, + alenaddr_t *address, + size_t *length) +{ + if (alenlist->al_logical_size == 0) + return(ALENLIST_FAILURE); + + *length = alenlist->al_chunk.alc_pair[0].al_length; + *address = alenlist->al_chunk.alc_pair[0].al_addr; + return(ALENLIST_SUCCESS); +} + + +/* + * Destroy an Address/Length List. + */ +void +alenlist_destroy(alenlist_t alenlist) +{ + if (alenlist == NULL) + return; + + /* + * Turn off FIXED_SIZE so this List can be + * automatically shrunk. + */ + alenlist->al_flags &= ~AL_FIXED_SIZE; + + /* Free extension chunks first */ + if (alenlist->al_chunk.alc_next) + alenlist_clear(alenlist); + + /* Now, free the alenlist itself */ + kmem_zone_free(alenlist_zone, alenlist); + DECR_COUNT(&alenlist_count); +} + +/* + * Release an Address/Length List. + * This is in preparation for a day when alenlist's may be longer-lived, and + * perhaps associated with a buf structure. We'd add a reference count, and + * this routine would decrement the count. For now, we create alenlist's on + * on demand and free them when done. If the driver is not explicitly managing + * a List for its own use, it should call alenlist_done rather than alenlist_destroy. + */ +void +alenlist_done(alenlist_t alenlist) +{ + alenlist_destroy(alenlist); +} + + +/* + * Append another address/length to the end of an Address/Length List, + * growing the list if permitted and necessary. + * + * Returns: SUCCESS/FAILURE + */ +int +alenlist_append( alenlist_t alenlist, /* append to this list */ + alenaddr_t address, /* address to append */ + size_t length, /* length to append */ + unsigned flags) +{ + alen_t *alenp; + int index, last_index; + + index = alenlist->al_logical_size % ALEN_CHUNK_SZ; + + if ((alenlist->al_logical_size > 0)) { + /* + * See if we can compact this new pair in with the previous entry. + * al_compaction_address holds that value that we'd need to see + * in order to compact. + */ + if (!(flags & AL_NOCOMPACT) && + (alenlist->al_compaction_address == address)) { + last_index = (alenlist->al_logical_size-1) % ALEN_CHUNK_SZ; + alenp = &(alenlist->al_last_chunk->alc_pair[last_index]); + alenp->al_length += length; + alenlist->al_compaction_address += length; + return(ALENLIST_SUCCESS); + } + + /* + * If we're out of room in this chunk, move to a new chunk. + */ + if (index == 0) { + if (alenlist->al_flags & AL_FIXED_SIZE) { + alenlist->al_last_chunk = alenlist->al_last_chunk->alc_next; + + /* If we're out of space in a FIXED_SIZE List, quit. */ + if (alenlist->al_last_chunk == NULL) { + ASSERT(alenlist->al_logical_size == alenlist->al_actual_size); + return(ALENLIST_FAILURE); + } + } else { + alenlist_chunk_t new_chunk; + + new_chunk = kmem_zone_alloc(alenlist_chunk_zone, + flags & AL_NOSLEEP ? VM_NOSLEEP : 0); + + if (new_chunk == NULL) + return(ALENLIST_FAILURE); + + alenlist->al_last_chunk->alc_next = new_chunk; + new_chunk->alc_next = NULL; + alenlist->al_last_chunk = new_chunk; + alenlist->al_actual_size += ALEN_CHUNK_SZ; + INCR_COUNT(&alenlist_chunk_count); + } + } + } + + alenp = &(alenlist->al_last_chunk->alc_pair[index]); + alenp->al_addr = address; + alenp->al_length = length; + + alenlist->al_logical_size++; + alenlist->al_compaction_address = address + length; + + return(ALENLIST_SUCCESS); +} + + +/* + * Replace an item in an Address/Length List. Cursor is updated so + * that alenlist_get will get the next item in the list. This interface + * is not very useful for drivers; but it is useful to bus providers + * that need to translate between address spaced in situ. The old Address + * and Length are returned. + */ +/* ARGSUSED */ +int +alenlist_replace( alenlist_t alenlist, /* in: replace in this list */ + alenlist_cursor_t cursorp, /* inout: which item to replace */ + alenaddr_t *addrp, /* inout: address */ + size_t *lengthp, /* inout: length */ + unsigned flags) +{ + alen_t *alenp; + alenlist_chunk_t chunk; + unsigned int index; + size_t length; + alenaddr_t addr; + + if ((addrp == NULL) || (lengthp == NULL)) + return(ALENLIST_FAILURE); + + if (alenlist->al_logical_size == 0) + return(ALENLIST_FAILURE); + + addr = *addrp; + length = *lengthp; + + /* + * If no cursor explicitly specified, use the Address/Length List's + * internal cursor. + */ + if (cursorp == NULL) + cursorp = &alenlist->al_cursor; + + chunk = cursorp->al_chunk; + index = cursorp->al_index; + + ASSERT(cursorp->al_alenlist == alenlist); + if (cursorp->al_alenlist != alenlist) + return(ALENLIST_FAILURE); + + alenp = &chunk->alc_pair[index]; + + /* Return old values */ + *addrp = alenp->al_length; + *lengthp = alenp->al_addr; + + /* Set up new values */ + alenp->al_length = length; + alenp->al_addr = addr; + + /* Update cursor to point to next item */ + cursorp->al_bcount = length; + + return(ALENLIST_SUCCESS); +} + + +/* + * Initialize a cursor in order to walk an alenlist. + * An alenlist_cursor always points to the last thing that was obtained + * from the list. If al_chunk is NULL, then nothing has yet been obtained. + * + * Note: There is an "internal cursor" associated with every Address/Length List. + * For users that scan sequentially through a List, it is more efficient to + * simply use the internal cursor. The caller must insure that no other users + * will simultaneously scan the List. The caller can reposition the internal + * cursor by calling alenlist_cursor_init with a NULL cursorp. + */ +int +alenlist_cursor_init(alenlist_t alenlist, size_t offset, alenlist_cursor_t cursorp) +{ + size_t byte_count; + + if (cursorp == NULL) + cursorp = &alenlist->al_cursor; + + /* Get internal cursor's byte count for use as a hint. + * + * If the internal cursor points passed the point that we're interested in, + * we need to seek forward from the beginning. Otherwise, we can seek forward + * from the internal cursor. + */ + if ((offset > 0) && + ((byte_count = alenlist_cursor_offset(alenlist, (alenlist_cursor_t)NULL)) <= offset)) { + offset -= byte_count; + alenlist_cursor_clone(alenlist, NULL, cursorp); + } else + do_cursor_init(alenlist, cursorp); + + /* We could easily speed this up, but it shouldn't be used very often. */ + while (offset != 0) { + alenaddr_t addr; + size_t length; + + if (alenlist_get(alenlist, cursorp, offset, &addr, &length, 0) != ALENLIST_SUCCESS) + return(ALENLIST_FAILURE); + offset -= length; + } + return(ALENLIST_SUCCESS); +} + + +/* + * Copy a cursor. The source cursor is either an internal alenlist cursor + * or an explicit cursor. + */ +int +alenlist_cursor_clone( alenlist_t alenlist, + alenlist_cursor_t cursorp_in, + alenlist_cursor_t cursorp_out) +{ + ASSERT(cursorp_out); + + if (alenlist && cursorp_in) + if (alenlist != cursorp_in->al_alenlist) + return(ALENLIST_FAILURE); + + if (alenlist) + *cursorp_out = alenlist->al_cursor; /* small structure copy */ + else if (cursorp_in) + *cursorp_out = *cursorp_in; /* small structure copy */ + else + return(ALENLIST_FAILURE); /* no source */ + + return(ALENLIST_SUCCESS); +} + +/* + * Return the number of bytes passed so far according to the specified cursor. + * If cursorp is NULL, use the alenlist's internal cursor. + */ +size_t +alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp) +{ + ASSERT(!alenlist || !cursorp || (alenlist == cursorp->al_alenlist)); + + if (cursorp == NULL) { + ASSERT(alenlist); + cursorp = &alenlist->al_cursor; + } + + return(cursorp->al_offset); +} + +/* + * Allocate and initialize an Address/Length List cursor. + */ +alenlist_cursor_t +alenlist_cursor_create(alenlist_t alenlist, unsigned flags) +{ + alenlist_cursor_t cursorp; + + ASSERT(alenlist != NULL); + cursorp = kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0); + if (cursorp) { + INCR_COUNT(&alenlist_cursor_count); + alenlist_cursor_init(alenlist, 0, cursorp); + } + return(cursorp); +} + +/* + * Free an Address/Length List cursor. + */ +void +alenlist_cursor_destroy(alenlist_cursor_t cursorp) +{ + DECR_COUNT(&alenlist_cursor_count); + kmem_zone_free(alenlist_cursor_zone, cursorp); +} + + +/* + * Fetch an address/length pair from an Address/Length List. Update + * the "cursor" so that next time this routine is called, we'll get + * the next address range. Never return a length that exceeds maxlength + * (if non-zero). If maxlength is a power of 2, never return a length + * that crosses a maxlength boundary. [This may seem strange at first, + * but it's what many drivers want.] + * + * Returns: SUCCESS/FAILURE + */ +int +alenlist_get( alenlist_t alenlist, /* in: get from this list */ + alenlist_cursor_t cursorp, /* inout: which item to get */ + size_t maxlength, /* in: at most this length */ + alenaddr_t *addrp, /* out: address */ + size_t *lengthp, /* out: length */ + unsigned flags) +{ + alen_t *alenp; + alenlist_chunk_t chunk; + unsigned int index; + size_t bcount; + size_t length; + + /* + * If no cursor explicitly specified, use the Address/Length List's + * internal cursor. + */ + if (cursorp == NULL) { + if (alenlist->al_logical_size == 0) + return(ALENLIST_FAILURE); + cursorp = &alenlist->al_cursor; + } + + chunk = cursorp->al_chunk; + index = cursorp->al_index; + bcount = cursorp->al_bcount; + + ASSERT(cursorp->al_alenlist == alenlist); + if (cursorp->al_alenlist != alenlist) + return(ALENLIST_FAILURE); + + alenp = &chunk->alc_pair[index]; + length = alenp->al_length - bcount; + + /* Bump up to next pair, if we're done with this pair. */ + if (length == 0) { + cursorp->al_bcount = bcount = 0; + cursorp->al_index = index = (index + 1) % ALEN_CHUNK_SZ; + + /* Bump up to next chunk, if we're done with this chunk. */ + if (index == 0) { + if (cursorp->al_chunk == alenlist->al_last_chunk) + return(ALENLIST_FAILURE); + chunk = chunk->alc_next; + ASSERT(chunk != NULL); + } else { + /* If in last chunk, don't go beyond end. */ + if (cursorp->al_chunk == alenlist->al_last_chunk) { + int last_size = alenlist->al_logical_size % ALEN_CHUNK_SZ; + if (last_size && (index >= last_size)) + return(ALENLIST_FAILURE); + } + } + + alenp = &chunk->alc_pair[index]; + length = alenp->al_length; + } + + /* Constrain what we return according to maxlength */ + if (maxlength) { + size_t maxlen1 = maxlength - 1; + + if ((maxlength & maxlen1) == 0) /* power of 2 */ + maxlength -= + ((alenp->al_addr + cursorp->al_bcount) & maxlen1); + + length = MIN(maxlength, length); + } + + /* Update the cursor, if desired. */ + if (!(flags & AL_LEAVE_CURSOR)) { + cursorp->al_bcount += length; + cursorp->al_chunk = chunk; + } + + *lengthp = length; + *addrp = alenp->al_addr + bcount; + + return(ALENLIST_SUCCESS); +} + + +/* + * Return the number of pairs in the specified Address/Length List. + * (For FIXED_SIZE Lists, this returns the logical size of the List, + * not the actual capacity of the List.) + */ +int +alenlist_size(alenlist_t alenlist) +{ + return(alenlist->al_logical_size); +} + + +/* + * Concatenate two Address/Length Lists. + */ +void +alenlist_concat(alenlist_t from, + alenlist_t to) +{ + struct alenlist_cursor_s cursor; + alenaddr_t addr; + size_t length; + + alenlist_cursor_init(from, 0, &cursor); + + while(alenlist_get(from, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS) + alenlist_append(to, addr, length, 0); +} + +/* + * Create a copy of a list. + * (Not all attributes of the old list are cloned. For instance, if + * a FIXED_SIZE list is cloned, the resulting list is NOT FIXED_SIZE.) + */ +alenlist_t +alenlist_clone(alenlist_t old_list, unsigned flags) +{ + alenlist_t new_list; + + new_list = alenlist_create(flags); + if (new_list != NULL) + alenlist_concat(old_list, new_list); + + return(new_list); +} + + +/* + * Convert a kernel virtual address to a Physical Address/Length List. + */ +alenlist_t +kvaddr_to_alenlist(alenlist_t alenlist, caddr_t kvaddr, size_t length, unsigned flags) +{ + alenaddr_t paddr; + long offset; + size_t piece_length; + int created_alenlist; + + if (length <=0) + return(NULL); + + /* If caller supplied a List, use it. Otherwise, allocate one. */ + if (alenlist == NULL) { + alenlist = alenlist_create(0); + created_alenlist = 1; + } else { + alenlist_clear(alenlist); + created_alenlist = 0; + } + + paddr = kvtophys(kvaddr); + offset = poff(kvaddr); + + /* Handle first page */ + piece_length = MIN(NBPP - offset, length); + if (alenlist_append(alenlist, paddr, piece_length, flags) == ALENLIST_FAILURE) + goto failure; + length -= piece_length; + kvaddr += piece_length; + + /* Handle middle pages */ + while (length >= NBPP) { + paddr = kvtophys(kvaddr); + if (alenlist_append(alenlist, paddr, NBPP, flags) == ALENLIST_FAILURE) + goto failure; + length -= NBPP; + kvaddr += NBPP; + } + + /* Handle last page */ + if (length) { + ASSERT(length < NBPP); + paddr = kvtophys(kvaddr); + if (alenlist_append(alenlist, paddr, length, flags) == ALENLIST_FAILURE) + goto failure; + } + + alenlist_cursor_init(alenlist, 0, NULL); + return(alenlist); + +failure: + if (created_alenlist) + alenlist_destroy(alenlist); + return(NULL); +} + + +#if DEBUG +static void +alenlist_show(alenlist_t alenlist) +{ + struct alenlist_cursor_s cursor; + alenaddr_t addr; + size_t length; + int i = 0; + + alenlist_cursor_init(alenlist, 0, &cursor); + + qprintf("Address/Length List@0x%x:\n", alenlist); + qprintf("logical size=0x%x actual size=0x%x last_chunk at 0x%x\n", + alenlist->al_logical_size, alenlist->al_actual_size, + alenlist->al_last_chunk); + qprintf("cursor: chunk=0x%x index=%d offset=0x%x\n", + alenlist->al_cursor.al_chunk, + alenlist->al_cursor.al_index, + alenlist->al_cursor.al_bcount); + while(alenlist_get(alenlist, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS) + qprintf("%d:\t0x%lx 0x%lx\n", ++i, addr, length); +} +#endif /* DEBUG */ diff -urN linux-2.4.0-test12/arch/ia64/sn/io/cdl.c linux-2.4.0-test12-lia/arch/ia64/sn/io/cdl.c --- linux-2.4.0-test12/arch/ia64/sn/io/cdl.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/cdl.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,231 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include "asm/sn/ioerror_handling.h" +#include + +#ifdef BRINGUP +/* these get called directly in cdl_add_connpt in fops bypass hack */ +extern int pcibr_attach(devfs_handle_t); +extern int xbow_attach(devfs_handle_t); +#endif /* BRINGUP */ + +/* + * cdl: Connection and Driver List + * + * We are not porting this to Linux. Devices are registered via + * the normal Linux PCI layer. This is a very simplified version + * of cdl that will allow us to register and call our very own + * IO Infrastructure Drivers e.g. pcibr. + */ + +struct cdl { + int part_num; + int mfg_num; + int (*attach) (devfs_handle_t); +} dummy_reg; + +typedef struct cdl *cdl_p; + +#define MAX_SGI_IO_INFRA_DRVR 4 +struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] = +{ + { XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */}, + { BRIDGE_WIDGET_PART_NUM, BRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops */}, + { XXBOW_WIDGET_PART_NUM, XXBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, + { XBOW_WIDGET_PART_NUM, XBOW_WIDGET_MFGR_NUM, xbow_attach /* &xbow_fops */}, +}; + +/* + * cdl_new: Called by pciio and xtalk. + */ +cdl_p +cdl_new(char *name, char *k1str, char *k2str) +{ + /* + * Just return a dummy pointer. + */ + return((cdl_p)&dummy_reg); +} + +/* + * cdl_del: Do nothing. + */ +void +cdl_del(cdl_p reg) +{ + printk("SGI IO INFRASTRUCTURE - cdl_del not supported.\n"); +} + +/* + * cdl_add_driver: The driver part number and manufacturers number + * are statically initialized above. + * + Do nothing. + */ +int +cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags) +{ + return 0; +} + +/* + * cdl_del_driver: Not supported. + */ +void +cdl_del_driver(cdl_p reg, + char *prefix) +{ + + printk("SGI IO INFRASTRUCTURE - cdl_del_driver not supported.\n"); +} + +/* + * cdl_add_connpt: We found a device and it's connect point. Call the + * attach routine of that driver. + * + * May need support for pciba registration here ... + * + * This routine use to create /hw/.id/pci/.../.. that links to + * /hw/module/006c06/Pbrick/xtalk/15/pci/ .. do we still need + * it? The specified driver attach routine does not reference these + * vertices. + */ +int +cdl_add_connpt(cdl_p reg, int part_num, int mfg_num, + devfs_handle_t connpt) +{ + int i; + + /* + * Find the driver entry point and call the attach routine. + */ + for (i = 0; i < MAX_SGI_IO_INFRA_DRVR; i++) { + + if ( (part_num == sgi_infrastructure_drivers[i].part_num) && + ( mfg_num == sgi_infrastructure_drivers[i].mfg_num) ) { + /* + * Call the device attach routines. + */ + if (sgi_infrastructure_drivers[i].attach) { + return(sgi_infrastructure_drivers[i].attach(connpt)); + } +#ifdef BRINGUP + /* + * XXX HACK ALERT bypassing fops for now.. + */ + else { + printk("cdl_add_connpt: NEED FOPS FOR OUR DRIVERS!!\n"); + printk("cdl_add_connpt: part_num= 0x%x mfg_num= 0x%x\n", + part_num, mfg_num); + return(-1); + } +#endif /* BRINGUP */ + } else { + continue; + } + + printk("**** cdl_add_connpt: driver not found for part_num %d mfg_num %d ****\n", part_num, mfg_num); + + return(-1); + } + if ( (i == MAX_SGI_IO_INFRA_DRVR) ) + printk("**** cdl_add_connpt: Driver not found for part_num 0x%x mfg_num 0x%x ****\n", part_num, mfg_num); + + return (0); +} + +/* + * cdl_del_connpt: Not implemented. + */ +void +cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt) +{ + + printk("SGI IO INFRASTRUCTURE - cdl_del_cdl_del_connpt not supported.\n"); +} + +/* + * cdl_iterate: Not Implemented. + */ +void +cdl_iterate(cdl_p reg, + char *prefix, + cdl_iter_f * func) +{ + + printk("SGI IO INFRASTRUCTURE - cdl_iterate not supported.\n"); +} + +async_attach_t +async_attach_new(void) +{ + + printk("SGI IO INFRASTRUCTURE - async_attach_new not supported.\n"); + return(0); +} + +void +async_attach_free(async_attach_t aa) +{ + printk("SGI IO INFRASTRUCTURE - async_attach_free not supported.\n"); +} + +async_attach_t +async_attach_get_info(devfs_handle_t vhdl) +{ + + printk("SGI IO INFRASTRUCTURE - async_attach_get_info not supported.\n"); + return(0); +} + +void +async_attach_add_info(devfs_handle_t vhdl, async_attach_t aa) +{ + printk("SGI IO INFRASTRUCTURE - async_attach_add_info not supported.\n"); + +} + +void +async_attach_del_info(devfs_handle_t vhdl) +{ + + printk("SGI IO INFRASTRUCTURE - async_attach_del_info not supported.\n"); + +} + +void async_attach_signal_start(async_attach_t aa) +{ + + printk("SGI IO INFRASTRUCTURE - async_attach_signal_start not supported.\n"); + +} + +void async_attach_signal_done(async_attach_t aa) +{ + + printk("SGI IO INFRASTRUCTURE - async_attach_signal_done not supported.\n"); + +} + +void async_attach_waitall(async_attach_t aa) +{ + + printk("SGI IO INFRASTRUCTURE - async_attach_waitall not supported.\n"); + +} + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/devsupport.c linux-2.4.0-test12-lia/arch/ia64/sn/io/devsupport.c --- linux-2.4.0-test12/arch/ia64/sn/io/devsupport.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/devsupport.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,1292 @@ +#define ilvt_t int + +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Interfaces in this file are all platform-independent AND IObus-independent. + * Be aware that there may be macro equivalents to each of these hiding in + * header files which supercede these functions. + */ + +/* =====Generic iobus support===== */ + +/* String table to hold names of interrupts. */ +#ifdef notyet +static struct string_table device_desc_string_table; +#endif + +/* One time initialization for device descriptor support. */ +static void +device_desc_init(void) +{ +#ifdef notyet + string_table_init(&device_desc_string_table); +#endif + FIXME("device_desc_init"); +} + + +/* Drivers use these interfaces to manage device descriptors */ +static device_desc_t +device_desc_alloc(void) +{ +#ifdef notyet + device_desc_t device_desc; + + device_desc = (device_desc_t)kmem_zalloc(sizeof(struct device_desc_s), 0); + device_desc->intr_target = GRAPH_VERTEX_NONE; + + ASSERT(device_desc->intr_policy == 0); + device_desc->intr_swlevel = -1; + ASSERT(device_desc->intr_name == NULL); + ASSERT(device_desc->flags == 0); + + ASSERT(!(device_desc->flags & D_IS_ASSOC)); + return(device_desc); +#else + FIXME("device_desc_alloc"); + return((device_desc_t)0); +#endif +} + +void +device_desc_free(device_desc_t device_desc) +{ +#ifdef notyet + if (!(device_desc->flags & D_IS_ASSOC)) /* sanity */ + kfree(device_desc); +#endif + FIXME("device_desc_free"); +} + +device_desc_t +device_desc_dup(devfs_handle_t dev) +{ +#ifdef notyet + device_desc_t orig_device_desc, new_device_desc; + + + new_device_desc = device_desc_alloc(); + orig_device_desc = device_desc_default_get(dev); + if (orig_device_desc) + *new_device_desc = *orig_device_desc;/* small structure copy */ + else { + device_driver_t driver; + ilvl_t pri; + /* + * Use the driver's thread priority in + * case the device thread priority has not + * been given. + */ + if (driver = device_driver_getbydev(dev)) { + pri = device_driver_thread_pri_get(driver); + device_desc_intr_swlevel_set(new_device_desc,pri); + } + } + new_device_desc->flags &= ~D_IS_ASSOC; + return(new_device_desc); +#else + FIXME("device_desc_dup"); + return((device_desc_t)0); +#endif +} + +device_desc_t +device_desc_default_get(devfs_handle_t dev) +{ +#ifdef notyet + graph_error_t rc; + device_desc_t device_desc; + + rc = hwgraph_info_get_LBL(dev, INFO_LBL_DEVICE_DESC, (arbitrary_info_t *)&device_desc); + + if (rc == GRAPH_SUCCESS) + return(device_desc); + else + return(NULL); +#else + FIXME("device_desc_default_get"); + return((device_desc_t)0); +#endif +} + +void +device_desc_default_set(devfs_handle_t dev, device_desc_t new_device_desc) +{ +#ifdef notyet + graph_error_t rc; + device_desc_t old_device_desc = NULL; + + if (new_device_desc) { + new_device_desc->flags |= D_IS_ASSOC; + rc = hwgraph_info_add_LBL(dev, INFO_LBL_DEVICE_DESC, + (arbitrary_info_t)new_device_desc); + if (rc == GRAPH_DUP) { + rc = hwgraph_info_replace_LBL(dev, INFO_LBL_DEVICE_DESC, + (arbitrary_info_t)new_device_desc, + (arbitrary_info_t *)&old_device_desc); + + ASSERT(rc == GRAPH_SUCCESS); + } + hwgraph_info_export_LBL(dev, INFO_LBL_DEVICE_DESC, + sizeof(struct device_desc_s)); + } else { + rc = hwgraph_info_remove_LBL(dev, INFO_LBL_DEVICE_DESC, + (arbitrary_info_t *)&old_device_desc); + } + + if (old_device_desc) { + ASSERT(old_device_desc->flags & D_IS_ASSOC); + old_device_desc->flags &= ~D_IS_ASSOC; + device_desc_free(old_device_desc); + } +#endif + FIXME("device_desc_default_set"); +} + +devfs_handle_t +device_desc_intr_target_get(device_desc_t device_desc) +{ +#ifdef notyet + return(device_desc->intr_target); +#else + FIXME("device_desc_intr_target_get"); + return((devfs_handle_t)0); +#endif +} + +int +device_desc_intr_policy_get(device_desc_t device_desc) +{ +#ifdef notyet + return(device_desc->intr_policy); +#else + FIXME("device_desc_intr_policy_get"); + return(0); +#endif +} + +ilvl_t +device_desc_intr_swlevel_get(device_desc_t device_desc) +{ +#ifdef notyet + return(device_desc->intr_swlevel); +#else + FIXME("device_desc_intr_swlevel_get"); + return((ilvl_t)0); +#endif +} + +char * +device_desc_intr_name_get(device_desc_t device_desc) +{ +#ifdef notyet + return(device_desc->intr_name); +#else + FIXME("device_desc_intr_name_get"); + return(NULL); +#endif +} + +int +device_desc_flags_get(device_desc_t device_desc) +{ +#ifdef notyet + return(device_desc->flags); +#else + FIXME("device_desc_flags_get"); + return(0); +#endif +} + +void +device_desc_intr_target_set(device_desc_t device_desc, devfs_handle_t target) +{ + if ( device_desc != (device_desc_t)0 ) + device_desc->intr_target = target; +} + +void +device_desc_intr_policy_set(device_desc_t device_desc, int policy) +{ + if ( device_desc != (device_desc_t)0 ) + device_desc->intr_policy = policy; +} + +void +device_desc_intr_swlevel_set(device_desc_t device_desc, ilvl_t swlevel) +{ + if ( device_desc != (device_desc_t)0 ) + device_desc->intr_swlevel = swlevel; +} + +void +device_desc_intr_name_set(device_desc_t device_desc, char *name) +{ +#ifdef notyet + if ( device_desc != (device_desc_t)0 ) + device_desc->intr_name = string_table_insert(&device_desc_string_table, name); +#else + FIXME("device_desc_intr_name_set"); +#endif +} + +void +device_desc_flags_set(device_desc_t device_desc, int flags) +{ + if ( device_desc != (device_desc_t)0 ) + device_desc->flags = flags; +} + + + +/*============= device admin registry routines ===================== */ + +/* Linked list of pairs */ +typedef struct dev_admin_list_s { + struct dev_admin_list_s *admin_next; /* next entry in the + * list + */ + char *admin_name; /* info label */ + char *admin_val; /* actual info */ +} dev_admin_list_t; + +/* Device/Driver administration registry */ +typedef struct dev_admin_registry_s { + mrlock_t reg_lock; /* To allow + * exclusive + * access + */ + dev_admin_list_t *reg_first; /* first entry in + * the list + */ + dev_admin_list_t **reg_last; /* pointer to the + * next to last entry + * in the last which + * is also the place + * where the new + * entry gets + * inserted + */ +} dev_admin_registry_t; + +/* +** device_driver_s associates a device driver prefix with device switch entries. +*/ +struct device_driver_s { + struct device_driver_s *dd_next; /* next element on hash chain */ + struct device_driver_s *dd_prev; /* previous element on hash chain */ + char *dd_prefix; /* driver prefix string */ + struct bdevsw *dd_bdevsw; /* driver's bdevsw */ + struct cdevsw *dd_cdevsw; /* driver's cdevsw */ + + /* driver administration specific data structures need to + * maintain the list of pairs + */ + dev_admin_registry_t dd_dev_admin_registry; + ilvl_t dd_thread_pri; /* default thread priority for + * all this driver's + * threads. + */ + +}; + +#define NEW(_p) (_p = kmalloc(sizeof(*_p), GFP_KERNEL)) +#define FREE(_p) (kmem_free(_p)) + +/* + * helpful lock macros + */ + +#define DEV_ADMIN_REGISTRY_INITLOCK(lockp,name) mrinit(lockp,name) +#define DEV_ADMIN_REGISTRY_RDLOCK(lockp) mraccess(lockp) +#define DEV_ADMIN_REGISTRY_WRLOCK(lockp) mrupdate(lockp) +#define DEV_ADMIN_REGISTRY_UNLOCK(lockp) mrunlock(lockp) + +/* Initialize the registry + */ +static void +dev_admin_registry_init(dev_admin_registry_t *registry) +{ +#ifdef notyet + if ( registry != (dev_admin_registry_t *)0 ) + DEV_ADMIN_REGISTRY_INITLOCK(®istry->reg_lock, + "dev_admin_registry_lock"); + registry->reg_first = NULL; + registry->reg_last = ®istry->reg_first; + } +#else + FIXME("dev_admin_registry_init"); +#endif +} + +/* + * add an entry to the dev admin registry. + * if the name already exists in the registry then change the + * value iff the new value differs from the old value. + * if the name doesn't exist a new list entry is created and put + * at the end. + */ +static void +dev_admin_registry_add(dev_admin_registry_t *registry, + char *name, + char *val) +{ +#ifdef notyet + dev_admin_list_t *reg_entry; + dev_admin_list_t *scan = 0; + + DEV_ADMIN_REGISTRY_WRLOCK(®istry->reg_lock); + + /* check if the name already exists in the registry */ + scan = registry->reg_first; + + while (scan) { + if (strcmp(scan->admin_name,name) == 0) { + /* name is there in the registry */ + if (strcmp(scan->admin_val,val)) { + /* old value != new value + * reallocate memory and copy the new value + */ + FREE(scan->admin_val); + scan->admin_val = + (char *)kern_calloc(1,strlen(val)+1); + strcpy(scan->admin_val,val); + goto out; + } + goto out; /* old value == new value */ + } + scan = scan->admin_next; + } + + /* name is not there in the registry. + * allocate memory for the new registry entry + */ + NEW(reg_entry); + + reg_entry->admin_next = 0; + reg_entry->admin_name = (char *)kern_calloc(1,strlen(name)+1); + strcpy(reg_entry->admin_name,name); + reg_entry->admin_val = (char *)kern_calloc(1,strlen(val)+1); + strcpy(reg_entry->admin_val,val); + + /* add the entry at the end of the registry */ + + *(registry->reg_last) = reg_entry; + registry->reg_last = ®_entry->admin_next; + +out: DEV_ADMIN_REGISTRY_UNLOCK(®istry->reg_lock); +#endif + FIXME("dev_admin_registry_add"); +} +/* + * check if there is an info corr. to a particular + * name starting from the cursor position in the + * registry + */ +static char * +dev_admin_registry_find(dev_admin_registry_t *registry,char *name) +{ +#ifdef notyet + dev_admin_list_t *scan = 0; + + DEV_ADMIN_REGISTRY_RDLOCK(®istry->reg_lock); + scan = registry->reg_first; + + while (scan) { + if (strcmp(scan->admin_name,name) == 0) { + DEV_ADMIN_REGISTRY_UNLOCK(®istry->reg_lock); + return scan->admin_val; + } + scan = scan->admin_next; + } + DEV_ADMIN_REGISTRY_UNLOCK(®istry->reg_lock); + return 0; +#else + FIXME("dev_admin_registry_find"); + return(NULL); +#endif +} +/*============= MAIN DEVICE/ DRIVER ADMINISTRATION INTERFACE================ */ +/* + * return any labelled info associated with a device. + * called by any kernel code including device drivers. + */ +char * +device_admin_info_get(devfs_handle_t dev_vhdl, + char *info_lbl) +{ +#ifdef notyet + char *info = 0; + + /* return value need not be GRAPH_SUCCESS as the labelled + * info may not be present + */ + (void)hwgraph_info_get_LBL(dev_vhdl,info_lbl, + (arbitrary_info_t *)&info); + + + return info; +#else + FIXME("device_admin_info_get"); + return(NULL); +#endif +} + +/* + * set labelled info associated with a device. + * called by hwgraph infrastructure . may also be called + * by device drivers etc. + */ +int +device_admin_info_set(devfs_handle_t dev_vhdl, + char *dev_info_lbl, + char *dev_info_val) +{ +#ifdef notyet + graph_error_t rv; + arbitrary_info_t old_info; + + /* Handle the labelled info + * intr_target + * sw_level + * in a special way. These are part of device_desc_t + * Right now this is the only case where we have + * a set of related device_admin attributes which + * are grouped together. + * In case there is a need for another set we need to + * take a more generic approach to solving this. + * Basically a registry should be implemented. This + * registry is initialized with the callbacks for the + * attributes which need to handled in a special way + * For example: + * Consider + * device_desc + * intr_target + * intr_swlevel + * register "do_intr_target" for intr_target + * register "do_intr_swlevel" for intr_swlevel. + * When the device_admin interface layer gets an pair + * it looks in the registry to see if there is a function registered to + * handle "attr. If not follow the default path of setting the + * as labelled information hanging off the vertex. + * In the above example: + * "do_intr_target" does what is being done below for the ADMIN_LBL_INTR_TARGET + * case + */ + if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_TARGET) || + !strcmp(dev_info_lbl,ADMIN_LBL_INTR_SWLEVEL)) { + + device_desc_t device_desc; + + /* Check if there is a default device descriptor + * information for this vertex. If not dup one . + */ + if (!(device_desc = device_desc_default_get(dev_vhdl))) { + device_desc = device_desc_dup(dev_vhdl); + device_desc_default_set(dev_vhdl,device_desc); + + } + if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_TARGET)) { + /* Check if a target cpu has been specified + * for this device by a device administration + * directive + */ +#ifdef DEBUG + printf(ADMIN_LBL_INTR_TARGET + " dev = 0x%x " + "dev_admin_info = %s" + " target = 0x%x\n", + dev_vhdl, + dev_info_lbl, + hwgraph_path_to_vertex(dev_info_val)); +#endif + + device_desc->intr_target = + hwgraph_path_to_vertex(dev_info_val); + } else if (!strcmp(dev_info_lbl,ADMIN_LBL_INTR_SWLEVEL)) { + /* Check if the ithread priority level has been + * specified for this device by a device administration + * directive + */ +#ifdef DEBUG + printf(ADMIN_LBL_INTR_SWLEVEL + " dev = 0x%x " + "dev_admin_info = %s" + " sw level = 0x%x\n", + dev_vhdl, + dev_info_lbl, + atoi(dev_info_val)); +#endif + device_desc->intr_swlevel = atoi(dev_info_val); + } + + } + if (!dev_info_val) + rv = hwgraph_info_remove_LBL(dev_vhdl, + dev_info_lbl, + &old_info); + else { + + rv = hwgraph_info_add_LBL(dev_vhdl, + dev_info_lbl, + (arbitrary_info_t)dev_info_val); + + if (rv == GRAPH_DUP) { + rv = hwgraph_info_replace_LBL(dev_vhdl, + dev_info_lbl, + (arbitrary_info_t)dev_info_val, + &old_info); + } + } + ASSERT(rv == GRAPH_SUCCESS); +#endif + FIXME("device_admin_info_set"); + return 0; +} + +/* + * return labelled info associated with a device driver + * called by kernel code including device drivers + */ +char * +device_driver_admin_info_get(char *driver_prefix, + char *driver_info_lbl) +{ +#ifdef notyet + device_driver_t driver; + + driver = device_driver_get(driver_prefix); + return (dev_admin_registry_find(&driver->dd_dev_admin_registry, + driver_info_lbl)); +#else + FIXME("device_driver_admin_info_get"); + return(NULL); +#endif +} + +/* + * set labelled info associated with a device driver. + * called by hwgraph infrastructure . may also be called + * from drivers etc. + */ +int +device_driver_admin_info_set(char *driver_prefix, + char *driver_info_lbl, + char *driver_info_val) +{ +#ifdef notyet + device_driver_t driver; + + driver = device_driver_get(driver_prefix); + dev_admin_registry_add(&driver->dd_dev_admin_registry, + driver_info_lbl, + driver_info_val); +#endif + FIXME("device_driver_admin_info_set"); + return 0; +} +/*================== device / driver admin support routines================*/ + +/* static tables created by lboot */ +extern dev_admin_info_t dev_admin_table[]; +extern dev_admin_info_t drv_admin_table[]; +extern int dev_admin_table_size; +extern int drv_admin_table_size; + +/* Extend the device admin table to allow the kernel startup code to + * provide some device specific administrative hints + */ +#define ADMIN_TABLE_CHUNK 100 +static dev_admin_info_t extended_dev_admin_table[ADMIN_TABLE_CHUNK]; +static int extended_dev_admin_table_size = 0; +static mrlock_t extended_dev_admin_table_lock; + +/* Initialize the extended device admin table */ +void +device_admin_table_init(void) +{ +#ifdef notyet + extended_dev_admin_table_size = 0; + mrinit(&extended_dev_admin_table_lock, + "extended_dev_admin_table_lock"); +#endif + FIXME("device_admin_table_init"); +} +/* Add triple to + * the extended device administration info table. This is helpful + * for kernel startup code to put some hints before the hwgraph + * is setup + */ +void +device_admin_table_update(char *name,char *label,char *value) +{ +#ifdef notyet + dev_admin_info_t *p; + + mrupdate(&extended_dev_admin_table_lock); + + /* Safety check that we haven't exceeded array limits */ + ASSERT(extended_dev_admin_table_size < ADMIN_TABLE_CHUNK); + + if (extended_dev_admin_table_size == ADMIN_TABLE_CHUNK) + goto out; + + /* Get the pointer to the entry in the table where we are + * going to put the new information + */ + p = &extended_dev_admin_table[extended_dev_admin_table_size++]; + + /* Allocate memory for the strings and copy them in */ + p->dai_name = (char *)kern_calloc(1,strlen(name)+1); + strcpy(p->dai_name,name); + p->dai_param_name = (char *)kern_calloc(1,strlen(label)+1); + strcpy(p->dai_param_name,label); + p->dai_param_val = (char *)kern_calloc(1,strlen(value)+1); + strcpy(p->dai_param_val,value); + +out: mrunlock(&extended_dev_admin_table_lock); +#endif + FIXME("device_admin_table_update"); +} +/* Extend the device driver admin table to allow the kernel startup code to + * provide some device driver specific administrative hints + */ + +static dev_admin_info_t extended_drv_admin_table[ADMIN_TABLE_CHUNK]; +static int extended_drv_admin_table_size = 0; +mrlock_t extended_drv_admin_table_lock; + +/* Initialize the extended device driver admin table */ +void +device_driver_admin_table_init(void) +{ +#ifdef notyet + extended_drv_admin_table_size = 0; + mrinit(&extended_drv_admin_table_lock, + "extended_drv_admin_table_lock"); +#endif + FIXME("device_driver_admin_table_init"); +} +/* Add triple to + * the extended device administration info table. This is helpful + * for kernel startup code to put some hints before the hwgraph + * is setup + */ +void +device_driver_admin_table_update(char *name,char *label,char *value) +{ +#ifdef notyet + dev_admin_info_t *p; + + mrupdate(&extended_dev_admin_table_lock); + + /* Safety check that we haven't exceeded array limits */ + ASSERT(extended_drv_admin_table_size < ADMIN_TABLE_CHUNK); + + if (extended_drv_admin_table_size == ADMIN_TABLE_CHUNK) + goto out; + + /* Get the pointer to the entry in the table where we are + * going to put the new information + */ + p = &extended_drv_admin_table[extended_drv_admin_table_size++]; + + /* Allocate memory for the strings and copy them in */ + p->dai_name = (char *)kern_calloc(1,strlen(name)+1); + strcpy(p->dai_name,name); + p->dai_param_name = (char *)kern_calloc(1,strlen(label)+1); + strcpy(p->dai_param_name,label); + p->dai_param_val = (char *)kern_calloc(1,strlen(value)+1); + strcpy(p->dai_param_val,value); + +out: mrunlock(&extended_drv_admin_table_lock); +#endif + FIXME("device_driver_admin_table_update"); +} +/* + * keeps on adding the labelled info for each new (lbl,value) pair + * that it finds in the static dev admin table ( created by lboot) + * and the extended dev admin table ( created if at all by the kernel startup + * code) corresponding to a device in the hardware graph. + */ +void +device_admin_info_update(devfs_handle_t dev_vhdl) +{ +#ifdef notyet + int i = 0; + dev_admin_info_t *scan; + devfs_handle_t scan_vhdl; + + /* Check the static device administration info table */ + scan = dev_admin_table; + while (i < dev_admin_table_size) { + + scan_vhdl = hwgraph_path_to_dev(scan->dai_name); + if (scan_vhdl == dev_vhdl) { + device_admin_info_set(dev_vhdl, + scan->dai_param_name, + scan->dai_param_val); + } + if (scan_vhdl != NODEV) + hwgraph_vertex_unref(scan_vhdl); + scan++;i++; + + } + i = 0; + /* Check the extended device administration info table */ + scan = extended_dev_admin_table; + while (i < extended_dev_admin_table_size) { + scan_vhdl = hwgraph_path_to_dev(scan->dai_name); + if (scan_vhdl == dev_vhdl) { + device_admin_info_set(dev_vhdl, + scan->dai_param_name, + scan->dai_param_val); + } + if (scan_vhdl != NODEV) + hwgraph_vertex_unref(scan_vhdl); + scan++;i++; + + } + + +#endif + FIXME("device_admin_info_update"); +} + +/* looks up the static drv admin table ( created by the lboot) and the extended + * drv admin table (created if at all by the kernel startup code) + * for this driver specific administration info and adds it to the admin info + * associated with this device driver's object + */ +void +device_driver_admin_info_update(device_driver_t driver) +{ +#ifdef notyet + int i = 0; + dev_admin_info_t *scan; + + /* Check the static device driver administration info table */ + scan = drv_admin_table; + while (i < drv_admin_table_size) { + + if (strcmp(scan->dai_name,driver->dd_prefix) == 0) { + dev_admin_registry_add(&driver->dd_dev_admin_registry, + scan->dai_param_name, + scan->dai_param_val); + } + scan++;i++; + } + i = 0; + /* Check the extended device driver administration info table */ + scan = extended_drv_admin_table; + while (i < extended_drv_admin_table_size) { + + if (strcmp(scan->dai_name,driver->dd_prefix) == 0) { + dev_admin_registry_add(&driver->dd_dev_admin_registry, + scan->dai_param_name, + scan->dai_param_val); + } + scan++;i++; + } +#endif + FIXME("device_driver_admin_info_update"); +} + +/* =====Device Driver Support===== */ + + + +/* +** Generic device driver support routines for use by kernel modules that +** deal with device drivers (but NOT for use by the drivers themselves). +** EVERY registered driver currently in the system -- static or loadable -- +** has an entry in the device_driver_hash table. A pointer to such an entry +** serves as a generic device driver handle. +*/ + +#define DEVICE_DRIVER_HASH_SIZE 32 +#ifdef notyet +lock_t device_driver_lock[DEVICE_DRIVER_HASH_SIZE]; +device_driver_t device_driver_hash[DEVICE_DRIVER_HASH_SIZE]; +static struct string_table driver_prefix_string_table; +#endif + +/* +** Initialize device driver infrastructure. +*/ +void +device_driver_init(void) +{ +#ifdef notyet + int i; + extern void alenlist_init(void); + extern void hwgraph_init(void); + extern void device_desc_init(void); + + ASSERT(DEVICE_DRIVER_NONE == NULL); + alenlist_init(); + hwgraph_init(); + device_desc_init(); + + string_table_init(&driver_prefix_string_table); + + for (i=0; isdd_prefix); + if (!driver) + driver = device_driver_alloc(desc->sdd_prefix); + pri = device_driver_sysgen_thread_pri_get(desc->sdd_prefix); + device_driver_thread_pri_set(driver, pri); + device_driver_devsw_put(driver, desc->sdd_bdevsw, desc->sdd_cdevsw); + } +#endif + FIXME("device_driver_init"); +} + +/* +** Hash a prefix string into a hash table chain. +*/ +static int +driver_prefix_hash(char *prefix) +{ +#ifdef notyet + int accum = 0; + char nextchar; + + while (nextchar = *prefix++) + accum = accum ^ nextchar; + + return(accum % DEVICE_DRIVER_HASH_SIZE); +#else + FIXME("driver_prefix_hash"); + return(0); +#endif +} + + +/* +** Allocate a driver handle. +** Returns the driver handle, or NULL if the driver prefix +** already has a handle. +** +** Upper layers prevent races among device_driver_alloc, +** device_driver_free, and device_driver_get*. +*/ +device_driver_t +device_driver_alloc(char *prefix) +{ +#ifdef notyet + int which_hash; + device_driver_t new_driver; + int s; + + which_hash = driver_prefix_hash(prefix); + + new_driver = kern_calloc(1, sizeof(*new_driver)); + ASSERT(new_driver != NULL); + new_driver->dd_prev = NULL; + new_driver->dd_prefix = string_table_insert(&driver_prefix_string_table, prefix); + new_driver->dd_bdevsw = NULL; + new_driver->dd_cdevsw = NULL; + + dev_admin_registry_init(&new_driver->dd_dev_admin_registry); + device_driver_admin_info_update(new_driver); + + s = mutex_spinlock(&device_driver_lock[which_hash]); + +#if DEBUG + { + device_driver_t drvscan; + + /* Make sure we haven't already added a driver with this prefix */ + drvscan = device_driver_hash[which_hash]; + while (drvscan && + strcmp(drvscan->dd_prefix, prefix)) { + drvscan = drvscan->dd_next; + } + + ASSERT(!drvscan); + } +#endif /* DEBUG */ + + + /* Add new_driver to front of hash chain. */ + new_driver->dd_next = device_driver_hash[which_hash]; + if (new_driver->dd_next) + new_driver->dd_next->dd_prev = new_driver; + device_driver_hash[which_hash] = new_driver; + + mutex_spinunlock(&device_driver_lock[which_hash], s); + + return(new_driver); +#else + FIXME("device_driver_alloc"); + return((device_driver_t)0); +#endif +} + +/* +** Free a driver handle. +** +** Statically loaded drivers should never device_driver_free. +** Dynamically loaded drivers device_driver_free when either an +** unloaded driver is unregistered, or when an unregistered driver +** is unloaded. +*/ +void +device_driver_free(device_driver_t driver) +{ +#ifdef notyet + int which_hash; + int s; + + if (!driver) + return; + + which_hash = driver_prefix_hash(driver->dd_prefix); + + s = mutex_spinlock(&device_driver_lock[which_hash]); + +#if DEBUG + { + device_driver_t drvscan; + + /* Make sure we're dealing with the right list */ + drvscan = device_driver_hash[which_hash]; + while (drvscan && (drvscan != driver)) + drvscan = drvscan->dd_next; + + ASSERT(drvscan); + } +#endif /* DEBUG */ + + if (driver->dd_next) + driver->dd_next->dd_prev = driver->dd_prev; + + if (driver->dd_prev) + driver->dd_prev->dd_next = driver->dd_next; + else + device_driver_hash[which_hash] = driver->dd_next; + + mutex_spinunlock(&device_driver_lock[which_hash], s); + + driver->dd_next = NULL; /* sanity */ + driver->dd_prev = NULL; /* sanity */ + driver->dd_prefix = NULL; /* sanity */ + + if (driver->dd_bdevsw) { + driver->dd_bdevsw->d_driver = NULL; + driver->dd_bdevsw = NULL; + } + + if (driver->dd_cdevsw) { + if (driver->dd_cdevsw->d_str) { + str_free_mux_node(driver); + } + driver->dd_cdevsw->d_driver = NULL; + driver->dd_cdevsw = NULL; + } + + kern_free(driver); +#endif + FIXME("device_driver_free"); +} + + +/* +** Given a device driver prefix, return a handle to the caller. +*/ +device_driver_t +device_driver_get(char *prefix) +{ +#ifdef notyet + int which_hash; + device_driver_t drvscan; + int s; + + if (prefix == NULL) + return(NULL); + + which_hash = driver_prefix_hash(prefix); + + s = mutex_spinlock(&device_driver_lock[which_hash]); + + drvscan = device_driver_hash[which_hash]; + while (drvscan && strcmp(drvscan->dd_prefix, prefix)) + drvscan = drvscan->dd_next; + + mutex_spinunlock(&device_driver_lock[which_hash], s); + + return(drvscan); +#else + FIXME("device_driver_get"); + return((device_driver_t)0); +#endif +} + + +/* +** Given a block or char special file devfs_handle_t, find the +** device driver that controls it. +*/ +device_driver_t +device_driver_getbydev(devfs_handle_t device) +{ +#ifdef notyet + struct bdevsw *my_bdevsw; + struct cdevsw *my_cdevsw; + + my_cdevsw = get_cdevsw(device); + if (my_cdevsw != NULL) + return(my_cdevsw->d_driver); + + my_bdevsw = get_bdevsw(device); + if (my_bdevsw != NULL) + return(my_bdevsw->d_driver); + +#endif + FIXME("device_driver_getbydev"); + return((device_driver_t)0); +} + + +/* +** Associate a driver with bdevsw/cdevsw pointers. +** +** Statically loaded drivers are permanently and automatically associated +** with the proper bdevsw/cdevsw. Dynamically loaded drivers associate +** themselves when the driver is registered, and disassociate when the +** driver unregisters. +** +** Returns 0 on success, -1 on failure (devsw already associated with driver) +*/ +int +device_driver_devsw_put(device_driver_t driver, + struct bdevsw *my_bdevsw, + struct cdevsw *my_cdevsw) +{ +#ifdef notyet + int i; + + if (!driver) + return(-1); + + /* Trying to re-register data? */ + if (((my_bdevsw != NULL) && (driver->dd_bdevsw != NULL)) || + ((my_cdevsw != NULL) && (driver->dd_cdevsw != NULL))) + return(-1); + + if (my_bdevsw != NULL) { + driver->dd_bdevsw = my_bdevsw; + my_bdevsw->d_driver = driver; + for (i = 0; i < bdevmax; i++) { + if (driver->dd_bdevsw->d_flags == bdevsw[i].d_flags) { + bdevsw[i].d_driver = driver; + break; + } + } + } + + if (my_cdevsw != NULL) { + driver->dd_cdevsw = my_cdevsw; + my_cdevsw->d_driver = driver; + for (i = 0; i < cdevmax; i++) { + if (driver->dd_cdevsw->d_flags == cdevsw[i].d_flags) { + cdevsw[i].d_driver = driver; + break; + } + } + } +#endif + FIXME("device_driver_devsw_put"); + return(0); +} + + +/* +** Given a driver, return the corresponding bdevsw and cdevsw pointers. +*/ +void +device_driver_devsw_get( device_driver_t driver, + struct bdevsw **bdevswp, + struct cdevsw **cdevswp) +{ + if (!driver) { + *bdevswp = NULL; + *cdevswp = NULL; + } else { + *bdevswp = driver->dd_bdevsw; + *cdevswp = driver->dd_cdevsw; + } +} + +/* + * device_driver_thread_pri_set + * Given a driver try to set its thread priority. + * Returns 0 on success , -1 on failure. + */ +int +device_driver_thread_pri_set(device_driver_t driver,ilvl_t pri) +{ + if (!driver) + return(-1); + driver->dd_thread_pri = pri; + return(0); +} +/* + * device_driver_thread_pri_get + * Given a driver return the driver thread priority. + * If the driver is NULL return invalid driver thread + * priority. + */ +ilvl_t +device_driver_thread_pri_get(device_driver_t driver) +{ + if (driver) + return(driver->dd_thread_pri); + else + return(DRIVER_THREAD_PRI_INVALID); +} +/* +** Given a device driver, return it's handle (prefix). +*/ +void +device_driver_name_get(device_driver_t driver, char *buffer, int length) +{ + if (driver == NULL) + return; + + strncpy(buffer, driver->dd_prefix, length); +} + + +/* +** Associate a pointer-sized piece of information with a device. +*/ +void +device_info_set(devfs_handle_t device, void *info) +{ +#ifdef notyet + hwgraph_fastinfo_set(device, (arbitrary_info_t)info); +#endif + FIXME("device_info_set"); +} + + +/* +** Retrieve a pointer-sized piece of information associated with a device. +*/ +void * +device_info_get(devfs_handle_t device) +{ +#ifdef notyet + return((void *)hwgraph_fastinfo_get(device)); +#else + FIXME("device_info_get"); + return(NULL); +#endif +} + +/* + * Find the thread priority for a device, from the various + * sysgen files. + */ +int +device_driver_sysgen_thread_pri_get(char *dev_prefix) +{ +#ifdef notyet + int pri; + char *pri_s; + char *class; + + extern default_intr_pri; + extern disk_intr_pri; + extern serial_intr_pri; + extern parallel_intr_pri; + extern tape_intr_pri; + extern graphics_intr_pri; + extern network_intr_pri; + extern scsi_intr_pri; + extern audio_intr_pri; + extern video_intr_pri; + extern external_intr_pri; + extern tserialio_intr_pri; + + /* Check if there is a thread priority specified for + * this driver's thread thru admin hints. If so + * use that value. Otherwise set it to its default + * class value, otherwise set it to the default + * value. + */ + + if (pri_s = device_driver_admin_info_get(dev_prefix, + ADMIN_LBL_THREAD_PRI)) { + pri = atoi(pri_s); + } else if (class = device_driver_admin_info_get(dev_prefix, + ADMIN_LBL_THREAD_CLASS)) { + if (strcmp(class, "disk") == 0) + pri = disk_intr_pri; + else if (strcmp(class, "serial") == 0) + pri = serial_intr_pri; + else if (strcmp(class, "parallel") == 0) + pri = parallel_intr_pri; + else if (strcmp(class, "tape") == 0) + pri = tape_intr_pri; + else if (strcmp(class, "graphics") == 0) + pri = graphics_intr_pri; + else if (strcmp(class, "network") == 0) + pri = network_intr_pri; + else if (strcmp(class, "scsi") == 0) + pri = scsi_intr_pri; + else if (strcmp(class, "audio") == 0) + pri = audio_intr_pri; + else if (strcmp(class, "video") == 0) + pri = video_intr_pri; + else if (strcmp(class, "external") == 0) + pri = external_intr_pri; + else if (strcmp(class, "tserialio") == 0) + pri = tserialio_intr_pri; + else + pri = default_intr_pri; + } else + pri = default_intr_pri; + + if (pri > 255) + pri = 255; + else if (pri < 0) + pri = 0; + return pri; +#else + FIXME("device_driver_sysgen_thread_pri_get"); + return(-1); +#endif +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/eeprom.c linux-2.4.0-test12-lia/arch/ia64/sn/io/eeprom.c --- linux-2.4.0-test12/arch/ia64/sn/io/eeprom.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/eeprom.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,1457 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +/* + * WARNING: There is more than one copy of this file in different isms. + * All copies must be kept exactly in sync. + * Do not modify this file without also updating the following: + * + * irix/kern/io/eeprom.c + * stand/arcs/lib/libsk/ml/eeprom.c + * stand/arcs/lib/libkl/io/eeprom.c + * + * (from time to time they might not be in sync but that's due to bringup + * activity - this comment is to remind us that they eventually have to + * get back together) + * + * eeprom.c + * + * access to board-mounted EEPROMs via the L1 system controllers + * + */ + +/************************************************************************** + * * + * Copyright (C) 1999 Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + ************************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* #include */ +#include +#include +#include +#include +#include + +#if defined(EEPROM_DEBUG) +#define db_printf(x) printk x +#else +#define db_printf(x) printk x +#endif + +#define BCOPY(x,y,z) memcpy(y,x,z) + +#define UNDERSCORE 0 /* don't convert underscores to hyphens */ +#define HYPHEN 1 /* convert underscores to hyphens */ + +void copy_ascii_field( char *to, char *from, int length, + int change_underscore ); +uint64_t generate_unique_id( char *sn, int sn_len ); +uchar_t char_to_base36( char c ); +int nicify( char *dst, eeprom_brd_record_t *src ); +static void int64_to_hex_string( char *out, uint64_t val ); + +// extern int router_lock( net_vec_t, int, int ); +// extern int router_unlock( net_vec_t ); +#define ROUTER_LOCK(p) // router_lock(p, 10000, 3000000) +#define ROUTER_UNLOCK(p) // router_unlock(p) + +#define IP27LOG_OVNIC "OverrideNIC" + + +/* the following function converts an EEPROM record to a close facsimile + * of the string returned by reading a Dallas Semiconductor NIC (see + * one of the many incarnations of nic.c for details on that driver) + */ +int nicify( char *dst, eeprom_brd_record_t *src ) +{ + int field_len; + uint64_t unique_id; + char *cur_dst = dst; + eeprom_board_ia_t *board; + + board = src->board_ia; + ASSERT( board ); /* there should always be a board info area */ + + /* copy part number */ + strcpy( cur_dst, "Part:" ); + cur_dst += strlen( cur_dst ); + ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK) + == FIELD_FORMAT_ASCII ); + field_len = board->part_num_tl & FIELD_LENGTH_MASK; + copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN ); + cur_dst += field_len; + + /* copy product name */ + strcpy( cur_dst, ";Name:" ); + cur_dst += strlen( cur_dst ); + ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII ); + field_len = board->product_tl & FIELD_LENGTH_MASK; + copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE ); + cur_dst += field_len; + + /* copy serial number */ + strcpy( cur_dst, ";Serial:" ); + cur_dst += strlen( cur_dst ); + ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK) + == FIELD_FORMAT_ASCII ); + field_len = board->serial_num_tl & FIELD_LENGTH_MASK; + copy_ascii_field( cur_dst, board->serial_num, field_len, + HYPHEN); + + cur_dst += field_len; + + /* copy revision */ + strcpy( cur_dst, ";Revision:"); + cur_dst += strlen( cur_dst ); + ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK) + == FIELD_FORMAT_ASCII ); + field_len = board->board_rev_tl & FIELD_LENGTH_MASK; + copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN ); + cur_dst += field_len; + + /* EEPROMs don't have equivalents for the Group, Capability and + * Variety fields, so we pad these with 0's + */ + strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" ); + cur_dst += strlen( cur_dst ); + + /* use the board serial number to "fake" a laser id */ + strcpy( cur_dst, ";Laser:" ); + cur_dst += strlen( cur_dst ); + unique_id = generate_unique_id( board->serial_num, + board->serial_num_tl & FIELD_LENGTH_MASK ); + int64_to_hex_string( cur_dst, unique_id ); + strcat( dst, ";" ); + + return 1; +} + + +/* These functions borrow heavily from chars2* in nic.c + */ +void copy_ascii_field( char *to, char *from, int length, + int change_underscore ) +{ + int i; + for( i = 0; i < length; i++ ) { + + /* change underscores to hyphens if requested */ + if( from[i] == '_' && change_underscore == HYPHEN ) + to[i] = '-'; + + /* ; and ; are separators, so mustn't appear within + * a field */ + else if( from[i] == ':' || from[i] == ';' ) + to[i] = '?'; + + /* I'm not sure why or if ASCII character 0xff would + * show up in an EEPROM field, but the NIC parsing + * routines wouldn't like it if it did... so we + * get rid of it, just in case. */ + else if( (unsigned char)from[i] == (unsigned char)0xff ) + to[i] = ' '; + + /* unprintable characters are replaced with . */ + else if( from[i] < ' ' || from[i] >= 0x7f ) + to[i] = '.'; + + /* otherwise, just copy the character */ + else + to[i] = from[i]; + } + + if( i == 0 ) { + to[i] = ' '; /* return at least a space... */ + i++; + } + to[i] = 0; /* terminating null */ +} + +/* Note that int64_to_hex_string currently only has a big-endian + * implementation. + */ +#ifdef _MIPSEB +static void int64_to_hex_string( char *out, uint64_t val ) +{ + int i; + uchar_t table[] = "0123456789abcdef"; + uchar_t *byte_ptr = (uchar_t *)&val; + for( i = 0; i < sizeof(uint64_t); i++ ) { + out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ]; + out[i*2+1] = table[ (*byte_ptr) & 0x0f ]; + byte_ptr++; + } + out[i*2] = '\0'; +} + +#else /* little endian */ + +static void int64_to_hex_string( char *out, uint64_t val ) +{ + + + printk("int64_to_hex_string needs a little-endian implementation.\n"); +} +#endif /* _MIPSEB */ + +/* Convert a standard ASCII serial number to a unique integer + * id number by treating the serial number string as though + * it were a base 36 number + */ +uint64_t generate_unique_id( char *sn, int sn_len ) +{ + int uid = 0; + int i; + + #define VALID_BASE36(c) ((c >= '0' && c <='9') \ + || (c >= 'A' && c <='Z') \ + || (c >= 'a' && c <='z')) + + for( i = 0; i < sn_len; i++ ) { + if( !VALID_BASE36(sn[i]) ) + continue; + uid *= 36; + uid += char_to_base36( sn[i] ); + } + + if( uid == 0 ) + return rtc_time(); + + return uid; +} + +uchar_t char_to_base36( char c ) +{ + uchar_t val; + + if( c >= '0' && c <= '9' ) + val = (c - '0'); + + else if( c >= 'A' && c <= 'Z' ) + val = (c - 'A' + 10); + + else if( c >= 'a' && c <= 'z' ) + val = (c - 'a' + 10); + + else val = 0; + + return val; +} + + +/* given a pointer to the three-byte little-endian EEPROM representation + * of date-of-manufacture, this function translates to a big-endian + * integer format + */ +int eeprom_xlate_board_mfr_date( uchar_t *src ) +{ + int rval = 0; + rval += *src; src++; + rval += ((int)(*src) << 8); src ++; + rval += ((int)(*src) << 16); + return rval; +} + + +int eeprom_str( char *nic_str, nasid_t nasid, int component ) +{ + eeprom_brd_record_t eep; + eeprom_board_ia_t board; + eeprom_chassis_ia_t chassis; + int r; + + if( (component & C_DIMM) == C_DIMM ) { + /* this function isn't applicable to DIMMs */ + return EEP_PARAM; + } + else { + eep.board_ia = &board; + eep.spd = NULL; + if( !(component & SUBORD_MASK) ) + eep.chassis_ia = &chassis; /* only main boards have a chassis + * info area */ + else + eep.chassis_ia = NULL; + } + + switch( component & BRICK_MASK ) { + case C_BRICK: + r = cbrick_eeprom_read( &eep, nasid, component ); + break; + case IO_BRICK: + r = iobrick_eeprom_read( &eep, nasid, component ); + break; + default: + return EEP_PARAM; /* must be an invalid component */ + } + if( r ) + return r; + if( !nicify( nic_str, &eep ) ) + return EEP_NICIFY; + + return EEP_OK; +} + +int vector_eeprom_str( char *nic_str, nasid_t nasid, + int component, net_vec_t path ) +{ + eeprom_brd_record_t eep; + eeprom_board_ia_t board; + eeprom_chassis_ia_t chassis; + int r; + + eep.board_ia = &board; + if( !(component & SUBORD_MASK) ) + eep.chassis_ia = &chassis; /* only main boards have a chassis + * info area */ + else + eep.chassis_ia = NULL; + + if( !(component & VECTOR) ) + return EEP_PARAM; + + if( (r = vector_eeprom_read( &eep, nasid, path, component )) ) + return r; + + if( !nicify( nic_str, &eep ) ) + return EEP_NICIFY; + + return EEP_OK; +} + + +int is_iobrick( int nasid, int widget_num ) +{ + uint32_t wid_reg; + int part_num, mfg_num; + + /* Read the widget's WIDGET_ID register to get + * its part number and mfg number + */ + wid_reg = *(volatile int32_t *) + (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID); + + part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; + mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT; + + /* Is this the "xbow part" of an XBridge? If so, this + * widget is definitely part of an I/O brick. + */ + if( part_num == XXBOW_WIDGET_PART_NUM && + mfg_num == XXBOW_WIDGET_MFGR_NUM ) + + return 1; + + /* Is this a "bridge part" of an XBridge? If so, once + * again, we know this widget is part of an I/O brick. + */ + if( part_num == XBRIDGE_WIDGET_PART_NUM && + mfg_num == XBRIDGE_WIDGET_MFGR_NUM ) + + return 1; + + return 0; +} + + +int cbrick_uid_get( nasid_t nasid, uint64_t *uid ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + char uid_str[32]; + char msg[BRL1_QSIZE]; + int subch, len; + l1sc_t sc; + l1sc_t *scp; + int local = (nasid == get_nasid()); + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + /* If the promlog variable pointed to by IP27LOG_OVNIC is set, + * use that value for the cbrick UID rather than the EEPROM + * serial number. + */ +#ifdef LOG_GETENV + if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 ) + { + /* We successfully read IP27LOG_OVNIC, so return it as the UID. */ + db_printf(( "cbrick_uid_get:" + "Overriding UID with environment variable %s\n", + IP27LOG_OVNIC )); + *uid = strtoull( uid_str, NULL, 0 ); + return EEP_OK; + } +#endif + + /* If this brick is retrieving its own uid, use the local l1sc_t to + * arbitrate access to the l1; otherwise, set up a new one. + */ + if( local ) { + scp = get_l1sc(); + } + else { + scp = ≻ + sc_init( &sc, nasid, BRL1_LOCALUART ); + } + + /* fill in msg with the opcode & params */ + BZERO( msg, BRL1_QSIZE ); + if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) + return EEP_L1; + + if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_SER_NUM, 0 )) < 0 ) + { + sc_close( scp, subch ); + return( EEP_L1 ); + } + + /* send the request to the L1 */ + if( sc_command( scp, subch, msg, msg, &len ) ) { + sc_close( scp, subch ); + return( EEP_L1 ); + } + + /* free up subchannel */ + sc_close(scp, subch); + + /* check response */ + if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 ) + { + return( EEP_L1 ); + } + + *uid = generate_unique_id( uid_str, strlen( uid_str ) ); + + return EEP_OK; +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + +int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + char uid_str[32]; + char msg[BRL1_QSIZE]; + int subch, len; + l1sc_t sc; + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + +#ifdef BRINGUP +#define FAIL \ + { \ + *uid = rtc_time(); \ + printk( "rbrick_uid_get failed; using current time as uid\n" ); \ + return EEP_OK; \ + } +#endif /* BRINGUP */ + + ROUTER_LOCK(path); + sc_init( &sc, nasid, path ); + + /* fill in msg with the opcode & params */ + BZERO( msg, BRL1_QSIZE ); + if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) { + ROUTER_UNLOCK(path); + FAIL; + } + + if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_SER_NUM, 0 )) < 0 ) + { + ROUTER_UNLOCK(path); + sc_close( &sc, subch ); + FAIL; + } + + /* send the request to the L1 */ + if( sc_command( &sc, subch, msg, msg, &len ) ) { + ROUTER_UNLOCK(path); + sc_close( &sc, subch ); + FAIL; + } + + /* free up subchannel */ + ROUTER_UNLOCK(path); + sc_close(&sc, subch); + + /* check response */ + if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 ) + { + FAIL; + } + + *uid = generate_unique_id( uid_str, strlen( uid_str ) ); + + return EEP_OK; +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + +int iobrick_uid_get( nasid_t nasid, uint64_t *uid ) +{ + eeprom_brd_record_t eep; + eeprom_board_ia_t board; + eeprom_chassis_ia_t chassis; + int r; + + eep.board_ia = &board; + eep.chassis_ia = &chassis; + eep.spd = NULL; + + r = iobrick_eeprom_read( &eep, nasid, IO_BRICK ); + if( r != EEP_OK ) { + *uid = rtc_time(); + return r; + } + + *uid = generate_unique_id( board.serial_num, + board.serial_num_tl & FIELD_LENGTH_MASK ); + + return EEP_OK; +} + + +int ibrick_mac_addr_get( nasid_t nasid, char *eaddr ) +{ + eeprom_brd_record_t eep; + eeprom_board_ia_t board; + eeprom_chassis_ia_t chassis; + int r; + char *tmp; + + eep.board_ia = &board; + eep.chassis_ia = &chassis; + eep.spd = NULL; + + r = iobrick_eeprom_read( &eep, nasid, IO_BRICK ); + if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) { + db_printf(( "ibrick_mac_addr_get: " + "Couldn't read MAC address from EEPROM\n" )); + return EEP_L1; + } + else { + /* successfully read info area */ + int ix; + tmp = board.mac_addr; + for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ ) + { + *eaddr++ = *tmp++; + } + *eaddr = '\0'; + } + + return EEP_OK; +} + + +/* + * eeprom_vertex_info_set + * + * Given a vertex handle, a component designation, a starting nasid + * and (in the case of a router) a vector path to the component, this + * function will read the EEPROM and attach the resulting information + * to the vertex in the same string format as that provided by the + * Dallas Semiconductor NIC drivers. If the vertex already has the + * string, this function just returns the string. + */ + +extern char *nic_vertex_info_get( devfs_handle_t ); +extern void nic_vmc_check( devfs_handle_t, char * ); +#ifdef BRINGUP +/* the following were lifted from nic.c - change later? */ +#define MAX_INFO 2048 +#define NEWSZ(ptr,sz) ((ptr) = kern_malloc((sz))) +#define DEL(ptr) (kern_free((ptr))) +#endif /* BRINGUP */ + +char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v, + net_vec_t path ) +{ + char *info_tmp; + int info_len; + char *info; + + /* see if this vertex is already marked */ + info_tmp = nic_vertex_info_get(v); + if (info_tmp) return info_tmp; + + /* get a temporary place for the data */ + NEWSZ(info_tmp, MAX_INFO); + if (!info_tmp) return NULL; + + /* read the EEPROM */ + if( component & R_BRICK ) { + if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK ) + return NULL; + } + else { + if( eeprom_str( info_tmp, nasid, component ) != EEP_OK ) + return NULL; + } + + /* allocate a smaller final place */ + info_len = strlen(info_tmp)+1; + NEWSZ(info, info_len); + if (info) { + strcpy(info, info_tmp); + DEL(info_tmp); + } else { + info = info_tmp; + } + + /* add info to the vertex */ + hwgraph_info_add_LBL(v, INFO_LBL_NIC, + (arbitrary_info_t) info); + + /* see if someone else got there first */ + info_tmp = nic_vertex_info_get(v); + if (info != info_tmp) { + DEL(info); + return info_tmp; + } + + /* export the data */ + hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len); + + /* trigger all matching callbacks */ + nic_vmc_check(v, info); + + return info; +} + + +/********************************************************************* + * + * stubs for use until the Bedrock/L1 link is available + * + */ + +#include + +/* #define EEPROM_TEST */ + +/* fake eeprom reading functions (replace when the BR/L1 communication + * channel is in working order) + */ + + +/* generate a charater in [0-9A-Z]; if an "extra" character is + * specified (such as '_'), include it as one of the possibilities. + */ +char random_eeprom_ch( char extra ) +{ + char ch; + int modval = 36; + if( extra ) + modval++; + + ch = rtc_time() % modval; + + if( ch < 10 ) + ch += '0'; + else if( ch >= 10 && ch < 36 ) + ch += ('A' - 10); + else + ch = extra; + + return ch; +} + +/* create a part number of the form xxx-xxxx-xxx. + * It may be important later to generate different + * part numbers depending on the component we're + * supposed to be "reading" from, so the component + * paramter is provided. + */ +void fake_a_part_number( char *buf, int component ) +{ + int i; + switch( component ) { + + /* insert component-specific routines here */ + + case C_BRICK: + strcpy( buf, "030-1266-001" ); + break; + default: + for( i = 0; i < 12; i++ ) { + if( i == 3 || i == 8 ) + buf[i] = '-'; + else + buf[i] = random_eeprom_ch(0); + } + } +} + + +/* create a six-character serial number */ +void fake_a_serial_number( char *buf, uint64_t ser ) +{ + int i; + static const char hexchars[] = "0123456789ABCDEF"; + + if (ser) { + for( i = 5; i >=0; i-- ) { + buf[i] = hexchars[ser & 0xf]; + ser >>= 4; + } + } + else { + for( i = 0; i < 6; i++ ) + buf[i] = random_eeprom_ch(0); + } +} + + +void fake_a_product_name( uchar_t *format, char* buf, int component ) +{ + switch( component & BRICK_MASK ) { + + case C_BRICK: + if( component & SUBORD_MASK ) { + strcpy( buf, "C_BRICK_SUB" ); + *format = 0xCB; + } + else { + strcpy( buf, "IP35" ); + *format = 0xC4; + } + break; + + case R_BRICK: + if( component & SUBORD_MASK ) { + strcpy( buf, "R_BRICK_SUB" ); + *format = 0xCB; + } + else { + strcpy( buf, "R_BRICK" ); + *format = 0xC7; + } + break; + + case IO_BRICK: + if( component & SUBORD_MASK ) { + strcpy( buf, "IO_BRICK_SUB" ); + *format = 0xCC; + } + else { + strcpy( buf, "IO_BRICK" ); + *format = 0xC8; + } + break; + + default: + strcpy( buf, "UNK_DEVICE" ); + *format = 0xCA; + } +} + + + +int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, + uint64_t ser ) +{ + eeprom_board_ia_t *board; + eeprom_chassis_ia_t *chassis; + int i, cs; + + board = buf->board_ia; + chassis = buf->chassis_ia; + + if( !(component & SUBORD_MASK) ) { + if( !chassis ) + return EEP_PARAM; + chassis->format = 0; + chassis->length = 5; + chassis->type = 0x17; + + chassis->part_num_tl = 0xCC; + fake_a_part_number( chassis->part_num, component ); + chassis->serial_num_tl = 0xC6; + fake_a_serial_number( chassis->serial_num, ser ); + + cs = chassis->format + chassis->length + chassis->type + + chassis->part_num_tl + chassis->serial_num_tl; + for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ ) + cs += chassis->part_num[i]; + for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ ) + cs += chassis->serial_num[i]; + chassis->checksum = 256 - (cs % 256); + } + + if( !board ) + return EEP_PARAM; + board->format = 0; + board->length = 10; + board->language = 0; + board->mfg_date = 1789200; /* noon, 5/26/99 */ + board->manuf_tl = 0xC3; + strcpy( board->manuf, "SGI" ); + + fake_a_product_name( &(board->product_tl), board->product, component ); + + board->serial_num_tl = 0xC6; + fake_a_serial_number( board->serial_num, ser ); + + board->part_num_tl = 0xCC; + fake_a_part_number( board->part_num, component ); + + board->board_rev_tl = 0xC2; + board->board_rev[0] = '0'; + board->board_rev[1] = '1'; + + board->eeprom_size_tl = 0x01; + board->eeprom_size = 1; + + board->temp_waiver_tl = 0xC2; + board->temp_waiver[0] = '0'; + board->temp_waiver[1] = '1'; + + cs = board->format + board->length + board->language + + (board->mfg_date & 0xFF) + + (board->mfg_date & 0xFF00) + + (board->mfg_date & 0xFF0000) + + board->manuf_tl + board->product_tl + board->serial_num_tl + + board->part_num_tl + board->board_rev_tl + + board->board_rev[0] + board->board_rev[1] + + board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl + + board->temp_waiver[0] + board->temp_waiver[1]; + for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ ) + cs += board->manuf[i]; + for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ ) + cs += board->product[i]; + for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ ) + cs += board->serial_num[i]; + for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ ) + cs += board->part_num[i]; + + board->checksum = 256 - (cs % 256); + + return EEP_OK; +} + +#define EEPROM_CHUNKSIZE 64 + +#if defined(EEPROM_DEBUG) +#define RETURN_ERROR \ +{ \ + printk( "read_ia error return, component 0x%x, line %d" \ + ", address 0x%x, ia code 0x%x\n", \ + l1_compt, __LINE__, sc->subch[subch].target, ia_code ); \ + return EEP_L1; \ +} + +#else +#define RETURN_ERROR return(EEP_L1) +#endif + +int read_ia( l1sc_t *sc, int subch, int l1_compt, + int ia_code, char *eep_record ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + char msg[BRL1_QSIZE]; /* message buffer */ + int len; /* number of bytes used in message buffer */ + int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */ + int offset = 0; /* current offset into info area */ + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + BZERO( msg, BRL1_QSIZE ); + + /* retrieve EEPROM data in 64-byte chunks + */ + + while( ia_len ) + { + /* fill in msg with opcode & params */ + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_EEPROM, 8, + L1_ARG_INT, l1_compt, + L1_ARG_INT, ia_code, + L1_ARG_INT, offset, + L1_ARG_INT, ia_len )) < 0 ) + { + RETURN_ERROR; + } + + /* send the request to the L1 */ + + if( sc_command( sc, subch, msg, msg, &len ) ) { + RETURN_ERROR; + } + + /* check response */ + if( sc_interpret_resp( msg, 5, + L1_ARG_INT, &ia_len, + L1_ARG_UNKNOWN, &len, eep_record ) < 0 ) + { + RETURN_ERROR; + } + + if( ia_len > EEPROM_CHUNKSIZE ) + ia_len = EEPROM_CHUNKSIZE; + + eep_record += EEPROM_CHUNKSIZE; + offset += EEPROM_CHUNKSIZE; + } + + return EEP_OK; +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + +int read_spd( l1sc_t *sc, int subch, int l1_compt, + eeprom_spd_u *spd ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + char msg[BRL1_QSIZE]; /* message buffer */ + int len; /* number of bytes used in message buffer */ + int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */ + int offset = 0; /* current offset into spd record */ + char *spd_p = spd->bytes; /* "thumb" for writing to spd */ + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + BZERO( msg, BRL1_QSIZE ); + + /* retrieve EEPROM data in 64-byte chunks + */ + + while( spd_len ) + { + /* fill in msg with opcode & params */ + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_EEPROM, 8, + L1_ARG_INT, l1_compt, + L1_ARG_INT, L1_EEP_SPD, + L1_ARG_INT, offset, + L1_ARG_INT, spd_len )) < 0 ) + { + return( EEP_L1 ); + } + + /* send the request to the L1 */ + if( sc_command( sc, subch, msg, msg, &len ) ) { + return( EEP_L1 ); + } + + /* check response */ + if( sc_interpret_resp( msg, 5, + L1_ARG_INT, &spd_len, + L1_ARG_UNKNOWN, &len, spd_p ) < 0 ) + { + return( EEP_L1 ); + } + + if( spd_len > EEPROM_CHUNKSIZE ) + spd_len = EEPROM_CHUNKSIZE; + + spd_p += EEPROM_CHUNKSIZE; + offset += EEPROM_CHUNKSIZE; + } + return EEP_OK; +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + +int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt, + eeprom_chassis_ia_t *ia ) +{ + char eep_record[512]; /* scratch area for building up info area */ + char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ + int checksum = 0; /* use to verify eeprom record checksum */ + int i; + + /* Read in info area record from the L1. + */ + if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record ) + != EEP_OK ) + { + return EEP_L1; + } + + /* Now we've got the whole info area. Transfer it to the data structure. + */ + + eep_rec_p = eep_record; + ia->format = *eep_rec_p++; + ia->length = *eep_rec_p++; + if( ia->length == 0 ) { + /* since we're using 8*ia->length-1 as an array index later, make + * sure it's sane. + */ + db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" )); + return EEP_L1; + } + ia->type = *eep_rec_p++; + + ia->part_num_tl = *eep_rec_p++; + + (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); + + ia->serial_num_tl = *eep_rec_p++; + + BCOPY( eep_rec_p, ia->serial_num, + (ia->serial_num_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); + + ia->checksum = eep_record[(8 * ia->length) - 1]; + + /* verify checksum */ + eep_rec_p = eep_record; + checksum = 0; + for( i = 0; i < (8 * ia->length); i++ ) { + checksum += *eep_rec_p++; + } + + if( (checksum & 0xff) != 0 ) + { + db_printf(( "read_chassis_ia: bad checksum\n" )); + db_printf(( "read_chassis_ia: target 0x%x uart 0x%x\n", + sc->subch[subch].target, sc->uart )); + return EEP_BAD_CHECKSUM; + } + + return EEP_OK; +} + + +int read_board_ia( l1sc_t *sc, int subch, int l1_compt, + eeprom_board_ia_t *ia ) +{ + char eep_record[512]; /* scratch area for building up info area */ + char *eep_rec_p = eep_record; /* thumb for moving through eep_record */ + int checksum = 0; /* running checksum total */ + int i; + + BZERO( ia, sizeof( eeprom_board_ia_t ) ); + + /* Read in info area record from the L1. + */ + if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record ) + != EEP_OK ) + { + db_printf(( "read_board_ia: error reading info area from L1\n" )); + return EEP_L1; + } + + /* Now we've got the whole info area. Transfer it to the data structure. + */ + + eep_rec_p = eep_record; + ia->format = *eep_rec_p++; + ia->length = *eep_rec_p++; + if( ia->length == 0 ) { + /* since we're using 8*ia->length-1 as an array index later, make + * sure it's sane. + */ + db_printf(( "read_board_ia: eeprom length byte of ZERO\n" )); + return EEP_L1; + } + ia->language = *eep_rec_p++; + + ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p ); + eep_rec_p += 3; + + ia->manuf_tl = *eep_rec_p++; + + BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK); + + ia->product_tl = *eep_rec_p++; + + BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK); + + ia->serial_num_tl = *eep_rec_p++; + + BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK)); + eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK); + + ia->part_num_tl = *eep_rec_p++; + + BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK); + + eep_rec_p++; /* we do not use the FRU file id */ + + ia->board_rev_tl = *eep_rec_p++; + + BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK); + + ia->eeprom_size_tl = *eep_rec_p++; + ia->eeprom_size = *eep_rec_p++; + + ia->temp_waiver_tl = *eep_rec_p++; + + BCOPY( eep_rec_p, ia->temp_waiver, + (ia->temp_waiver_tl & FIELD_LENGTH_MASK) ); + eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK); + + /* if there's more, we must be reading a main board; get + * additional fields + */ + if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { + + ia->ekey_G_tl = *eep_rec_p++; + BCOPY( eep_rec_p, (char *)&ia->ekey_G, + ia->ekey_G_tl & FIELD_LENGTH_MASK ); + eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK); + + ia->ekey_P_tl = *eep_rec_p++; + BCOPY( eep_rec_p, (char *)&ia->ekey_P, + ia->ekey_P_tl & FIELD_LENGTH_MASK ); + eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK); + + ia->ekey_Y_tl = *eep_rec_p++; + BCOPY( eep_rec_p, (char *)&ia->ekey_Y, + ia->ekey_Y_tl & FIELD_LENGTH_MASK ); + eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK); + + /* + * need to get a couple more fields if this is an I brick + */ + if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) { + + ia->mac_addr_tl = *eep_rec_p++; + BCOPY( eep_rec_p, ia->mac_addr, + ia->mac_addr_tl & FIELD_LENGTH_MASK ); + eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK); + + ia->ieee1394_cfg_tl = *eep_rec_p++; + BCOPY( eep_rec_p, ia->ieee1394_cfg, + ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK ); + + } + } + + ia->checksum = eep_record[(ia->length * 8) - 1]; + + /* verify checksum */ + eep_rec_p = eep_record; + checksum = 0; + for( i = 0; i < (8 * ia->length); i++ ) { + checksum += *eep_rec_p++; + } + + if( (checksum & 0xff) != 0 ) + { + db_printf(( "read_board_ia: bad checksum\n" )); + db_printf(( "read_board_ia: target 0x%x uart 0x%x\n", + sc->subch[subch].target, sc->uart )); + return EEP_BAD_CHECKSUM; + } + + return EEP_OK; +} + + +int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp, + int component ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + int r; + uint64_t uid = 0; + char uid_str[32]; + int l1_compt, subch; + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + /* make sure we're targeting a cbrick */ + if( !(component & C_BRICK) ) + return EEP_PARAM; + + /* If the promlog variable pointed to by IP27LOG_OVNIC is set, + * use that value for the cbrick UID rather than the EEPROM + * serial number. + */ +#ifdef LOG_GETENV + if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 ) + { + db_printf(( "_cbrick_eeprom_read: " + "Overriding UID with environment variable %s\n", + IP27LOG_OVNIC )); + uid = strtoull( uid_str, NULL, 0 ); + } +#endif + + if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 ) + return EEP_L1; + + switch( component ) + { + case C_BRICK: + /* c-brick motherboard */ + l1_compt = L1_EEP_NODE; + r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); + if( r != EEP_OK ) { + sc_close( scp, subch ); + db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); + return fake_an_eeprom_record( buf, component, uid ); + } + if( uid ) { + /* If IP27LOG_OVNIC is set, we want to put that value + * in as our UID. */ + fake_a_serial_number( buf->chassis_ia->serial_num, uid ); + buf->chassis_ia->serial_num_tl = 6; + } + break; + + case C_PIMM: + /* one of the PIMM boards */ + l1_compt = L1_EEP_PIMM( component & COMPT_MASK ); + break; + + case C_DIMM: + /* one of the DIMMs */ + l1_compt = L1_EEP_DIMM( component & COMPT_MASK ); + r = read_spd( scp, subch, l1_compt, buf->spd ); + sc_close( scp, subch ); + return r; + + default: + /* unsupported board type */ + sc_close( scp, subch ); + return EEP_PARAM; + } + + r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); + sc_close( scp, subch ); + if( r != EEP_OK ) + { + db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" )); + return fake_an_eeprom_record( buf, component, uid ); + } + return EEP_OK; +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + +int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, + int component ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + l1sc_t *scp; + int local = (nasid == get_nasid()); + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + /* If this brick is retrieving its own uid, use the local l1sc_t to + * arbitrate access to the l1; otherwise, set up a new one (prom) or + * use an existing remote l1sc_t (kernel) + */ + if( local ) { + scp = get_l1sc(); + } + else { + elsc_t *get_elsc(void); + scp = get_elsc(); + } + + return _cbrick_eeprom_read( buf, scp, component ); +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + +int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, + int component ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + int r; + int l1_compt, subch; + l1sc_t *scp; + int local = (nasid == get_nasid()); + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + /* make sure we're talking to an applicable brick */ + if( !(component & IO_BRICK) ) { + return EEP_PARAM; + } + + /* If we're talking to this c-brick's attached io brick, use + * the local l1sc_t; otherwise, set up a new one (prom) or + * use an existing remote l1sc_t (kernel) + */ + if( local ) { + scp = get_l1sc(); + } + else { + elsc_t *get_elsc(void); + scp = get_elsc(); + } + + if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 ) + return EEP_L1; + + + switch( component ) + { + case IO_BRICK: + /* IO brick motherboard */ + l1_compt = L1_EEP_LOGIC; + r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia ); + + if( r != EEP_OK ) { + sc_close( scp, subch ); +#ifdef BRINGUP /* Once EEPROMs are universally available, remove this */ + r = fake_an_eeprom_record( buf, component, rtc_time() ); +#endif /* BRINGUP */ + return r; + } + break; + + case IO_POWER: + /* IO brick power board */ + l1_compt = L1_EEP_POWER; + break; + + default: + /* unsupported board type */ + sc_close( scp, subch ); + return EEP_PARAM; + } + + r = read_board_ia( scp, subch, l1_compt, buf->board_ia ); + sc_close( scp, subch ); + if( r != EEP_OK ) { + return r; + } + return EEP_OK; +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + +int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, + net_vec_t path, int component ) +{ +#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + return EEP_L1; +#else + int r; + uint64_t uid = 0; + int l1_compt, subch; + l1sc_t sc; + + if ( IS_RUNNING_ON_SIMULATOR() ) + return EEP_L1; + + /* make sure we're targeting an applicable brick */ + if( !(component & VECTOR) ) + return EEP_PARAM; + + switch( component & BRICK_MASK ) + { + case R_BRICK: + ROUTER_LOCK( path ); + sc_init( &sc, nasid, path ); + + if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) + { + db_printf(( "vector_eeprom_read: couldn't open subch\n" )); + ROUTER_UNLOCK(path); + return EEP_L1; + } + switch( component ) + { + case R_BRICK: + /* r-brick motherboard */ + l1_compt = L1_EEP_LOGIC; + r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia ); + if( r != EEP_OK ) { + sc_close( &sc, subch ); + ROUTER_UNLOCK( path ); + printk( "vector_eeprom_read: couldn't get rbrick eeprom info;" + " using current time as uid\n" ); + uid = rtc_time(); + db_printf(("vector_eeprom_read: using a fake eeprom record\n")); + return fake_an_eeprom_record( buf, component, uid ); + } + break; + + case R_POWER: + /* r-brick power board */ + l1_compt = L1_EEP_POWER; + break; + + default: + /* unsupported board type */ + sc_close( &sc, subch ); + ROUTER_UNLOCK( path ); + return EEP_PARAM; + } + r = read_board_ia( &sc, subch, l1_compt, buf->board_ia ); + sc_close( &sc, subch ); + ROUTER_UNLOCK( path ); + if( r != EEP_OK ) { + db_printf(( "vector_eeprom_read: using a fake eeprom record\n" )); + return fake_an_eeprom_record( buf, component, uid ); + } + return EEP_OK; + + case C_BRICK: + sc_init( &sc, nasid, path ); + return _cbrick_eeprom_read( buf, &sc, component ); + + default: + /* unsupported brick type */ + return EEP_PARAM; + } +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/hcl.c linux-2.4.0-test12-lia/arch/ia64/sn/io/hcl.c --- linux-2.4.0-test12/arch/ia64/sn/io/hcl.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/hcl.c Thu Dec 14 02:15:52 2000 @@ -0,0 +1,1506 @@ +/* $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. + * + * hcl - SGI's Hardware Graph compatibility layer. + * + * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER" +#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE" +#define HCL_TEMP_NAME_LEN 44 +#define HCL_VERSION "1.0" +devfs_handle_t hwgraph_root = NULL; + +/* + * Debug flag definition. + */ +#define OPTION_NONE 0x00 +#define HCL_DEBUG_NONE 0x00000 +#define HCL_DEBUG_ALL 0x0ffff +#if defined(CONFIG_HCL_DEBUG) +static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE; +#endif +static unsigned int hcl_debug = HCL_DEBUG_NONE; +static unsigned int boot_options = OPTION_NONE; + +/* + * Some Global definitions. + */ +spinlock_t hcl_spinlock; +devfs_handle_t hcl_handle = NULL; + +/* + * HCL device driver. + * The purpose of this device driver is to provide a facility + * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path + * to manipulate label entries without having to implement + * system call interfaces. This methodology will enable us to + * make this feature module loadable. + */ +static int hcl_open(struct inode * inode, struct file * filp) +{ + if (hcl_debug) { + printk("HCL: hcl_open called.\n"); + } + + return(0); + +} + +static int hcl_close(struct inode * inode, struct file * filp) +{ + + if (hcl_debug) { + printk("HCL: hcl_close called.\n"); + } + + return(0); + +} + +static int hcl_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + + if (hcl_debug) { + printk("HCL: hcl_ioctl called.\n"); + } + + switch (cmd) { + default: + if (hcl_debug) { + printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd); + } + } + + return(0); + +} + +struct file_operations hcl_fops = { + NULL, /* lseek - default */ + NULL, /* read - general block-dev read */ + NULL, /* write - general block-dev write */ + NULL, /* readdir - bad */ + NULL, /* poll */ + hcl_ioctl, /* ioctl */ + NULL, /* mmap */ + hcl_open, /* open */ + NULL, /* flush */ + hcl_close, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL /* lock */ +}; + + +/* + * init_hcl() - Boot time initialization. Ensure that it is called + * after devfs has been initialized. + * + * For now this routine is being called out of devfs/base.c. Actually + * Not a bad place to be .. + * + */ +#ifdef MODULE +int init_module (void) +#else +int __init init_hcl(void) +#endif +{ + extern void string_table_init(struct string_table *); + extern struct string_table label_string_table; + int rv = 0; + + printk ("\n%s: v%s Colin Ngam (cngam@sgi.com)\n", + HCL_NAME, HCL_VERSION); +#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE) + hcl_debug = hcl_debug_init; + printk ("%s: hcl_debug: 0x%0x\n", HCL_NAME, hcl_debug); +#endif + printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options); + spin_lock_init(&hcl_spinlock); + + /* + * Create the hwgraph_root on devfs. + */ + rv = hwgraph_path_add(NULL, "hw", &hwgraph_root); + if (rv) + printk ("init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv); + + /* + * Create the hcl driver to support inventory entry manipulations. + * By default, it is expected that devfs is mounted on /dev. + * + */ + hcl_handle = hwgraph_register(hwgraph_root, ".hcl", + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + &hcl_fops, NULL); + + if (hcl_handle == NULL) { + panic("HCL: Unable to create HCL Driver in init_hcl().\n"); + return(0); + } + + /* + * Initialize the HCL string table. + */ + string_table_init(&label_string_table); + + return(0); + +} + + +/* + * hcl_setup() - Process boot time parameters if given. + * "hcl=" + * This routine gets called only if "hcl=" is given in the + * boot line and before init_hcl(). + * + * We currently do not have any boot options .. when we do, + * functionalities can be added here. + * + */ +static int __init hcl_setup(char *str) +{ + while ( (*str != '\0') && !isspace (*str) ) + { + printk("HCL: Boot time parameter %s\n", str); +#ifdef CONFIG_HCL_DEBUG + if (strncmp (str, "all", 3) == 0) { + hcl_debug_init |= HCL_DEBUG_ALL; + str += 3; + } else + return 0; +#endif + if (*str != ',') return 0; + ++str; + } + + return 1; + +} + +__setup("hcl=", hcl_setup); + + +/* + * Set device specific "fast information". + * + */ +void +hwgraph_fastinfo_set(devfs_handle_t de, arbitrary_info_t fastinfo) +{ + + if (hcl_debug) { + printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n", + de, fastinfo); + } + + labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL); + +} + + +/* + * Get device specific "fast information". + * + */ +arbitrary_info_t +hwgraph_fastinfo_get(devfs_handle_t de) +{ + arbitrary_info_t fastinfo; + int rv; + + if (!de) { + printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n"); + return(-1); + } + + rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo); + if (rv == 0) + return(fastinfo); + + return(0); +} + + +/* + * hwgraph_connectpt_set - Sets the connect point handle in de to the + * given connect_de handle. By default, the connect point of the + * devfs node is the parent. This effectively changes this assumption. + */ +int +hwgraph_connectpt_set(devfs_handle_t de, devfs_handle_t connect_de) +{ + int rv; + + if (!de) + return(-1); + + rv = labelcl_info_connectpt_set(de, connect_de); + + return(rv); +} + + +/* + * hwgraph_connectpt_get: Returns the entry's connect point in the devfs + * tree. + */ +devfs_handle_t +hwgraph_connectpt_get(devfs_handle_t de) +{ + int rv; + arbitrary_info_t info; + devfs_handle_t connect; + + rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); + if (rv != 0) { + return(NULL); + } + + connect = (devfs_handle_t)info; + return(connect); + +} + + +/* + * hwgraph_mk_dir - Creates a directory entry with devfs. + * Note that a directory entry in devfs can have children + * but it cannot be a char|block special file. + */ +devfs_handle_t +hwgraph_mk_dir(devfs_handle_t de, const char *name, + unsigned int namelen, void *info) +{ + + int rv; + labelcl_info_t *labelcl_info = NULL; + devfs_handle_t new_devfs_handle = NULL; + devfs_handle_t parent = NULL; + + /* + * Create the device info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(NULL); + + /* + * Create a devfs entry. + */ + new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info); + if (!new_devfs_handle) { + labelcl_info_destroy(labelcl_info); + return(NULL); + } + + /* + * Get the parent handle. + */ + parent = devfs_get_parent (new_devfs_handle); + + /* + * To provide the same semantics as the hwgraph, set the connect point. + */ + rv = hwgraph_connectpt_set(new_devfs_handle, parent); + if (!rv) { + /* + * We need to clean up! + */ + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); + + return(new_devfs_handle); + +} + +/* + * hwgraph_vertex_create - Create a vertex by giving it a temp name. + */ + +/* + * hwgraph_path_add - Create a directory node with the given path starting + * from the given devfs_handle_t. + */ +extern char * dev_to_name(devfs_handle_t, char *, uint); +int +hwgraph_path_add(devfs_handle_t fromv, + char *path, + devfs_handle_t *new_de) +{ + + unsigned int namelen = strlen(path); + int rv; + + /* + * We need to handle the case when fromv is NULL .. + * in this case we need to create the path from the + * hwgraph root! + */ + if (fromv == NULL) + fromv = hwgraph_root; + + /* + * check the entry doesn't already exist, if it does + * then we simply want new_de to point to it (otherwise + * we'll overwrite the existing labelcl_info struct) + */ + rv = hwgraph_edge_get(fromv, path, new_de); + if (rv) { /* couldn't find entry so we create it */ + *new_de = hwgraph_mk_dir(fromv, path, namelen, NULL); + if (new_de == NULL) + return(-1); + else + return(0); + } + else + return(0); + +} + +/* + * hwgraph_register - Creates a file entry with devfs. + * Note that a file entry cannot have children .. it is like a + * char|block special vertex in hwgraph. + */ +devfs_handle_t +hwgraph_register(devfs_handle_t de, const char *name, + unsigned int namelen, unsigned int flags, + unsigned int major, unsigned int minor, + umode_t mode, uid_t uid, gid_t gid, + struct file_operations *fops, + void *info) +{ + + int rv; + void *labelcl_info = NULL; + devfs_handle_t new_devfs_handle = NULL; + devfs_handle_t parent = NULL; + + /* + * Create the labelcl info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(NULL); + + /* + * Create a devfs entry. + */ + new_devfs_handle = devfs_register(de, name, flags, major, + minor, mode, fops, labelcl_info); + if (!new_devfs_handle) { + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + return(NULL); + } + + /* + * Get the parent handle. + */ + if (de == NULL) + parent = devfs_get_parent (new_devfs_handle); + else + parent = de; + + /* + * To provide the same semantics as the hwgraph, set the connect point. + */ + rv = hwgraph_connectpt_set(new_devfs_handle, parent); + if (rv) { + /* + * We need to clean up! + */ + printk("HCL: Unable to set the connect point to it's parent 0x%p\n", + new_devfs_handle); + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); + + return(new_devfs_handle); + +} + + +/* + * hwgraph_mk_symlink - Create a symbolic link. + */ +int +hwgraph_mk_symlink(devfs_handle_t de, const char *name, unsigned int namelen, + unsigned int flags, const char *link, unsigned int linklen, + devfs_handle_t *handle, void *info) +{ + + void *labelcl_info = NULL; + int status = 0; + devfs_handle_t new_devfs_handle = NULL; + + /* + * Create the labelcl info structure for hwgraph compatiblity support. + */ + labelcl_info = labelcl_info_create(); + if (!labelcl_info) + return(-1); + + /* + * Create a symbolic link devfs entry. + */ + status = devfs_mk_symlink(de, name, flags, link, + &new_devfs_handle, labelcl_info); + if ( (!new_devfs_handle) || (!status) ){ + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + return(-1); + } + + /* + * If the caller provides a private data pointer, save it in the + * labelcl info structure(fastinfo). This can be retrieved via + * hwgraph_fastinfo_get() + */ + if (info) + hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info); + + *handle = new_devfs_handle; + return(0); + +} + +/* + * hwgraph_vertex_get_next - this routine returns the next sibbling for the + * device entry given in de. If there are no more sibbling, NULL + * is returned in next_sibbling. + * + * Currently we do not have any protection against de being deleted + * while it's handle is being held. + */ +int +hwgraph_vertex_get_next(devfs_handle_t *next_sibbling, devfs_handle_t *de) +{ + *next_sibbling = devfs_get_next_sibling (*de); + + if (*next_sibbling != NULL) + *de = *next_sibbling; + return (0); +} + + +/* + * hwgraph_vertex_destroy - Destroy the devfs entry + */ +int +hwgraph_vertex_destroy(devfs_handle_t de) +{ + + void *labelcl_info = NULL; + + labelcl_info = devfs_get_info(de); + devfs_unregister(de); + + if (labelcl_info) + labelcl_info_destroy((labelcl_info_t *)labelcl_info); + + return(0); +} + +/* +** See if a vertex has an outgoing edge with a specified name. +** Vertices in the hwgraph *implicitly* contain these edges: +** "." refers to "current vertex" +** ".." refers to "connect point vertex" +** "char" refers to current vertex (character device access) +** "block" refers to current vertex (block device access) +*/ + +/* + * hwgraph_edge_add - This routines has changed from the original conext. + * All it does now is to create a symbolic link from "from" to "to". + */ +/* ARGSUSED */ +int +hwgraph_edge_add(devfs_handle_t from, devfs_handle_t to, char *name) +{ + + char *path; + int name_start; + devfs_handle_t handle = NULL; + int rv; + + path = kmalloc(1024, GFP_KERNEL); + name_start = devfs_generate_path (to, path, 1024); + + /* + * Otherwise, just create a symlink to the vertex. + * In this case the vertex was previous created with a REAL pathname. + */ + rv = devfs_mk_symlink (from, (const char *)name, + DEVFS_FL_DEFAULT, (const char *)&path[name_start], + &handle, NULL); + + name_start = devfs_generate_path (handle, path, 1024); + return(rv); + + +} +/* ARGSUSED */ +int +hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr) +{ + + int namelen = 0; + devfs_handle_t target_handle = NULL; + + if (name == NULL) + return(-1); + + if (toptr == NULL) + return(-1); + + /* + * If the name is "." just return the current devfs entry handle. + */ + if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) { + if (toptr) { + *toptr = from; + } + } else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) { + /* + * Hmmm .. should we return the connect point or parent .. + * see in hwgraph, the concept of parent is the connectpt! + * + * Maybe we should see whether the connectpt is set .. if + * not just return the parent! + */ + target_handle = hwgraph_connectpt_get(from); + if (target_handle) { + /* + * Just return the connect point. + */ + *toptr = target_handle; + return(0); + } + target_handle = devfs_get_parent(from); + *toptr = target_handle; + + } else { + /* + * Call devfs to get the devfs entry. + */ + namelen = (int) strlen(name); + target_handle = devfs_find_handle (from, name, 0, 0, + 0, 1); /* Yes traverse symbolic links */ + if (target_handle == NULL) + return(-1); + else + *toptr = target_handle; + } + + return(0); +} + + +/* + * hwgraph_edge_get_next - Retrieves the next sibbling given the current + * entry number "placeptr". + * + * Allow the caller to retrieve walk through the sibblings of "source" + * devfs_handle_t. The implicit edges "." and ".." is returned first + * followed by each of the real children. + * + * We may end up returning garbage if another thread perform any deletion + * in this directory before "placeptr". + * + */ +/* ARGSUSED */ +int +hwgraph_edge_get_next(devfs_handle_t source, char *name, devfs_handle_t *target, + uint *placeptr) + +{ + + uint which_place; + unsigned int namelen = 0; + const char *tempname = NULL; + + if (placeptr == NULL) + return(-1); + + which_place = *placeptr; + +again: + if (which_place <= HWGRAPH_RESERVED_PLACES) { + if (which_place == EDGE_PLACE_WANT_CURRENT) { + /* + * Looking for "." + * Return the current devfs handle. + */ + if (name != NULL) + strcpy(name, HWGRAPH_EDGELBL_DOT); + + if (target != NULL) { + *target = source; + /* XXX should incr "source" ref count here if we + * ever implement ref counts */ + } + + } else if (which_place == EDGE_PLACE_WANT_CONNECTPT) { + /* + * Looking for the connect point or parent. + * If the connect point is set .. it returns the connect point. + * Otherwise, it returns the parent .. will we support + * connect point? + */ + devfs_handle_t connect_point = hwgraph_connectpt_get(source); + + if (connect_point == NULL) { + /* + * No connectpoint set .. either the User + * explicitly NULL it or this node was not + * created via hcl. + */ + which_place++; + goto again; + } + + if (name != NULL) + strcpy(name, HWGRAPH_EDGELBL_DOTDOT); + + if (target != NULL) + *target = connect_point; + + } else if (which_place == EDGE_PLACE_WANT_REAL_EDGES) { + /* + * return first "real" entry in directory, and increment + * placeptr. Next time around we should have + * which_place > HWGRAPH_RESERVED_EDGES so we'll fall through + * this nested if block. + */ + *target = devfs_get_first_child(source); + if (*target && name) { + tempname = devfs_get_name(*target, &namelen); + if (tempname && namelen) + strcpy(name, tempname); + } + + *placeptr = which_place + 1; + return (0); + } + + *placeptr = which_place+1; + return(0); + } + + /* + * walk linked list, (which_place - HWGRAPH_RESERVED_PLACES) times + */ + { + devfs_handle_t curr; + int i = 0; + + for (curr=devfs_get_first_child(source), i= i+HWGRAPH_RESERVED_PLACES; + curr!=NULL && iinv_next) { + if ((int)class != -1 && old_pinv->inv_class != class) + continue; + if ((int)type != -1 && old_pinv->inv_type != type) + continue; + if ((int)state != -1 && old_pinv->inv_state != state) + continue; + if ((int)controller != -1 + && old_pinv->inv_controller != controller) + continue; + if ((int)unit != -1 && old_pinv->inv_unit != unit) + continue; + + /* exact duplicate of previously-added inventory item */ + rv = LABELCL_DUP; + goto failure; + } + + /* Not a duplicate, so we know that we need to add something. */ + if (pinv == NULL) { + /* Release lock while we wait for memory. */ + /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ + pinv = (inventory_t *)kmalloc(sizeof(inventory_t), GFP_KERNEL); + replace_in_inventory(pinv, class, type, controller, unit, state); + goto again; + } + + pinv->inv_next = NULL; + if (last_pinv) { + last_pinv->inv_next = pinv; + } else { + rv = labelcl_info_add_LBL(de, INFO_LBL_INVENT, + sizeof(inventory_t), (arbitrary_info_t)pinv); + + if (!rv) + goto failure; + } + + /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ + return(0); + +failure: + /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ + if (pinv) + kfree(pinv); + return(rv); +} + + +/* + * hwgraph_inventory_remove - Removes an inventory entry. + * + * Remove an inventory item associated with a vertex. It is the caller's + * responsibility to make sure that there are no races between removing + * inventory from a vertex and simultaneously removing that vertex. +*/ +int +hwgraph_inventory_remove( devfs_handle_t de, + int class, + int type, + major_t controller, + minor_t unit, + int state) +{ + inventory_t *pinv = NULL, *last_pinv = NULL, *next_pinv = NULL; + labelcl_error_t rv; + + /* + * We never remove stuff from ".invent" .. + */ + if (!de) + return (-1); + + /* + * Remove our inventory data to the list of inventory data + * associated with this vertex. + */ + /* GRAPH_LOCK_UPDATE(&invent_lock); */ + rv = labelcl_info_get_LBL(de, + INFO_LBL_INVENT, + NULL, (arbitrary_info_t *)&pinv); + if (rv != LABELCL_SUCCESS) + goto failure; + + /* + * Search through inventory items associated with this + * vertex, looking for a match. + */ + for (;pinv; pinv = next_pinv) { + next_pinv = pinv->inv_next; + + if(((int)class == -1 || pinv->inv_class == class) && + ((int)type == -1 || pinv->inv_type == type) && + ((int)state == -1 || pinv->inv_state == state) && + ((int)controller == -1 || pinv->inv_controller == controller) && + ((int)unit == -1 || pinv->inv_unit == unit)) { + + /* Found a matching inventory item. Remove it. */ + if (last_pinv) { + last_pinv->inv_next = pinv->inv_next; + } else { + rv = hwgraph_info_replace_LBL(de, INFO_LBL_INVENT, (arbitrary_info_t)pinv->inv_next, NULL); + if (rv != LABELCL_SUCCESS) + goto failure; + } + + pinv->inv_next = NULL; /* sanity */ + kfree(pinv); + } else + last_pinv = pinv; + } + + if (last_pinv == NULL) { + rv = hwgraph_info_remove_LBL(de, INFO_LBL_INVENT, NULL); + if (rv != LABELCL_SUCCESS) + goto failure; + } + + rv = LABELCL_SUCCESS; + +failure: + /* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */ + return(rv); +} + +/* + * hwgraph_inventory_get_next - Get next inventory item associated with the + * specified vertex. + * + * No locking is really needed. We don't yet have the ability + * to remove inventory items, and new items are always added to + * the end of a vertex' inventory list. + * + * However, a devfs entry can be removed! +*/ +int +hwgraph_inventory_get_next(devfs_handle_t de, invplace_t *place, inventory_t **ppinv) +{ + inventory_t *pinv; + labelcl_error_t rv; + + if (de == NULL) + return(LABELCL_BAD_PARAM); + + if (place->invplace_vhdl == NULL) { + place->invplace_vhdl = de; + place->invplace_inv = NULL; + } + + if (de != place->invplace_vhdl) + return(LABELCL_BAD_PARAM); + + if (place->invplace_inv == NULL) { + /* Just starting on this vertex */ + rv = labelcl_info_get_LBL(de, INFO_LBL_INVENT, + NULL, (arbitrary_info_t *)&pinv); + if (rv != LABELCL_SUCCESS) + return(LABELCL_NOT_FOUND); + + } else { + /* Advance to next item on this vertex */ + pinv = place->invplace_inv->inv_next; + } + place->invplace_inv = pinv; + *ppinv = pinv; + + return(LABELCL_SUCCESS); +} + +/* + * hwgraph_controller_num_get - Returns the controller number in the inventory + * entry. + */ +int +hwgraph_controller_num_get(devfs_handle_t device) +{ + inventory_t *pinv; + invplace_t invplace = { NULL, NULL, NULL }; + int val = -1; + if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) { + val = (pinv->inv_class == INV_NETWORK)? pinv->inv_unit: pinv->inv_controller; + } +#ifdef DEBUG + /* + * It does not make any sense to call this on vertexes with multiple + * inventory structs chained together + */ + if ( device_inventory_get_next(device, &invplace) != NULL ) { + printk("Should panic here ... !\n"); +#endif + return (val); +} + +/* + * hwgraph_controller_num_set - Sets the controller number in the inventory + * entry. + */ +void +hwgraph_controller_num_set(devfs_handle_t device, int contr_num) +{ + inventory_t *pinv; + invplace_t invplace = { NULL, NULL, NULL }; + if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) { + if (pinv->inv_class == INV_NETWORK) + pinv->inv_unit = contr_num; + else { + if (pinv->inv_class == INV_FCNODE) + pinv = device_inventory_get_next(device, &invplace); + if (pinv != NULL) + pinv->inv_controller = contr_num; + } + } +#ifdef DEBUG + /* + * It does not make any sense to call this on vertexes with multiple + * inventory structs chained together + */ + if(pinv != NULL) + ASSERT(device_inventory_get_next(device, &invplace) == NULL); +#endif +} + +/* + * Find the canonical name for a given vertex by walking back through + * connectpt's until we hit the hwgraph root vertex (or until we run + * out of buffer space or until something goes wrong). + * + * COMPATIBILITY FUNCTIONALITY + * Walks back through 'parents', not necessarily the same as connectpts. + * + * Need to resolve the fact that devfs does not return the path from + * "/" but rather it just stops right before /dev .. + */ +int +hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen) +{ + char *locbuf; + int pos; + + if (buflen < 1) + return(-1); /* XXX should be GRAPH_BAD_PARAM ? */ + + locbuf = kmalloc(buflen, GFP_KERNEL); + + pos = devfs_generate_path(vhdl, locbuf, buflen); + if (pos < 0) { + kfree(locbuf); + return pos; + } + + strcpy(buf, &locbuf[pos]); + kfree(locbuf); + return 0; +} + +/* +** vertex_to_name converts a vertex into a canonical name by walking +** back through connect points until we hit the hwgraph root (or until +** we run out of buffer space). +** +** Usually returns a pointer to the original buffer, filled in as +** appropriate. If the buffer is too small to hold the entire name, +** or if anything goes wrong while determining the name, vertex_to_name +** returns "UnknownDevice". +*/ + +#define DEVNAME_UNKNOWN "UnknownDevice" + +char * +vertex_to_name(devfs_handle_t vhdl, char *buf, uint buflen) +{ + if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS) + return(buf); + else + return(DEVNAME_UNKNOWN); +} + +#ifdef IRIX +/* +** Return the compact node id of the node that ultimately "owns" the specified +** vertex. In order to do this, we walk back through masters and connect points +** until we reach a vertex that represents a node. +*/ +cnodeid_t +master_node_get(devfs_handle_t vhdl) +{ + cnodeid_t cnodeid; + devfs_handle_t master; + + for (;;) { + cnodeid = nodevertex_to_cnodeid(vhdl); + if (cnodeid != CNODEID_NONE) + return(cnodeid); + + master = device_master_get(vhdl); + + /* Check for exceptional cases */ + if (master == vhdl) { + /* Since we got a reference to the "master" thru + * device_master_get() we should decrement + * its reference count by 1 + */ + hwgraph_vertex_unref(master); + return(CNODEID_NONE); + } + + if (master == GRAPH_VERTEX_NONE) { + master = hwgraph_connectpt_get(vhdl); + if ((master == GRAPH_VERTEX_NONE) || + (master == vhdl)) { + if (master == vhdl) + /* Since we got a reference to the + * "master" thru + * hwgraph_connectpt_get() we should + * decrement its reference count by 1 + */ + hwgraph_vertex_unref(master); + return(CNODEID_NONE); + } + } + + vhdl = master; + /* Decrement the reference to "master" which was got + * either thru device_master_get() or hwgraph_connectpt_get() + * above. + */ + hwgraph_vertex_unref(master); + } +} + +/* + * Using the canonical path name to get hold of the desired vertex handle will + * not work on multi-hub sn0 nodes. Hence, we use the following (slightly + * convoluted) algorithm. + * + * - Start at the vertex corresponding to the driver (provided as input parameter) + * - Loop till you reach a vertex which has EDGE_LBL_MEMORY + * - If EDGE_LBL_CONN exists, follow that up. + * else if EDGE_LBL_MASTER exists, follow that up. + * else follow EDGE_LBL_DOTDOT up. + * + * * We should be at desired hub/heart vertex now * + * - Follow EDGE_LBL_CONN to the widget vertex. + * + * - return vertex handle of this widget. + */ +devfs_handle_t +mem_vhdl_get(devfs_handle_t drv_vhdl) +{ +devfs_handle_t cur_vhdl, cur_upper_vhdl; +devfs_handle_t tmp_mem_vhdl, mem_vhdl; +graph_error_t loop_rv; + + /* Initializations */ + cur_vhdl = drv_vhdl; + loop_rv = ~GRAPH_SUCCESS; + + /* Loop till current vertex has EDGE_LBL_MEMORY */ + while (loop_rv != GRAPH_SUCCESS) { + + if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &cur_upper_vhdl)) == GRAPH_SUCCESS) { + + } else if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_MASTER, &cur_upper_vhdl)) == GRAPH_SUCCESS) { + } else { /* Follow HWGRAPH_EDGELBL_DOTDOT up */ + (void) hwgraph_edge_get(cur_vhdl, HWGRAPH_EDGELBL_DOTDOT, &cur_upper_vhdl); + } + + cur_vhdl = cur_upper_vhdl; + +#if DEBUG && HWG_DEBUG + printf("Current vhdl %d \n", cur_vhdl); +#endif /* DEBUG */ + + loop_rv = hwgraph_edge_get(cur_vhdl, EDGE_LBL_MEMORY, &tmp_mem_vhdl); + } + + /* We should be at desired hub/heart vertex now */ + if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &mem_vhdl)) != GRAPH_SUCCESS) + return (GRAPH_VERTEX_NONE); + + return (mem_vhdl); +} +#endif /* IRIX */ + + +/* +** Add a char device -- if the driver supports it -- at a specified vertex. +*/ +graph_error_t +hwgraph_char_device_add( devfs_handle_t from, + char *path, + char *prefix, + devfs_handle_t *devhdl) +{ + devfs_handle_t xx = NULL; + + printk("FIXME: hwgraph_char_device_add() called. Use hwgraph_register.\n"); + *devhdl = xx; // Must set devhdl + return(GRAPH_SUCCESS); +} + +graph_error_t +hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr) +{ + printk("FIXME: hwgraph_edge_remove\n"); + return(GRAPH_ILLEGAL_REQUEST); +} + +graph_error_t +hwgraph_vertex_unref(devfs_handle_t vhdl) +{ + printk("FIXME: hwgraph_vertex_unref\n"); + return(GRAPH_ILLEGAL_REQUEST); +} + + +EXPORT_SYMBOL(hwgraph_mk_dir); +EXPORT_SYMBOL(hwgraph_path_add); +EXPORT_SYMBOL(hwgraph_char_device_add); +EXPORT_SYMBOL(hwgraph_register); +EXPORT_SYMBOL(hwgraph_vertex_destroy); + +EXPORT_SYMBOL(hwgraph_fastinfo_get); +EXPORT_SYMBOL(hwgraph_edge_get); + +EXPORT_SYMBOL(hwgraph_fastinfo_set); +EXPORT_SYMBOL(hwgraph_connectpt_set); +EXPORT_SYMBOL(hwgraph_connectpt_get); +EXPORT_SYMBOL(hwgraph_edge_get_next); +EXPORT_SYMBOL(hwgraph_info_add_LBL); +EXPORT_SYMBOL(hwgraph_info_remove_LBL); +EXPORT_SYMBOL(hwgraph_info_replace_LBL); +EXPORT_SYMBOL(hwgraph_info_get_LBL); +EXPORT_SYMBOL(hwgraph_info_get_exported_LBL); +EXPORT_SYMBOL(hwgraph_info_get_next_LBL); +EXPORT_SYMBOL(hwgraph_info_export_LBL); +EXPORT_SYMBOL(hwgraph_info_unexport_LBL); +EXPORT_SYMBOL(hwgraph_path_lookup); +EXPORT_SYMBOL(hwgraph_traverse); +EXPORT_SYMBOL(hwgraph_path_to_vertex); +EXPORT_SYMBOL(hwgraph_path_to_dev); +EXPORT_SYMBOL(hwgraph_block_device_get); +EXPORT_SYMBOL(hwgraph_char_device_get); +EXPORT_SYMBOL(hwgraph_cdevsw_get); +EXPORT_SYMBOL(hwgraph_bdevsw_get); +EXPORT_SYMBOL(hwgraph_vertex_name_get); diff -urN linux-2.4.0-test12/arch/ia64/sn/io/hcl_util.c linux-2.4.0-test12-lia/arch/ia64/sn/io/hcl_util.c --- linux-2.4.0-test12/arch/ia64/sn/io/hcl_util.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/hcl_util.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,160 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static devfs_handle_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE; +extern devfs_handle_t hwgraph_root; + + +/* +** Return the "master" for a given vertex. A master vertex is a +** controller or adapter or other piece of hardware that the given +** vertex passes through on the way to the rest of the system. +*/ +devfs_handle_t +device_master_get(devfs_handle_t vhdl) +{ + graph_error_t rc; + devfs_handle_t master; + + rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master); + if (rc == GRAPH_SUCCESS) + return(master); + else + return(GRAPH_VERTEX_NONE); +} + +/* +** Set the master for a given vertex. +** Returns 0 on success, non-0 indicates failure +*/ +int +device_master_set(devfs_handle_t vhdl, devfs_handle_t master) +{ + graph_error_t rc; + + rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER); + return(rc != GRAPH_SUCCESS); +} + + +/* +** Return the compact node id of the node that ultimately "owns" the specified +** vertex. In order to do this, we walk back through masters and connect points +** until we reach a vertex that represents a node. +*/ +cnodeid_t +master_node_get(devfs_handle_t vhdl) +{ + cnodeid_t cnodeid; + devfs_handle_t master; + + for (;;) { + cnodeid = nodevertex_to_cnodeid(vhdl); + if (cnodeid != CNODEID_NONE) + return(cnodeid); + + master = device_master_get(vhdl); + + /* Check for exceptional cases */ + if (master == vhdl) { + /* Since we got a reference to the "master" thru + * device_master_get() we should decrement + * its reference count by 1 + */ + return(CNODEID_NONE); + } + + if (master == GRAPH_VERTEX_NONE) { + master = hwgraph_connectpt_get(vhdl); + if ((master == GRAPH_VERTEX_NONE) || + (master == vhdl)) { + return(CNODEID_NONE); + } + } + + vhdl = master; + } +} + +/* +** If the specified device represents a node, return its +** compact node ID; otherwise, return CNODEID_NONE. +*/ +cnodeid_t +nodevertex_to_cnodeid(devfs_handle_t vhdl) +{ + int rv = 0; + arbitrary_info_t cnodeid = CNODEID_NONE; + + rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid); + + return((cnodeid_t)cnodeid); +} + +void +mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid) +{ + if (cnodeid == CNODEID_NONE) + return; + + cnodeid_to_vertex(cnodeid) = vhdl; + labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, + (arbitrary_info_t)cnodeid); + + { + char cnodeid_buffer[10]; + + if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) { + (void)hwgraph_path_add( hwgraph_root, + EDGE_LBL_NODENUM, + &hwgraph_all_cnodes); + } + + sprintf(cnodeid_buffer, "%d", cnodeid); + (void)hwgraph_edge_add( hwgraph_all_cnodes, + vhdl, + cnodeid_buffer); + } +} + + +/* +** dev_to_name converts a devfs_handle_t into a canonical name. If the devfs_handle_t +** represents a vertex in the hardware graph, it is converted in the +** normal way for vertices. If the devfs_handle_t is an old devfs_handle_t (one which +** does not represent a hwgraph vertex), we synthesize a name based +** on major/minor number. +** +** Usually returns a pointer to the original buffer, filled in as +** appropriate. If the buffer is too small to hold the entire name, +** or if anything goes wrong while determining the name, dev_to_name +** returns "UnknownDevice". +*/ +char * +dev_to_name(devfs_handle_t dev, char *buf, uint buflen) +{ + return(vertex_to_name(dev, buf, buflen)); +} + + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/hubdev.c linux-2.4.0-test12-lia/arch/ia64/sn/io/hubdev.c --- linux-2.4.0-test12/arch/ia64/sn/io/hubdev.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/hubdev.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,127 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct hubdev_callout { + int (*attach_method)(devfs_handle_t); + struct hubdev_callout *fp; +}; + +typedef struct hubdev_callout hubdev_callout_t; + +mutex_t hubdev_callout_mutex; +hubdev_callout_t *hubdev_callout_list = NULL; + +void +hubdev_init(void) +{ + mutex_init(&hubdev_callout_mutex, MUTEX_DEFAULT, "hubdev"); + hubdev_callout_list = NULL; +} + +void +hubdev_register(int (*attach_method)(devfs_handle_t)) +{ + hubdev_callout_t *callout; + + ASSERT(attach_method); + + callout = (hubdev_callout_t *)kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP); + ASSERT(callout); + + mutex_lock(&hubdev_callout_mutex, PZERO); + /* + * Insert at the front of the list + */ + callout->fp = hubdev_callout_list; + hubdev_callout_list = callout; + callout->attach_method = attach_method; + mutex_unlock(&hubdev_callout_mutex); +} + +int +hubdev_unregister(int (*attach_method)(devfs_handle_t)) +{ + hubdev_callout_t **p; + + ASSERT(attach_method); + + mutex_lock(&hubdev_callout_mutex, PZERO); + /* + * Remove registry element containing attach_method + */ + for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) { + if ((*p)->attach_method == attach_method) { + hubdev_callout_t* victim = *p; + *p = (*p)->fp; + kfree(victim); + mutex_unlock(&hubdev_callout_mutex); + return (0); + } + } + mutex_unlock(&hubdev_callout_mutex); + return (ENOENT); +} + + +int +hubdev_docallouts(devfs_handle_t hub) +{ + hubdev_callout_t *p; + int errcode; + + mutex_lock(&hubdev_callout_mutex, PZERO); + + for (p = hubdev_callout_list; p != NULL; p = p->fp) { + ASSERT(p->attach_method); + errcode = (*p->attach_method)(hub); + if (errcode != 0) { + mutex_unlock(&hubdev_callout_mutex); + return (errcode); + } + } + mutex_unlock(&hubdev_callout_mutex); + return (0); +} + +/* + * Given a hub vertex, return the base address of the Hspec space + * for that hub. + */ +caddr_t +hubdev_prombase_get(devfs_handle_t hub) +{ + hubinfo_t hinfo = NULL; + + hubinfo_get(hub, &hinfo); + ASSERT(hinfo); + + return ((caddr_t)NODE_RBOOT_BASE(hinfo->h_nasid)); +} + +cnodeid_t +hubdev_cnodeid_get(devfs_handle_t hub) +{ + hubinfo_t hinfo = NULL; + hubinfo_get(hub, &hinfo); + ASSERT(hinfo); + + return hinfo->h_cnodeid; +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/hubspc.c linux-2.4.0-test12-lia/arch/ia64/sn/io/hubspc.c --- linux-2.4.0-test12/arch/ia64/sn/io/hubspc.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/hubspc.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,447 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* + * hubspc.c - Hub Memory Space Management Driver + * This driver implements the managers for the following + * memory resources: + * 1) reference counters + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#include +#include +#endif + +#include + + +/* Uncomment the following line for tracing */ +/* #define HUBSPC_DEBUG 1 */ + +int hubspc_devflag = D_MP; + +extern void *device_info_get(devfs_handle_t device); +extern void device_info_set(devfs_handle_t device, void *info); + + + +/***********************************************************************/ +/* CPU Prom Space */ +/***********************************************************************/ + +typedef struct cpuprom_info { + devfs_handle_t prom_dev; + devfs_handle_t nodevrtx; + struct cpuprom_info *next; +}cpuprom_info_t; + +static cpuprom_info_t *cpuprom_head; +lock_t cpuprom_spinlock; +#define PROM_LOCK() mutex_spinlock(&cpuprom_spinlock) +#define PROM_UNLOCK(s) mutex_spinunlock(&cpuprom_spinlock, (s)) + +/* + * Add prominfo to the linked list maintained. + */ +void +prominfo_add(devfs_handle_t hub, devfs_handle_t prom) +{ + cpuprom_info_t *info; + int s; + + info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL); + ASSERT(info); + info->prom_dev = prom; + info->nodevrtx = hub; + + + s = PROM_LOCK(); + info->next = cpuprom_head; + cpuprom_head = info; + PROM_UNLOCK(s); +} + +void +prominfo_del(devfs_handle_t prom) +{ + int s; + cpuprom_info_t *info; + cpuprom_info_t **prev; + + s = PROM_LOCK(); + prev = &cpuprom_head; + while ( (info = *prev) ) { + if (info->prom_dev == prom) { + *prev = info->next; + PROM_UNLOCK(s); + return; + } + + prev = &info->next; + } + PROM_UNLOCK(s); + ASSERT(0); +} + +devfs_handle_t +prominfo_nodeget(devfs_handle_t prom) +{ + int s; + cpuprom_info_t *info; + + s = PROM_LOCK(); + info = cpuprom_head; + while (info) { + if(info->prom_dev == prom) { + PROM_UNLOCK(s); + return info->nodevrtx; + } + info = info->next; + } + PROM_UNLOCK(s); + return 0; +} + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define SN_PROMVERSION INV_IP35PROM +#endif + +/* Add "detailed" labelled inventory information to the + * prom vertex + */ +void +cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node) +{ + invent_miscinfo_t *cpuprom_inventory_info; + extern invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, + int class, int size); + cnodeid_t cnode = hubdev_cnodeid_get(node); + + /* Allocate memory for the extra inventory information + * for the prom + */ + cpuprom_inventory_info = (invent_miscinfo_t *) + klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); + + ASSERT(cpuprom_inventory_info); + + /* Set the enabled flag so that the hinv interprets this + * information + */ + cpuprom_inventory_info->im_gen.ig_flag = INVENT_ENABLED; + cpuprom_inventory_info->im_type = SN_PROMVERSION; + /* Store prom revision into inventory information */ + cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev; + cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers; + + + /* Store this info as labelled information hanging off the + * prom device vertex + */ + hwgraph_info_add_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t) cpuprom_inventory_info); + /* Export this information so that user programs can get to + * this by using attr_get() + */ + hwgraph_info_export_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, + sizeof(invent_miscinfo_t)); +} + +int +cpuprom_attach(devfs_handle_t node) +{ + devfs_handle_t prom_dev; + + hwgraph_char_device_add(node, EDGE_LBL_PROM, "hubspc_", &prom_dev); +#ifdef HUBSPC_DEBUG + printf("hubspc: prom_attach hub: 0x%x prom: 0x%x\n", node, prom_dev); +#endif /* HUBSPC_DEBUG */ + device_inventory_add(prom_dev, INV_PROM, SN_PROMVERSION, + (major_t)0, (minor_t)0, 0); + + /* Add additional inventory info about the cpu prom like + * revision & version numbers etc. + */ + cpuprom_detailed_inventory_info_add(prom_dev,node); + device_info_set(prom_dev, (void*)(ulong)HUBSPC_PROM); + prominfo_add(node, prom_dev); + + return (0); +} + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define FPROM_CONFIG_ADDR MD_JUNK_BUS_TIMING +#define FPROM_ENABLE_MASK MJT_FPROM_ENABLE_MASK +#define FPROM_ENABLE_SHFT MJT_FPROM_ENABLE_SHFT +#define FPROM_SETUP_MASK MJT_FPROM_SETUP_MASK +#define FPROM_SETUP_SHFT MJT_FPROM_SETUP_SHFT +#endif + +/*ARGSUSED*/ +int +cpuprom_map(devfs_handle_t dev, vhandl_t *vt, off_t addr, size_t len) +{ + int errcode; + caddr_t kvaddr; + devfs_handle_t node; + cnodeid_t cnode; + + node = prominfo_nodeget(dev); + + if (!node) + return EIO; + + + kvaddr = hubdev_prombase_get(node); + cnode = hubdev_cnodeid_get(node); +#ifdef HUBSPC_DEBUG + printf("cpuprom_map: hubnode %d kvaddr 0x%x\n", node, kvaddr); +#endif + + if (len > RBOOT_SIZE) + len = RBOOT_SIZE; + /* + * Map in the prom space + */ + errcode = v_mapphys(vt, kvaddr, len); + + if (errcode == 0 ){ + /* + * Set the MD configuration registers suitably. + */ + nasid_t nasid; + uint64_t value; + volatile hubreg_t *regaddr; + + nasid = COMPACT_TO_NASID_NODEID(cnode); + regaddr = REMOTE_HUB_ADDR(nasid, FPROM_CONFIG_ADDR); + value = HUB_L(regaddr); + value &= ~(FPROM_SETUP_MASK | FPROM_ENABLE_MASK); + { + value |= (((long)CONFIG_FPROM_SETUP << FPROM_SETUP_SHFT) | + ((long)CONFIG_FPROM_ENABLE << FPROM_ENABLE_SHFT)); + } + HUB_S(regaddr, value); + + } + return (errcode); +} + +/*ARGSUSED*/ +int +cpuprom_unmap(devfs_handle_t dev, vhandl_t *vt) +{ + return 0; +} + +/***********************************************************************/ +/* Base Hub Space Driver */ +/***********************************************************************/ + +// extern int l1_attach( devfs_handle_t ); + +/* + * hubspc_init + * Registration of the hubspc devices with the hub manager + */ +void +hubspc_init(void) +{ + /* + * Register with the hub manager + */ + + /* The reference counters */ + hubdev_register(mem_refcnt_attach); + + /* Prom space */ + hubdev_register(cpuprom_attach); + +#if defined(CONFIG_SERIAL_SGI_L1_PROTOCOL) + /* L1 system controller link */ + if ( !IS_RUNNING_ON_SIMULATOR() ) { + /* initialize the L1 link */ + void l1_cons_init( l1sc_t *sc ); + elsc_t *get_elsc(void); + + l1_cons_init((l1sc_t *)get_elsc()); + } +#endif + +#ifdef HUBSPC_DEBUG + printf("hubspc_init: Completed\n"); +#endif /* HUBSPC_DEBUG */ + /* Initialize spinlocks */ + spinlock_init(&cpuprom_spinlock, "promlist"); +} + +/* ARGSUSED */ +int +hubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp) +{ + int errcode = 0; + + switch ((hubspc_subdevice_t)(ulong)device_info_get(*devp)) { + case HUBSPC_REFCOUNTERS: + errcode = mem_refcnt_open(devp, oflag, otyp, crp); + break; + + case HUBSPC_PROM: + /* Check if the user has proper access rights to + * read/write the prom space. + */ + if (!cap_able(CAP_DEVICE_MGT)) { + errcode = EPERM; + } + break; + + default: + errcode = ENODEV; + } + +#ifdef HUBSPC_DEBUG + printf("hubspc_open: Completed open for type %d\n", + (hubspc_subdevice_t)(ulong)device_info_get(*devp)); +#endif /* HUBSPC_DEBUG */ + + return (errcode); +} + + +/* ARGSUSED */ +int +hubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) +{ + int errcode = 0; + + switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) { + case HUBSPC_REFCOUNTERS: + errcode = mem_refcnt_close(dev, oflag, otyp, crp); + break; + + case HUBSPC_PROM: + break; + default: + errcode = ENODEV; + } + +#ifdef HUBSPC_DEBUG + printf("hubspc_close: Completed close for type %d\n", + (hubspc_subdevice_t)(ulong)device_info_get(dev)); +#endif /* HUBSPC_DEBUG */ + + return (errcode); +} + +/* ARGSUSED */ +int +hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) +{ + /*REFERENCED*/ + hubspc_subdevice_t subdevice; + int errcode = 0; + + /* check validity of request */ + if( len == 0 ) { + return ENXIO; + } + + subdevice = (hubspc_subdevice_t)(ulong)device_info_get(dev); + +#ifdef HUBSPC_DEBUG + printf("hubspc_map: subdevice: %d vaddr: 0x%x phyaddr: 0x%x len: 0x%x\n", + subdevice, v_getaddr(vt), off, len); +#endif /* HUBSPC_DEBUG */ + + switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) { + case HUBSPC_REFCOUNTERS: + errcode = mem_refcnt_mmap(dev, vt, off, len, prot); + break; + + case HUBSPC_PROM: + errcode = cpuprom_map(dev, vt, off, len); + break; + default: + errcode = ENODEV; + } + +#ifdef HUBSPC_DEBUG + printf("hubspc_map finished: spctype: %d vaddr: 0x%x len: 0x%x\n", + (hubspc_subdevice_t)(ulong)device_info_get(dev), v_getaddr(vt), len); +#endif /* HUBSPC_DEBUG */ + + return errcode; +} + +/* ARGSUSED */ +int +hubspc_unmap(devfs_handle_t dev, vhandl_t *vt) +{ + int errcode = 0; + + switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) { + case HUBSPC_REFCOUNTERS: + errcode = mem_refcnt_unmap(dev, vt); + break; + + case HUBSPC_PROM: + errcode = cpuprom_unmap(dev, vt); + break; + + default: + errcode = ENODEV; + } + return errcode; + +} + +/* ARGSUSED */ +int +hubspc_ioctl(devfs_handle_t dev, + int cmd, + void *arg, + int mode, + cred_t *cred_p, + int *rvalp) +{ + int errcode = 0; + + switch ((hubspc_subdevice_t)(ulong)device_info_get(dev)) { + case HUBSPC_REFCOUNTERS: + errcode = mem_refcnt_ioctl(dev, cmd, arg, mode, cred_p, rvalp); + break; + + case HUBSPC_PROM: + break; + + default: + errcode = ENODEV; + } + return errcode; + +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/invent.c linux-2.4.0-test12-lia/arch/ia64/sn/io/invent.c --- linux-2.4.0-test12/arch/ia64/sn/io/invent.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/invent.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,198 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* + * Hardware Inventory + * + * See sys/sn/invent.h for an explanation of the hardware inventory contents. + * + */ +#include +#include +#include +#include +#include +#include + +void +inventinit(void) +{ +} + +/* + * For initializing/updating an inventory entry. + */ +void +replace_in_inventory( + inventory_t *pinv, int class, int type, + int controller, int unit, int state) +{ + pinv->inv_class = class; + pinv->inv_type = type; + pinv->inv_controller = controller; + pinv->inv_unit = unit; + pinv->inv_state = state; +} + +/* + * Inventory addition + * + * XXX NOTE: Currently must be called after dynamic memory allocator is + * initialized. + * + */ +void +add_to_inventory(int class, int type, int controller, int unit, int state) +{ + (void)device_inventory_add((devfs_handle_t)GRAPH_VERTEX_NONE, class, type, + controller, unit, state); +} + + +/* + * Inventory retrieval + * + * These two routines are intended to prevent the caller from having to know + * the internal structure of the inventory table. + * + */ +inventory_t * +get_next_inventory(invplace_t *place) +{ + inventory_t *pinv; + devfs_handle_t device = place->invplace_vhdl; + int rv; + + while ((pinv = device_inventory_get_next(device, place)) == NULL) { + /* + * We've exhausted inventory items on the last device. + * Advance to next device. + */ + rv = hwgraph_vertex_get_next(&device, &place->invplace_vplace); + if (rv != LABELCL_SUCCESS) + return(NULL); + place->invplace_vhdl = device; + place->invplace_inv = NULL; /* Start from beginning invent on this device */ + } + + return(pinv); +} + +/* ARGSUSED */ +int +get_sizeof_inventory(int abi) +{ + return sizeof(inventory_t); +} + +/* + * Hardware inventory scanner. + * + * Calls fun() for every entry in inventory list unless fun() returns something + * other than 0. + */ +int +scaninvent(int (*fun)(inventory_t *, void *), void *arg) +{ + inventory_t *ie; + invplace_t iplace = { NULL,NULL, NULL }; + int rc; + + ie = 0; + rc = 0; + while ( (ie = (inventory_t *)get_next_inventory(&iplace)) ) { + rc = (*fun)(ie, arg); + if (rc) + break; + } + return rc; +} + +/* + * Find a particular inventory object + * + * pinv can be a pointer to an inventory entry and the search will begin from + * there, or it can be 0 in which case the search starts at the beginning. + * A -1 for any of the other arguments is a wildcard (i.e. it always matches). + */ +inventory_t * +find_inventory(inventory_t *pinv, int class, int type, int controller, + int unit, int state) +{ + invplace_t iplace = { NULL,NULL, NULL }; + + while ((pinv = (inventory_t *)get_next_inventory(&iplace)) != NULL) { + if (class != -1 && pinv->inv_class != class) + continue; + if (type != -1 && pinv->inv_type != type) + continue; + + /* XXXX - perhaps the "state" entry should be ignored so an + * an existing entry can be updated. See vino_init() and + * ml/IP22.c:add_ioboard() for an example. + */ + if (state != -1 && pinv->inv_state != state) + continue; + if (controller != -1 + && pinv->inv_controller != controller) + continue; + if (unit != -1 && pinv->inv_unit != unit) + continue; + break; + } + + return(pinv); +} + + +/* +** Retrieve inventory data associated with a device. +*/ +inventory_t * +device_inventory_get_next( devfs_handle_t device, + invplace_t *invplace) +{ + inventory_t *pinv; + int rv; + + rv = hwgraph_inventory_get_next(device, invplace, &pinv); + if (rv == LABELCL_SUCCESS) + return(pinv); + else + return(NULL); +} + + +/* +** Associate canonical inventory information with a device (and +** add it to the general inventory). +*/ +void +device_inventory_add( devfs_handle_t device, + int class, + int type, + major_t controller, + minor_t unit, + int state) +{ + hwgraph_inventory_add(device, class, type, controller, unit, state); +} + +int +device_controller_num_get(devfs_handle_t device) +{ + return (hwgraph_controller_num_get(device)); +} + +void +device_controller_num_set(devfs_handle_t device, int contr_num) +{ + hwgraph_controller_num_set(device, contr_num); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/io.c linux-2.4.0-test12-lia/arch/ia64/sn/io/io.c --- linux-2.4.0-test12/arch/ia64/sn/io/io.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/io.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,1312 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern xtalk_provider_t hub_provider; + +#ifndef CONFIG_IA64_SGI_IO +/* Global variables */ +extern pdaindr_t pdaindr[MAXCPUS]; +#endif + +/* + * Perform any initializations needed to support hub-based I/O. + * Called once during startup. + */ +void +hubio_init(void) +{ +#if 0 + /* This isn't needed unless we port the entire sio driver ... */ + extern void early_brl1_port_init( void ); + early_brl1_port_init(); +#endif +} + +/* + * Implementation of hub iobus operations. + * + * Hub provides a crosstalk "iobus" on IP27 systems. These routines + * provide a platform-specific implementation of xtalk used by all xtalk + * cards on IP27 systems. + * + * Called from corresponding xtalk_* routines. + */ + + +/* PIO MANAGEMENT */ +/* For mapping system virtual address space to xtalk space on a specified widget */ + +/* + * Setup pio structures needed for a particular hub. + */ +static void +hub_pio_init(devfs_handle_t hubv) +{ + xwidgetnum_t widget; + hubinfo_t hubinfo; + nasid_t nasid; + int bigwin; + hub_piomap_t hub_piomap; + + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + + /* Initialize small window piomaps for this hub */ + for (widget=0; widget <= HUB_WIDGET_ID_MAX; widget++) { + hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget); + hub_piomap->hpio_xtalk_info.xp_target = widget; + hub_piomap->hpio_xtalk_info.xp_xtalk_addr = 0; + hub_piomap->hpio_xtalk_info.xp_mapsz = SWIN_SIZE; + hub_piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)NODE_SWIN_BASE(nasid, widget); + hub_piomap->hpio_hub = hubv; + hub_piomap->hpio_flags = HUB_PIOMAP_IS_VALID; + } + + /* Initialize big window piomaps for this hub */ + for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) { + hub_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin); + hub_piomap->hpio_xtalk_info.xp_mapsz = BWIN_SIZE; + hub_piomap->hpio_hub = hubv; + hub_piomap->hpio_holdcnt = 0; + hub_piomap->hpio_flags = HUB_PIOMAP_IS_BIGWINDOW; + IIO_ITTE_DISABLE(nasid, bigwin); + } +#ifdef BRINGUP + hub_set_piomode(nasid, HUB_PIO_CONVEYOR); +#else + /* Set all the xwidgets in fire-and-forget mode + * by default + */ + hub_set_piomode(nasid, HUB_PIO_FIRE_N_FORGET); +#endif /* BRINGUP */ + + sv_init(&hubinfo->h_bwwait, SV_FIFO, "bigwin"); + spinlock_init(&hubinfo->h_bwlock, "bigwin"); +} + +/* + * Create a caddr_t-to-xtalk_addr mapping. + * + * Use a small window if possible (that's the usual case), but + * manage big windows if needed. Big window mappings can be + * either FIXED or UNFIXED -- we keep at least 1 big window available + * for UNFIXED mappings. + * + * Returns an opaque pointer-sized type which can be passed to + * other hub_pio_* routines on success, or NULL if the request + * cannot be satisfied. + */ +/* ARGSUSED */ +hub_piomap_t +hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ + size_t byte_count, + size_t byte_count_max, /* maximum size of a mapping */ + unsigned flags) /* defined in sys/pio.h */ +{ + xwidget_info_t widget_info = xwidget_info_get(dev); + xwidgetnum_t widget = xwidget_info_id_get(widget_info); + devfs_handle_t hubv = xwidget_info_master_get(widget_info); + hubinfo_t hubinfo; + hub_piomap_t bw_piomap; + int bigwin, free_bw_index; + nasid_t nasid; + volatile hubreg_t junk; + int s; + + /* sanity check */ + if (byte_count_max > byte_count) + return(NULL); + + hubinfo_get(hubv, &hubinfo); + + /* If xtalk_addr range is mapped by a small window, we don't have + * to do much + */ + if (xtalk_addr + byte_count <= SWIN_SIZE) + return(hubinfo_swin_piomap_get(hubinfo, (int)widget)); + + /* We need to use a big window mapping. */ + + /* + * TBD: Allow requests that would consume multiple big windows -- + * split the request up and use multiple mapping entries. + * For now, reject requests that span big windows. + */ + if ((xtalk_addr % BWIN_SIZE) + byte_count > BWIN_SIZE) + return(NULL); + + + /* Round xtalk address down for big window alignement */ + xtalk_addr = xtalk_addr & ~(BWIN_SIZE-1); + + /* + * Check to see if an existing big window mapping will suffice. + */ +tryagain: + free_bw_index = -1; + s = mutex_spinlock(&hubinfo->h_bwlock); + for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) { + bw_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin); + + /* If mapping is not valid, skip it */ + if (!(bw_piomap->hpio_flags & HUB_PIOMAP_IS_VALID)) { + free_bw_index = bigwin; + continue; + } + + /* + * If mapping is UNFIXED, skip it. We don't allow sharing + * of UNFIXED mappings, because this would allow starvation. + */ + if (!(bw_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED)) + continue; + + if ( xtalk_addr == bw_piomap->hpio_xtalk_info.xp_xtalk_addr && + widget == bw_piomap->hpio_xtalk_info.xp_target) { + bw_piomap->hpio_holdcnt++; + mutex_spinunlock(&hubinfo->h_bwlock, s); + return(bw_piomap); + } + } + + /* + * None of the existing big window mappings will work for us -- + * we need to establish a new mapping. + */ + + /* Insure that we don't consume all big windows with FIXED mappings */ + if (flags & PIOMAP_FIXED) { + if (hubinfo->h_num_big_window_fixed < HUB_NUM_BIG_WINDOW-1) { + ASSERT(free_bw_index >= 0); + hubinfo->h_num_big_window_fixed++; + } else { + bw_piomap = NULL; + goto done; + } + } else /* PIOMAP_UNFIXED */ { + if (free_bw_index < 0) { + if (flags & PIOMAP_NOSLEEP) { + bw_piomap = NULL; + goto done; + } + + sv_wait(&hubinfo->h_bwwait, PZERO, &hubinfo->h_bwlock, s); + goto tryagain; + } + } + + + /* OK! Allocate big window free_bw_index for this mapping. */ + /* + * The code below does a PIO write to setup an ITTE entry. + * We need to prevent other CPUs from seeing our updated memory + * shadow of the ITTE (in the piomap) until the ITTE entry is + * actually set up; otherwise, another CPU might attempt a PIO + * prematurely. + * + * Also, the only way we can know that an entry has been received + * by the hub and can be used by future PIO reads/writes is by + * reading back the ITTE entry after writing it. + * + * For these two reasons, we PIO read back the ITTE entry after + * we write it. + */ + + nasid = hubinfo->h_nasid; + IIO_ITTE_PUT(nasid, free_bw_index, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr); + junk = HUB_L(IIO_ITTE_GET(nasid, free_bw_index)); + + bw_piomap = hubinfo_bwin_piomap_get(hubinfo, free_bw_index); + bw_piomap->hpio_xtalk_info.xp_dev = dev; + bw_piomap->hpio_xtalk_info.xp_target = widget; + bw_piomap->hpio_xtalk_info.xp_xtalk_addr = xtalk_addr; + bw_piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)NODE_BWIN_BASE(nasid, free_bw_index); + bw_piomap->hpio_holdcnt++; + bw_piomap->hpio_bigwin_num = free_bw_index; + + if (flags & PIOMAP_FIXED) + bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED; + else + bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID; + +done: + mutex_spinunlock(&hubinfo->h_bwlock, s); + return(bw_piomap); +} + +/* + * hub_piomap_free destroys a caddr_t-to-xtalk pio mapping and frees + * any associated mapping resources. + * + * If this * piomap was handled with a small window, or if it was handled + * in a big window that's still in use by someone else, then there's + * nothing to do. On the other hand, if this mapping was handled + * with a big window, AND if we were the final user of that mapping, + * then destroy the mapping. + */ +void +hub_piomap_free(hub_piomap_t hub_piomap) +{ + devfs_handle_t hubv; + hubinfo_t hubinfo; + nasid_t nasid; + int s; + + /* + * Small windows are permanently mapped to corresponding widgets, + * so there're no resources to free. + */ + if (!(hub_piomap->hpio_flags & HUB_PIOMAP_IS_BIGWINDOW)) + return; + + ASSERT(hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID); + ASSERT(hub_piomap->hpio_holdcnt > 0); + + hubv = hub_piomap->hpio_hub; + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + + s = mutex_spinlock(&hubinfo->h_bwlock); + + /* + * If this is the last hold on this mapping, free it. + */ + if (--hub_piomap->hpio_holdcnt == 0) { + IIO_ITTE_DISABLE(nasid, hub_piomap->hpio_bigwin_num ); + + if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED) { + hub_piomap->hpio_flags &= ~(HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED); + hubinfo->h_num_big_window_fixed--; + ASSERT(hubinfo->h_num_big_window_fixed >= 0); + } else + hub_piomap->hpio_flags &= ~HUB_PIOMAP_IS_VALID; + + (void)sv_signal(&hubinfo->h_bwwait); + } + + mutex_spinunlock(&hubinfo->h_bwlock, s); +} + +/* + * Establish a mapping to a given xtalk address range using the resources + * allocated earlier. + */ +caddr_t +hub_piomap_addr(hub_piomap_t hub_piomap, /* mapping resources */ + iopaddr_t xtalk_addr, /* map for this xtalk address */ + size_t byte_count) /* map this many bytes */ +{ + /* Verify that range can be mapped using the specified piomap */ + if (xtalk_addr < hub_piomap->hpio_xtalk_info.xp_xtalk_addr) + return(0); + + if (xtalk_addr + byte_count > + ( hub_piomap->hpio_xtalk_info.xp_xtalk_addr + + hub_piomap->hpio_xtalk_info.xp_mapsz)) + return(0); + + if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID) + return(hub_piomap->hpio_xtalk_info.xp_kvaddr + + (xtalk_addr % hub_piomap->hpio_xtalk_info.xp_mapsz)); + else + return(0); +} + + +/* + * Driver indicates that it's done with PIO's from an earlier piomap_addr. + */ +/* ARGSUSED */ +void +hub_piomap_done(hub_piomap_t hub_piomap) /* done with these mapping resources */ +{ + /* Nothing to do */ +} + + +/* + * For translations that require no mapping resources, supply a kernel virtual + * address that maps to the specified xtalk address range. + */ +/* ARGSUSED */ +caddr_t +hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* Crosstalk address */ + size_t byte_count, /* map this many bytes */ + unsigned flags) /* (currently unused) */ +{ + xwidget_info_t widget_info = xwidget_info_get(dev); + xwidgetnum_t widget = xwidget_info_id_get(widget_info); + devfs_handle_t hubv = xwidget_info_master_get(widget_info); + hub_piomap_t hub_piomap; + hubinfo_t hubinfo; + + hubinfo_get(hubv, &hubinfo); + + if (xtalk_addr + byte_count <= SWIN_SIZE) { + hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget); + return(hub_piomap_addr(hub_piomap, xtalk_addr, byte_count)); + } else + return(0); +} + + +/* DMA MANAGEMENT */ +/* Mapping from crosstalk space to system physical space */ + +/* + * There's not really very much to do here, since crosstalk maps + * directly to system physical space. It's quite possible that this + * DMA layer will be bypassed in performance kernels. + */ + + +/* ARGSUSED */ +static void +hub_dma_init(devfs_handle_t hubv) +{ +} + + +/* + * Allocate resources needed to set up DMA mappings up to a specified size + * on a specified adapter. + * + * We don't actually use the adapter ID for anything. It's just the adapter + * that the lower level driver plans to use for DMA. + */ +/* ARGSUSED */ +hub_dmamap_t +hub_dmamap_alloc( devfs_handle_t dev, /* set up mappings for this device */ + device_desc_t dev_desc, /* device descriptor */ + size_t byte_count_max, /* max size of a mapping */ + unsigned flags) /* defined in dma.h */ +{ + hub_dmamap_t dmamap; + xwidget_info_t widget_info = xwidget_info_get(dev); + xwidgetnum_t widget = xwidget_info_id_get(widget_info); + devfs_handle_t hubv = xwidget_info_master_get(widget_info); + + dmamap = kern_malloc(sizeof(struct hub_dmamap_s)); + dmamap->hdma_xtalk_info.xd_dev = dev; + dmamap->hdma_xtalk_info.xd_target = widget; + dmamap->hdma_hub = hubv; + dmamap->hdma_flags = HUB_DMAMAP_IS_VALID; + if (flags & XTALK_FIXED) + dmamap->hdma_flags |= HUB_DMAMAP_IS_FIXED; + + return(dmamap); +} + +/* + * Destroy a DMA mapping from crosstalk space to system address space. + * There is no actual mapping hardware to destroy, but we at least mark + * the dmamap INVALID and free the space that it took. + */ +void +hub_dmamap_free(hub_dmamap_t hub_dmamap) +{ + hub_dmamap->hdma_flags &= ~HUB_DMAMAP_IS_VALID; + kern_free(hub_dmamap); +} + +/* + * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc. + * Return an appropriate crosstalk address range that maps to the specified physical + * address range. + */ +/* ARGSUSED */ +extern iopaddr_t +hub_dmamap_addr( hub_dmamap_t dmamap, /* use these mapping resources */ + paddr_t paddr, /* map for this address */ + size_t byte_count) /* map this many bytes */ +{ + devfs_handle_t vhdl; + + ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID); + + if (dmamap->hdma_flags & HUB_DMAMAP_USED) { + /* If the map is FIXED, re-use is OK. */ + if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) { + vhdl = dmamap->hdma_xtalk_info.xd_dev; +#if defined(SUPPORT_PRINTING_V_FORMAT) + cmn_err(CE_WARN, "%v: hub_dmamap_addr re-uses dmamap.\n",vhdl); +#else + cmn_err(CE_WARN, "0x%p: hub_dmamap_addr re-uses dmamap.\n", &vhdl); +#endif + } + } else { + dmamap->hdma_flags |= HUB_DMAMAP_USED; + } + + /* There isn't actually any DMA mapping hardware on the hub. */ + return(paddr); +} + +/* + * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc. + * Return an appropriate crosstalk address list that maps to the specified physical + * address list. + */ +/* ARGSUSED */ +alenlist_t +hub_dmamap_list(hub_dmamap_t hub_dmamap, /* use these mapping resources */ + alenlist_t palenlist, /* map this area of memory */ + unsigned flags) +{ + devfs_handle_t vhdl; + + ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID); + + if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) { + /* If the map is FIXED, re-use is OK. */ + if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) { + vhdl = hub_dmamap->hdma_xtalk_info.xd_dev; +#if defined(SUPPORT_PRINTING_V_FORMAT) + cmn_err(CE_WARN,"%v: hub_dmamap_list re-uses dmamap\n",vhdl); +#else + cmn_err(CE_WARN,"0x%p: hub_dmamap_list re-uses dmamap\n", &vhdl); +#endif + } + } else { + hub_dmamap->hdma_flags |= HUB_DMAMAP_USED; + } + + /* There isn't actually any DMA mapping hardware on the hub. */ + return(palenlist); +} + +/* + * Driver indicates that it has completed whatever DMA it may have started + * after an earlier dmamap_addr or dmamap_list call. + */ +void +hub_dmamap_done(hub_dmamap_t hub_dmamap) /* done with these mapping resources */ +{ + devfs_handle_t vhdl; + + if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) { + hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED; + } else { + /* If the map is FIXED, re-done is OK. */ + if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) { + vhdl = hub_dmamap->hdma_xtalk_info.xd_dev; +#if defined(SUPPORT_PRINTING_V_FORMAT) + cmn_err(CE_WARN, "%v: hub_dmamap_done already done with dmamap\n",vhdl); +#else + cmn_err(CE_WARN, "0x%p: hub_dmamap_done already done with dmamap\n", &vhdl); +#endif + } + } +} + +/* + * Translate a single system physical address into a crosstalk address. + */ +/* ARGSUSED */ +iopaddr_t +hub_dmatrans_addr( devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + unsigned flags) /* defined in dma.h */ +{ + /* no translation needed */ + return(paddr); +} + +/* + * Translate a list of IP27 addresses and lengths into a list of crosstalk + * addresses and lengths. No actual hardware mapping takes place; the hub + * has no DMA mapping registers -- crosstalk addresses map directly. + */ +/* ARGSUSED */ +alenlist_t +hub_dmatrans_list( devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + alenlist_t palenlist, /* system address/length list */ + unsigned flags) /* defined in dma.h */ +{ + /* no translation needed */ + return(palenlist); +} + +/*ARGSUSED*/ +void +hub_dmamap_drain( hub_dmamap_t map) +{ + /* XXX- flush caches, if cache coherency WAR is needed */ +} + +/*ARGSUSED*/ +void +hub_dmaaddr_drain( devfs_handle_t vhdl, + paddr_t addr, + size_t bytes) +{ + /* XXX- flush caches, if cache coherency WAR is needed */ +} + +/*ARGSUSED*/ +void +hub_dmalist_drain( devfs_handle_t vhdl, + alenlist_t list) +{ + /* XXX- flush caches, if cache coherency WAR is needed */ +} + + + +/* INTERRUPT MANAGEMENT */ + +/* ARGSUSED */ +static void +hub_intr_init(devfs_handle_t hubv) +{ +} + +/* + * hub_device_desc_update + * Update the passed in device descriptor with the actual the + * target cpu number and interrupt priority level. + * NOTE : These might be the same as the ones passed in thru + * the descriptor. + */ +static void +hub_device_desc_update(device_desc_t dev_desc, + ilvl_t intr_swlevel, + cpuid_t cpu) +{ + char cpuname[40]; + + /* Store the interrupt priority level in the device descriptor */ + device_desc_intr_swlevel_set(dev_desc, intr_swlevel); + + /* Convert the cpuid to the vertex handle in the hwgraph and + * save it in the device descriptor. + */ + sprintf(cpuname,"/hw/cpunum/%ld",cpu); + device_desc_intr_target_set(dev_desc, + hwgraph_path_to_dev(cpuname)); +} + +int allocate_my_bit = INTRCONNECT_ANYBIT; + +/* + * Allocate resources required for an interrupt as specified in dev_desc. + * Returns a hub interrupt handle on success, or 0 on failure. + */ +hub_intr_t +hub_intr_alloc( devfs_handle_t dev, /* which crosstalk device */ + device_desc_t dev_desc, /* device descriptor */ + devfs_handle_t owner_dev) /* owner of this interrupt, if known */ +{ + cpuid_t cpu; /* cpu to receive interrupt */ + int cpupicked = 0; + int bit; /* interrupt vector */ + /*REFERENCED*/ + int intr_resflags; + hub_intr_t intr_hdl; + cnodeid_t nodeid; /* node to receive interrupt */ + /*REFERENCED*/ + nasid_t nasid; /* nasid to receive interrupt */ + struct xtalk_intr_s *xtalk_info; + iopaddr_t xtalk_addr; /* xtalk addr on hub to set intr */ + xwidget_info_t xwidget_info; /* standard crosstalk widget info handle */ + char *intr_name = NULL; + ilvl_t intr_swlevel; + extern int default_intr_pri; +#ifdef CONFIG_IA64_SGI_SN1 + extern void synergy_intr_alloc(int, int); +#endif + + /* + * If caller didn't explicily specify a device descriptor, see if there's + * a default descriptor associated with the device. + */ + if (!dev_desc) + dev_desc = device_desc_default_get(dev); + + if (dev_desc) { + intr_name = device_desc_intr_name_get(dev_desc); + intr_swlevel = device_desc_intr_swlevel_get(dev_desc); + if (dev_desc->flags & D_INTR_ISERR) { + intr_resflags = II_ERRORINT; + } else if (!(dev_desc->flags & D_INTR_NOTHREAD)) { + intr_resflags = II_THREADED; + } else { + /* Neither an error nor a thread. */ + intr_resflags = 0; + } + } else { + intr_swlevel = default_intr_pri; + intr_resflags = II_THREADED; + } + + /* XXX - Need to determine if the interrupt should be threaded. */ + + /* If the cpu has not been picked already then choose a candidate + * interrupt target and reserve the interrupt bit + */ +#if defined(NEW_INTERRUPTS) + if (!cpupicked) { + cpu = intr_heuristic(dev,dev_desc,allocate_my_bit, + intr_resflags,owner_dev, + intr_name,&bit); + } +#endif + + /* At this point we SHOULD have a valid cpu */ + if (cpu == CPU_NONE) { +#if defined(SUPPORT_PRINTING_V_FORMAT) + cmn_err(CE_WARN, + "%v hub_intr_alloc could not allocate interrupt\n", + owner_dev); +#else + cmn_err(CE_WARN, + "0x%p hub_intr_alloc could not allocate interrupt\n", + &owner_dev); +#endif + return(0); + + } + + /* If the cpu has been picked already (due to the bridge data + * corruption bug) then try to reserve an interrupt bit . + */ +#if defined(NEW_INTERRUPTS) + if (cpupicked) { + bit = intr_reserve_level(cpu, allocate_my_bit, + intr_resflags, + owner_dev, intr_name); + if (bit < 0) { +#if defined(SUPPORT_PRINTING_V_FORMAT) + cmn_err(CE_WARN, + "Could not reserve an interrupt bit for cpu " + " %d and dev %v\n", + cpu,owner_dev); +#else + cmn_err(CE_WARN, + "Could not reserve an interrupt bit for cpu " + " %d and dev 0x%x\n", + cpu, &owner_dev); +#endif + + return(0); + } + } +#endif /* NEW_INTERRUPTS */ + + nodeid = cpuid_to_cnodeid(cpu); + nasid = cpuid_to_nasid(cpu); + xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu))); + + /* + * Allocate an interrupt handle, and fill it in. There are two + * pieces to an interrupt handle: the piece needed by generic + * xtalk code which is used by crosstalk device drivers, and + * the piece needed by low-level IP27 hardware code. + */ + intr_hdl = kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid); + ASSERT_ALWAYS(intr_hdl); + + /* + * Fill in xtalk information for generic xtalk interfaces that + * operate on xtalk_intr_hdl's. + */ + xtalk_info = &intr_hdl->i_xtalk_info; + xtalk_info->xi_dev = dev; + xtalk_info->xi_vector = bit; + xtalk_info->xi_addr = xtalk_addr; + xtalk_info->xi_flags = (intr_resflags == II_THREADED) ? + 0 : XTALK_INTR_NOTHREAD; + + /* + * Regardless of which CPU we ultimately interrupt, a given crosstalk + * widget always handles interrupts (and PIO and DMA) through its + * designated "master" crosstalk provider. + */ + xwidget_info = xwidget_info_get(dev); + if (xwidget_info) + xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info); + + /* Fill in low level hub information for hub_* interrupt interface */ + intr_hdl->i_swlevel = intr_swlevel; + intr_hdl->i_cpuid = cpu; + intr_hdl->i_bit = bit; + intr_hdl->i_flags = HUB_INTR_IS_ALLOCED; + + /* Store the actual interrupt priority level & interrupt target + * cpu back in the device descriptor. + */ + hub_device_desc_update(dev_desc, intr_swlevel, cpu); +#ifdef CONFIG_IA64_SGI_SN1 + synergy_intr_alloc((int)bit, (int)cpu); +#endif + return(intr_hdl); +} + + +/* + * Free resources consumed by intr_alloc. + */ +void +hub_intr_free(hub_intr_t intr_hdl) +{ + cpuid_t cpu = intr_hdl->i_cpuid; + int bit = intr_hdl->i_bit; + xtalk_intr_t xtalk_info; + + if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) { + /* Setting the following fields in the xtalk interrupt info + * clears the interrupt target register in the xtalk user + */ + xtalk_info = &intr_hdl->i_xtalk_info; + xtalk_info->xi_dev = NODEV; + xtalk_info->xi_vector = 0; + xtalk_info->xi_addr = 0; + hub_intr_disconnect(intr_hdl); + } + + if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED) + kfree(intr_hdl); + +#if defined(NEW_INTERRUPTS) + intr_unreserve_level(cpu, bit); +#endif +} + + +/* + * Associate resources allocated with a previous hub_intr_alloc call with the + * described handler, arg, name, etc. + */ +/*ARGSUSED*/ +int +hub_intr_connect( hub_intr_t intr_hdl, /* xtalk intr resource handle */ + intr_func_t intr_func, /* xtalk intr handler */ + void *intr_arg, /* arg to intr handler */ + xtalk_intr_setfunc_t setfunc, /* func to set intr hw */ + void *setfunc_arg, /* arg to setfunc */ + void *thread) /* intr thread to use */ +{ + int rv; + cpuid_t cpu = intr_hdl->i_cpuid; + int bit = intr_hdl->i_bit; +#ifdef CONFIG_IA64_SGI_SN1 + extern int synergy_intr_connect(int, int); +#endif + + ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED); + +#if defined(NEW_INTERRUPTS) + rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, + intr_func, intr_arg, NULL); + if (rv < 0) + return(rv); + +#endif + intr_hdl->i_xtalk_info.xi_setfunc = setfunc; + intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg; + + if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl); + + intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED; +#ifdef CONFIG_IA64_SGI_SN1 + return(synergy_intr_connect((int)bit, (int)cpu)); +#endif +} + + +/* + * Disassociate handler with the specified interrupt. + */ +void +hub_intr_disconnect(hub_intr_t intr_hdl) +{ + /*REFERENCED*/ + int rv; + cpuid_t cpu = intr_hdl->i_cpuid; + int bit = intr_hdl->i_bit; + xtalk_intr_setfunc_t setfunc; + + setfunc = intr_hdl->i_xtalk_info.xi_setfunc; + + /* TBD: send disconnected interrupts somewhere harmless */ + if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl); + +#if defined(NEW_INTERRUPTS) + rv = intr_disconnect_level(cpu, bit); + ASSERT(rv == 0); +#endif + + intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED; +} + + +/* + * Return a hwgraph vertex that represents the CPU currently + * targeted by an interrupt. + */ +devfs_handle_t +hub_intr_cpu_get(hub_intr_t intr_hdl) +{ + cpuid_t cpuid = intr_hdl->i_cpuid; + ASSERT(cpuid != CPU_NONE); + + return(cpuid_to_vertex(cpuid)); +} + + + +/* CONFIGURATION MANAGEMENT */ + +/* + * Perform initializations that allow this hub to start crosstalk support. + */ +void +hub_provider_startup(devfs_handle_t hubv) +{ + hub_pio_init(hubv); + hub_dma_init(hubv); + hub_intr_init(hubv); +} + +/* + * Shutdown crosstalk support from a hub. + */ +void +hub_provider_shutdown(devfs_handle_t hub) +{ + /* TBD */ + xtalk_provider_unregister(hub); +} + +/* + * Check that an address is in teh real small window widget 0 space + * or else in the big window we're using to emulate small window 0 + * in the kernel. + */ +int +hub_check_is_widget0(void *addr) +{ + nasid_t nasid = NASID_GET(addr); + + if (((__psunsigned_t)addr >= RAW_NODE_SWIN_BASE(nasid, 0)) && + ((__psunsigned_t)addr < RAW_NODE_SWIN_BASE(nasid, 1))) + return 1; + return 0; +} + + +/* + * Check that two addresses use the same widget + */ +int +hub_check_window_equiv(void *addra, void *addrb) +{ + if (hub_check_is_widget0(addra) && hub_check_is_widget0(addrb)) + return 1; + + /* XXX - Assume this is really a small window address */ + if (WIDGETID_GET((__psunsigned_t)addra) == + WIDGETID_GET((__psunsigned_t)addrb)) + return 1; + + return 0; +} + + +/* + * Determine whether two PCI addresses actually refer to the same device. + * This only works if both addresses are in small windows. It's used to + * determine whether prom addresses refer to particular PCI devices. + */ +/* + * XXX - This won't work as written if we ever have more than two nodes + * on a crossbow. In that case, we'll need an array or partners. + */ +int +hub_check_pci_equiv(void *addra, void *addrb) +{ + nasid_t nasida, nasidb; + + /* + * This is for a permanent workaround that causes us to use a + * big window in place of small window 0. + */ + if (!hub_check_window_equiv(addra, addrb)) + return 0; + + /* If the offsets aren't the same, forget it. */ + if (SWIN_WIDGETADDR((__psunsigned_t)addra) != + (SWIN_WIDGETADDR((__psunsigned_t)addrb))) + return 0; + + /* Now, check the nasids */ + nasida = NASID_GET(addra); + nasidb = NASID_GET(addrb); + + ASSERT(NASID_TO_COMPACT_NODEID(nasida) != INVALID_NASID); + ASSERT(NASID_TO_COMPACT_NODEID(nasidb) != INVALID_NASID); + + /* + * Either the NASIDs must be the same or they must be crossbow + * partners (on the same crossbow). + */ + return (check_nasid_equiv(nasida, nasidb)); +} + +/* + * hub_setup_prb(nasid, prbnum, credits, conveyor) + * + * Put a PRB into fire-and-forget mode if conveyor isn't set. Otehrwise, + * put it into conveyor belt mode with the specified number of credits. + */ +void +hub_setup_prb(nasid_t nasid, int prbnum, int credits, int conveyor) +{ + iprb_t prb; + int prb_offset; +#ifdef IRIX + extern int force_fire_and_forget; + extern volatile int ignore_conveyor_override; + + if (force_fire_and_forget && !ignore_conveyor_override) + if (conveyor == HUB_PIO_CONVEYOR) + conveyor = HUB_PIO_FIRE_N_FORGET; +#endif + + /* + * Get the current register value. + */ + prb_offset = IIO_IOPRB(prbnum); + prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset); + + /* + * Clear out some fields. + */ + prb.iprb_ovflow = 1; + prb.iprb_bnakctr = 0; + prb.iprb_anakctr = 0; + + /* + * Enable or disable fire-and-forget mode. + */ + prb.iprb_ff = ((conveyor == HUB_PIO_CONVEYOR) ? 0 : 1); + + /* + * Set the appropriate number of PIO cresits for the widget. + */ + prb.iprb_xtalkctr = credits; + + /* + * Store the new value to the register. + */ + REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval); +} + +/* + * hub_set_piomode() + * + * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget" + * mode. To do this, we have to make absolutely sure that no PIOs + * are in progress so we turn off access to all widgets for the duration + * of the function. + * + * XXX - This code should really check what kind of widget we're talking + * to. Bridges can only handle three requests, but XG will do more. + * How many can crossbow handle to widget 0? We're assuming 1. + * + * XXX - There is a bug in the crossbow that link reset PIOs do not + * return write responses. The easiest solution to this problem is to + * leave widget 0 (xbow) in fire-and-forget mode at all times. This + * only affects pio's to xbow registers, which should be rare. + */ +void +hub_set_piomode(nasid_t nasid, int conveyor) +{ + hubreg_t ii_iowa; + int direct_connect; + hubii_wcr_t ii_wcr; + int prbnum; + int s, cons_lock = 0; + + ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID); + if (nasid == get_console_nasid()) { + PUTBUF_LOCK(s); + cons_lock = 1; + } + + ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS); + REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0); + + ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR); + direct_connect = ii_wcr.iwcr_dir_con; + + if (direct_connect) { + /* + * Assume a bridge here. + */ + hub_setup_prb(nasid, 0, 3, conveyor); + } else { + /* + * Assume a crossbow here. + */ + hub_setup_prb(nasid, 0, 1, conveyor); + } + + for (prbnum = HUB_WIDGET_ID_MIN; prbnum <= HUB_WIDGET_ID_MAX; prbnum++) { + /* + * XXX - Here's where we should take the widget type into + * when account assigning credits. + */ + /* Always set the PRBs in fire-and-forget mode */ + hub_setup_prb(nasid, prbnum, 3, conveyor); + } + +#ifdef IRIX + /* + * In direct connect mode, disable access to all widgets but 0. + * Later, the prom will do this for us. + */ + if (direct_connect) + ii_iowa = 1; +#endif + + REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa); + + if (cons_lock) + PUTBUF_UNLOCK(s); +} +/* Interface to allow special drivers to set hub specific + * device flags. + * Return 0 on failure , 1 on success + */ +int +hub_widget_flags_set(nasid_t nasid, + xwidgetnum_t widget_num, + hub_widget_flags_t flags) +{ + + ASSERT((flags & HUB_WIDGET_FLAGS) == flags); + + if (flags & HUB_PIO_CONVEYOR) { + hub_setup_prb(nasid,widget_num, + 3,HUB_PIO_CONVEYOR); /* set the PRB in conveyor + * belt mode with 3 credits + */ + } else if (flags & HUB_PIO_FIRE_N_FORGET) { + hub_setup_prb(nasid,widget_num, + 3,HUB_PIO_FIRE_N_FORGET); /* set the PRB in fire + * and forget mode + */ + } + + return 1; +} +/* Interface to allow special drivers to set hub specific + * device flags. + * Return 0 on failure , 1 on success + */ +int +hub_device_flags_set(devfs_handle_t widget_vhdl, + hub_widget_flags_t flags) +{ + xwidget_info_t widget_info = xwidget_info_get(widget_vhdl); + xwidgetnum_t widget_num = xwidget_info_id_get(widget_info); + devfs_handle_t hub_vhdl = xwidget_info_master_get(widget_info); + hubinfo_t hub_info = 0; + nasid_t nasid; + int s,rv; + + /* Use the nasid from the hub info hanging off the hub vertex + * and widget number from the widget vertex + */ + hubinfo_get(hub_vhdl, &hub_info); + /* Being over cautious by grabbing a lock */ + s = mutex_spinlock(&hub_info->h_bwlock); + nasid = hub_info->h_nasid; + rv = hub_widget_flags_set(nasid,widget_num,flags); + mutex_spinunlock(&hub_info->h_bwlock, s); + + return rv; +} + +#if ((defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && defined(BRINGUP)) +/* BRINGUP: This ought to be useful for IP27 too but, for now, + * make it SN1 only because `ii_ixtt_u_t' is not in IP27/hubio.h + * (or anywhere else :-). + */ +int +hubii_ixtt_set(devfs_handle_t widget_vhdl, ii_ixtt_u_t *ixtt) +{ + xwidget_info_t widget_info = xwidget_info_get(widget_vhdl); + devfs_handle_t hub_vhdl = xwidget_info_master_get(widget_info); + hubinfo_t hub_info = 0; + nasid_t nasid; + int s; + + /* Use the nasid from the hub info hanging off the hub vertex + * and widget number from the widget vertex + */ + hubinfo_get(hub_vhdl, &hub_info); + /* Being over cautious by grabbing a lock */ + s = mutex_spinlock(&hub_info->h_bwlock); + nasid = hub_info->h_nasid; + + REMOTE_HUB_S(nasid, IIO_IXTT, ixtt->ii_ixtt_regval); + + mutex_spinunlock(&hub_info->h_bwlock, s); + return 0; +} + +int +hubii_ixtt_get(devfs_handle_t widget_vhdl, ii_ixtt_u_t *ixtt) +{ + xwidget_info_t widget_info = xwidget_info_get(widget_vhdl); + devfs_handle_t hub_vhdl = xwidget_info_master_get(widget_info); + hubinfo_t hub_info = 0; + nasid_t nasid; + int s; + + /* Use the nasid from the hub info hanging off the hub vertex + * and widget number from the widget vertex + */ + hubinfo_get(hub_vhdl, &hub_info); + /* Being over cautious by grabbing a lock */ + s = mutex_spinlock(&hub_info->h_bwlock); + nasid = hub_info->h_nasid; + + ixtt->ii_ixtt_regval = REMOTE_HUB_L(nasid, IIO_IXTT); + + mutex_spinunlock(&hub_info->h_bwlock, s); + return 0; +} +#endif /* CONFIG_IA64_SGI_SN1 */ + +/* + * hub_device_inquiry + * Find out the xtalk widget related information stored in this + * hub's II. + */ +void +hub_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) +{ + devfs_handle_t xconn, hub_vhdl; + char widget_name[8]; + hubreg_t ii_iidem,ii_iiwa, ii_iowa; + hubinfo_t hubinfo; + nasid_t nasid; + int d; + + sprintf(widget_name, "%d", widget); + if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn) + != GRAPH_SUCCESS) + return; + + hub_vhdl = device_master_get(xconn); + if (hub_vhdl == GRAPH_VERTEX_NONE) + return; + + hubinfo_get(hub_vhdl, &hubinfo); + if (!hubinfo) + return; + + nasid = hubinfo->h_nasid; + + ii_iidem = REMOTE_HUB_L(nasid, IIO_IIDEM); + ii_iiwa = REMOTE_HUB_L(nasid, IIO_IIWA); + ii_iowa = REMOTE_HUB_L(nasid, IIO_IOWA); + +#if defined(SUPPORT_PRINTING_V_FORMAT) + cmn_err(CE_CONT, "Inquiry Info for %v\n", xconn); +#else + cmn_err(CE_CONT, "Inquiry Info for 0x%p\n", &xconn); +#endif + + cmn_err(CE_CONT,"\tDevices shutdown [ "); + + for (d = 0 ; d <= 7 ; d++) + if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d)))) + cmn_err(CE_CONT, " %d", d); + + cmn_err(CE_CONT,"]\n"); + + cmn_err(CE_CONT, + "\tInbound access ? %s\n", + ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no"); + + cmn_err(CE_CONT, + "\tOutbound access ? %s\n", + ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no"); + +} + +/* + * A pointer to this structure hangs off of every hub hwgraph vertex. + * The generic xtalk layer may indirect through it to get to this specific + * crosstalk bus provider. + */ +xtalk_provider_t hub_provider = { + (xtalk_piomap_alloc_f *) hub_piomap_alloc, + (xtalk_piomap_free_f *) hub_piomap_free, + (xtalk_piomap_addr_f *) hub_piomap_addr, + (xtalk_piomap_done_f *) hub_piomap_done, + (xtalk_piotrans_addr_f *) hub_piotrans_addr, + + (xtalk_dmamap_alloc_f *) hub_dmamap_alloc, + (xtalk_dmamap_free_f *) hub_dmamap_free, + (xtalk_dmamap_addr_f *) hub_dmamap_addr, + (xtalk_dmamap_list_f *) hub_dmamap_list, + (xtalk_dmamap_done_f *) hub_dmamap_done, + (xtalk_dmatrans_addr_f *) hub_dmatrans_addr, + (xtalk_dmatrans_list_f *) hub_dmatrans_list, + (xtalk_dmamap_drain_f *) hub_dmamap_drain, + (xtalk_dmaaddr_drain_f *) hub_dmaaddr_drain, + (xtalk_dmalist_drain_f *) hub_dmalist_drain, + + (xtalk_intr_alloc_f *) hub_intr_alloc, + (xtalk_intr_free_f *) hub_intr_free, + (xtalk_intr_connect_f *) hub_intr_connect, + (xtalk_intr_disconnect_f *) hub_intr_disconnect, + (xtalk_intr_cpu_get_f *) hub_intr_cpu_get, + + (xtalk_provider_startup_f *) hub_provider_startup, + (xtalk_provider_shutdown_f *) hub_provider_shutdown, +}; + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/ip37.c linux-2.4.0-test12-lia/arch/ia64/sn/io/ip37.c --- linux-2.4.0-test12/arch/ia64/sn/io/ip37.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/ip37.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,127 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* + * ip37.c + * Support for IP35/IP37 machines + */ + +#include +#include + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#include +#include +#include /* for bridge_t */ + + +xwidgetnum_t +hub_widget_id(nasid_t nasid) +{ + hubii_wcr_t ii_wcr; /* the control status register */ + + ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR); + + printk("hub_widget_id: Found Hub Widget ID 0x%x from Register 0x%p\n", ii_wcr.wcr_fields_s.wcr_widget_id, REMOTE_HUB_ADDR(nasid, IIO_WCR)); + + printk("hub_widget_id: Found Hub Widget 0x%lx wcr_reg_value 0x%lx\n", REMOTE_HUB_L(nasid,IIO_WCR), ii_wcr.wcr_reg_value); + + return ii_wcr.wcr_fields_s.wcr_widget_id; +} + +/* + * get_nasid() returns the physical node id number of the caller. + */ +nasid_t +get_nasid(void) +{ + return (nasid_t)((LOCAL_HUB_L(LB_REV_ID) & LRI_NODEID_MASK) >> LRI_NODEID_SHFT); +} + +int +get_slice(void) +{ + return LOCAL_HUB_L(PI_CPU_NUM); +} + +int +is_fine_dirmode(void) +{ + return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK) + >> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL); + +} + +hubreg_t +get_hub_chiprev(nasid_t nasid) +{ + + printk("get_hub_chiprev: Hub Chip Rev 0x%lx\n", + (REMOTE_HUB_L(nasid, LB_REV_ID) & LRI_REV_MASK) >> LRI_REV_SHFT); + return ((REMOTE_HUB_L(nasid, LB_REV_ID) & LRI_REV_MASK) + >> LRI_REV_SHFT); +} + +int +verify_snchip_rev(void) +{ + int hub_chip_rev; + int i; + static int min_hub_rev = 0; + nasid_t nasid; + static int first_time = 1; + extern int maxnodes; + + + if (first_time) { + for (i = 0; i < maxnodes; i++) { + nasid = COMPACT_TO_NASID_NODEID(i); + hub_chip_rev = get_hub_chiprev(nasid); + + if ((hub_chip_rev < min_hub_rev) || (i == 0)) + min_hub_rev = hub_chip_rev; + } + + + first_time = 0; + } + + return min_hub_rev; + +} + +#ifdef SN1_USE_POISON_BITS +int +hub_bte_poison_ok(void) +{ + /* + * For now, assume poisoning is ok. If it turns out there are chip + * bugs that prevent its use in early revs, there is some neat code + * to steal from the IP27 equivalent of this code. + */ + +#ifdef BRINGUP /* temp disable BTE poisoning - might be sw bugs in this area */ + return 0; +#else + return 1; +#endif +} +#endif /* SN1_USE_POISON_BITS */ + + +void +ni_reset_port(void) +{ + LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK); + LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); +} + +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ diff -urN linux-2.4.0-test12/arch/ia64/sn/io/klconflib.c linux-2.4.0-test12-lia/arch/ia64/sn/io/klconflib.c --- linux-2.4.0-test12/arch/ia64/sn/io/klconflib.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/klconflib.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,1334 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define printf printk +int hasmetarouter; + +#define LDEBUG 0 +#define NIC_UNKNOWN ((nic_t) -1) + +#undef DEBUG_KLGRAPH +#ifdef DEBUG_KLGRAPH +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG_KLGRAPH */ + +static void sort_nic_names(lboard_t *) ; + +lboard_t * +find_lboard(lboard_t *start, unsigned char brd_type) +{ + /* Search all boards stored on this node. */ + while (start) { + if (start->brd_type == brd_type) + return start; + start = KLCF_NEXT(start); + } + + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +lboard_t * +find_lboard_class(lboard_t *start, unsigned char brd_type) +{ + /* Search all boards stored on this node. */ + while (start) { + if (KLCLASS(start->brd_type) == KLCLASS(brd_type)) + return start; + start = KLCF_NEXT(start); + } + + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +klinfo_t * +find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type) +{ + int index, j; + + if (kli == (klinfo_t *)NULL) { + index = 0; + } else { + for (j = 0; j < KLCF_NUM_COMPS(brd); j++) { + if (kli == KLCF_COMP(brd, j)) + break; + } + index = j; + if (index == KLCF_NUM_COMPS(brd)) { + printf("find_component: Bad pointer: 0x%p\n", kli); + return (klinfo_t *)NULL; + } + index++; /* next component */ + } + + for (; index < KLCF_NUM_COMPS(brd); index++) { + kli = KLCF_COMP(brd, index); + DBG("find_component: brd %p kli %p request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli)); + if (KLCF_COMP_TYPE(kli) == struct_type) + return kli; + } + + /* Didn't find it. */ + return (klinfo_t *)NULL; +} + +klinfo_t * +find_first_component(lboard_t *brd, unsigned char struct_type) +{ + return find_component(brd, (klinfo_t *)NULL, struct_type); +} + +lboard_t * +find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot) +{ + /* Search all boards stored on this node. */ + while (start) { + if (MODULE_MATCH(start->brd_module, mod) && + (start->brd_slot == slot)) + return start; + start = KLCF_NEXT(start); + } + + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +lboard_t * +find_lboard_module(lboard_t *start, moduleid_t mod) +{ + /* Search all boards stored on this node. */ + while (start) { + if (MODULE_MATCH(start->brd_module, mod)) + return start; + start = KLCF_NEXT(start); + } + + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +lboard_t * +find_lboard_module_class(lboard_t *start, moduleid_t mod, + unsigned char brd_type) +{ + while (start) { + + DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type); + + if (MODULE_MATCH(start->brd_module, mod) && + (KLCLASS(start->brd_type) == KLCLASS(brd_type))) + return start; + start = KLCF_NEXT(start); + } + + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +#ifndef CONFIG_IA64_SGI_IO +#define tolower(c) (isupper(c) ? (c) - 'A' + 'a' : (c)) +#define toupper(c) (islower(c) ? (c) - 'a' + 'A' : (c)) +#endif + + +/* + * Convert a NIC name to a name for use in the hardware graph. + */ +void +nic_name_convert(char *old_name, char *new_name) +{ + int i; + char c; + char *compare_ptr; + + if ((old_name[0] == '\0') || (old_name[1] == '\0')) { + strcpy(new_name, EDGE_LBL_XWIDGET); + } else { + for (i = 0; i < strlen(old_name); i++) { + c = old_name[i]; + + if (isalpha(c)) + new_name[i] = tolower(c); + else if (isdigit(c)) + new_name[i] = c; + else + new_name[i] = '_'; + } + new_name[i] = '\0'; + } + + /* XXX - + * Since a bunch of boards made it out with weird names like + * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and + * replace it with "baseio" to avoid confusion in the field. + * We also have to make sure we don't report media_io instead of + * baseio. + */ + + /* Skip underscores at the beginning of the name */ + for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++) + ; + + /* + * Check for some names we need to replace. Early boards + * had junk following the name so check only the first + * characters. + */ + if (!strncmp(new_name, "io6", 3) || + !strncmp(new_name, "mio", 3) || + !strncmp(new_name, "media_io", 8)) + strcpy(new_name, "baseio"); +#if !defined(CONFIG_SGI_IP35) && !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC) + else if (!strncmp(new_name, "ip29", 4)) + strcpy(new_name,SN00_MOTHERBOARD); +#endif + else if (!strncmp(new_name, "divo", 4)) + strcpy(new_name, "divo") ; + +} + +/* Check if the given board corresponds to the global + * master io6 + */ +int +is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot) +{ + lboard_t *board; + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +/* BRINGUP: If this works then look for callers of is_master_baseio() + * (e.g. iograph.c) and let them pass in a slot if they want + */ + board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module); +#else + board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), + module, slot); +#endif + +#ifndef _STANDALONE + { + cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); + + if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC + board = find_lboard_module((lboard_t *) + KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), + module); +#else + board = find_lboard_modslot((lboard_t *) + KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), + module, slot); +#endif + } +#endif + if (!board) + return(0); + return(board->brd_flags & GLOBAL_MASTER_IO6); +} +/* + * Find the lboard structure and get the board name. + * If we can't find the structure or it's too low a revision, + * use default name. + */ +lboard_t * +get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name) +{ + lboard_t *brd; + + brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), + mod, slot); + +#ifndef _STANDALONE + { + cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid); + + if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID)) + brd = find_lboard_modslot((lboard_t *) + KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer), + mod, slot); + } +#endif + + if (!brd || (brd->brd_sversion < 2)) { + strcpy(name, EDGE_LBL_XWIDGET); + } else { + nic_name_convert(brd->brd_name, name); + } + + /* + * PV # 540860 + * If the name is not 'baseio' or SN00 MOTHERBOARD + * get the lowest of all the names in the nic string. + * This is needed for boards like divo, which can have + * a bunch of daughter cards, but would like to be called + * divo. We could do this for baseio and SN00 MOTHERBOARD + * but it has some special case names that we would not + * like to disturb at this point. + */ + + /* gfx boards don't need any of this name scrambling */ + if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) { + return(brd); + } + + if (!(!strcmp(name, "baseio") )) { + if (brd) { + sort_nic_names(brd) ; + /* Convert to small case, '-' to '_' etc */ + nic_name_convert(brd->brd_name, name) ; + } + } + + return(brd); +} + +int +get_cpu_slice(cpuid_t cpu) +{ + klcpu_t *acpu; + if ((acpu = get_cpuinfo(cpu)) == NULL) + return -1; + return acpu->cpu_info.physid; +} + + +/* + * get_actual_nasid + * + * Completely disabled brds have their klconfig on + * some other nasid as they have no memory. But their + * actual nasid is hidden in the klconfig. Use this + * routine to get it. Works for normal boards too. + */ +nasid_t +get_actual_nasid(lboard_t *brd) +{ + klhub_t *hub ; + + if (!brd) + return INVALID_NASID ; + + /* find out if we are a completely disabled brd. */ + + hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); + if (!hub) + return INVALID_NASID ; + if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */ + return hub->hub_info.physid ; + else + return brd->brd_nasid ; +} + +int +xbow_port_io_enabled(nasid_t nasid, int link) +{ + lboard_t *brd; + klxbow_t *xbow_p; + + /* + * look for boards that might contain an xbow or xbridge + */ +#if SN0 + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8); +#else + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_PBRICK_XBOW); +#endif + if (brd == NULL) return 0; + + if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) + == NULL) + return 0; + + if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link)) + return 0; + + printf("xbow_port_io_enabled: brd 0x%p xbow_p 0x%p \n", brd, xbow_p); + + return 1; +} + +void +board_to_path(lboard_t *brd, char *path) +{ + moduleid_t modnum; + char *board_name; +#if !defined(CONFIG_SGI_IP35) && !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC) + slotid_t slot; + char slot_name[SLOTNUM_MAXLENGTH]; +#endif + + ASSERT(brd); + + switch (KLCLASS(brd->brd_type)) { + + case KLCLASS_NODE: + board_name = EDGE_LBL_NODE; + break; + case KLCLASS_ROUTER: + if (brd->brd_type == KLTYPE_META_ROUTER) { + board_name = EDGE_LBL_META_ROUTER; + hasmetarouter++; + } else + board_name = EDGE_LBL_ROUTER; + break; + case KLCLASS_MIDPLANE: + board_name = EDGE_LBL_MIDPLANE; + break; + case KLCLASS_IO: + board_name = EDGE_LBL_IO; + break; + case KLCLASS_IOBRICK: + if (brd->brd_type == KLTYPE_PBRICK) + board_name = EDGE_LBL_PBRICK; + else if (brd->brd_type == KLTYPE_IBRICK) + board_name = EDGE_LBL_IBRICK; + else if (brd->brd_type == KLTYPE_XBRICK) + board_name = EDGE_LBL_XBRICK; + else + board_name = EDGE_LBL_IOBRICK; + break; + default: + board_name = EDGE_LBL_UNKNOWN; + } + + modnum = brd->brd_module; + +#if defined(SN0) + slot = brd->brd_slot; + get_slotname(slot, slot_name); + + ASSERT(modnum >= 0); + + sprintf(path, "%H/" EDGE_LBL_SLOT "/%s/%s", + modnum, slot_name, board_name); +#else + ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); +#ifdef BRINGUP /* fix IP35 hwgraph */ + sprintf(path, EDGE_LBL_MODULE "/%x/%s", modnum, board_name); +#else + sprintf(path, "%H/%s", modnum, board_name); +#endif +#endif +} + +/* + * Get the module number for a NASID. + */ +moduleid_t +get_module_id(nasid_t nasid) +{ + lboard_t *brd; + + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); + + if (!brd) + return INVALID_MODULE; + else + return brd->brd_module; +} + + +#ifndef CONFIG_IA64_SGI_IO +#if 1 +/* + * find_gfxpipe(#) + * + * XXXmacko + * This is only used by graphics drivers, and should be moved + * over to gfx/kern/graphics/SN0 as soon as it's convenient. + */ +static klgfx_t *graphics_pipe_list = NULL; +static devfs_handle_t hwgraph_all_gfxids = GRAPH_VERTEX_NONE; + +void +setup_gfxpipe_link(devfs_handle_t vhdl,int pipenum) +{ + char idbuf[8]; + extern graph_hdl_t hwgraph; + + graph_info_add_LBL(hwgraph, vhdl, INFO_LBL_GFXID, INFO_DESC_EXPORT, + (arbitrary_info_t)pipenum); + if (hwgraph_all_gfxids == GRAPH_VERTEX_NONE) + hwgraph_path_add(hwgraph_root, EDGE_LBL_GFX, &hwgraph_all_gfxids); + sprintf(idbuf, "%d", pipenum); + hwgraph_edge_add(hwgraph_all_gfxids, vhdl, idbuf); + +} +#endif + +/* + * find the pipenum'th logical graphics pipe (KLCLASS_GFX) + */ +lboard_t * +find_gfxpipe(int pipenum) +{ + gda_t *gdap; + cnodeid_t cnode; + nasid_t nasid; + lboard_t *lb; + klgfx_t *kg,**pkg; + int i; + + gdap = (gda_t *)GDA_ADDR(get_nasid()); + if (gdap->g_magic != GDA_MAGIC) + return NULL; + + if (!graphics_pipe_list) { + /* for all nodes */ + for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) { + nasid = gdap->g_nasidtable[cnode]; + if (nasid == INVALID_NASID) + continue; + lb = KL_CONFIG_INFO(nasid) ; + while (lb = find_lboard_class(lb, KLCLASS_GFX)) { + moduleid_t kgm, pkgm; + int kgs, pkgs; + +#if defined(DEBUG) && (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1 || defined(CONFIG_IA64_GENERIC))) && defined(BRINGUP) + printf("find_gfxpipe(): PIPE: %s mod %M slot %d\n",lb?lb->brd_name:"!LBRD", + lb->brd_module,lb->brd_slot); +#endif + /* insert lb into list */ + if (!(kg = (klgfx_t*)find_first_component(lb,KLSTRUCT_GFX))) { + lb = KLCF_NEXT(lb); + continue; + } + /* set moduleslot now that we have brd_module set */ + kg->moduleslot = (lb->brd_module << 8) | SLOTNUM_GETSLOT(lb->brd_slot); + /* make sure board has device flag set */ + kg->gfx_info.flags |= KLINFO_DEVICE; + if (kg->cookie < KLGFX_COOKIE) { + kg->gfx_next_pipe = NULL; + kg->cookie = KLGFX_COOKIE; + } + + kgm = kg->moduleslot>>8; + kgs = kg->moduleslot&0xff; + pkg = &graphics_pipe_list; + while (*pkg) { + pkgm = (*pkg)->moduleslot>>8; + pkgs = (*pkg)->moduleslot&0xff; + + if (!(MODULE_CMP(kgm, pkgm) > 0 || + (MODULE_CMP(kgm, pkgm) == 0 && + kgs > pkgs))) + break; + + pkg = &(*pkg)->gfx_next_pipe; + } + kg->gfx_next_pipe = *pkg; + *pkg = kg; + lb = KLCF_NEXT(lb); + } + } +#ifdef FIND_GFXPIPE_DEBUG + i = 0; + kg = graphics_pipe_list; + while (kg) { + lboard_t *lb; +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + lb = find_lboard_class(KL_CONFIG_INFO(kg->gfx_info.nasid), KLCLASS_GFX); +#else +#error Need to figure out how to find graphics boards ... +#endif +#if defined(SUPPORT_PRINTING_M_FORMAT) + printf("find_gfxpipe(): %s pipe %d mod %M slot %d\n",lb?lb->brd_name:"!LBRD",i, + (kg->moduleslot>>8),(kg->moduleslot&0xff)); +#else + printf("find_gfxpipe(): %s pipe %d mod 0x%x slot %d\n",lb?lb->brd_name:"!LBRD",i, + (kg->moduleslot>>8),(kg->moduleslot&0xff)); +#endif + kg = kg->gfx_next_pipe; + i++; + } +#endif + } + + i = 0; + kg = graphics_pipe_list; + while (kg && (i < pipenum)) { + kg = kg->gfx_next_pipe; + i++; + } + + if (!kg) return NULL; + +#if defined(SN0) + return find_lboard_modslot(KL_CONFIG_INFO(kg->gfx_info.nasid), + (kg->moduleslot>>8), + SLOTNUM_XTALK_CLASS|(kg->moduleslot&0xff)); +#elif defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + return find_lboard_class(KL_CONFIG_INFO(kg->gfx_info.nasid), KLCLASS_GFX); +#else +#error Need to figure out how to find graphics boards ... +#endif +} +#endif + + +#define MHZ 1000000 + +#ifndef CONFIG_IA64_SGI_IO +uint +cpu_cycles_adjust(uint orig_cycles) +{ + klcpu_t *acpu; + uint speed; + + acpu = nasid_slice_to_cpuinfo(get_nasid(), get_slice()); + + if (acpu == NULL) return orig_cycles; + + /* + * cpu cycles seem to be half of the real value, hack and mult by 2 + * for now. + */ + speed = (orig_cycles * 2) / MHZ; + + /* + * if the cpu thinks its running at some random speed nowhere close + * the programmed speed, do nothing. + */ + if ((speed < (acpu->cpu_speed - 2)) || (speed > (acpu->cpu_speed + 2))) + return orig_cycles; + return (acpu->cpu_speed * MHZ/2); +} +#endif /* CONFIG_IA64_SGI_IO */ + +/* Get the canonical hardware graph name for the given pci component + * on the given io board. + */ +void +device_component_canonical_name_get(lboard_t *brd, + klinfo_t *component, + char *name) +{ + moduleid_t modnum; + slotid_t slot; + char board_name[20]; +#ifdef SN0 + char slot_name[SLOTNUM_MAXLENGTH]; +#endif + + ASSERT(brd); + + /* Get the module number of this board */ + modnum = brd->brd_module; + + /* Convert the [ CLASS | TYPE ] kind of slotid + * into a string + */ + slot = brd->brd_slot; +#ifdef SN0 + get_slotname(slot, slot_name); + + ASSERT(modnum >= 0); +#else + ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); +#endif + + /* Get the io board name */ + if (!brd || (brd->brd_sversion < 2)) { + strcpy(name, EDGE_LBL_XWIDGET); + } else { + nic_name_convert(brd->brd_name, board_name); + } + + /* Give out the canonical name of the pci device*/ +#ifdef SN0 + sprintf(name, + "/hw/"EDGE_LBL_MODULE "/%M/"EDGE_LBL_SLOT"/%s/%s/" + EDGE_LBL_PCI"/%d", + modnum, slot_name, board_name,KLCF_BRIDGE_W_ID(component)); +#elif defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + sprintf(name, + "/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/" + EDGE_LBL_PCI"/%d", + modnum, board_name,KLCF_BRIDGE_W_ID(component)); +#endif + +} + +/* + * Get the serial number of the main component of a board + * Returns 0 if a valid serial number is found + * 1 otherwise. + * Assumptions: Nic manufacturing string has the following format + * *Serial:;* + */ +static int +component_serial_number_get(lboard_t *board, + klconf_off_t mfg_nic_offset, + char *serial_number, + char *key_pattern) +{ + + char *mfg_nic_string; + char *serial_string,*str; + int i; + char *serial_pattern = "Serial:"; + + /* We have an error on a null mfg nic offset */ + if (!mfg_nic_offset) + return(1); + /* Get the hub's manufacturing nic information + * which is in the form of a pre-formatted string + */ + mfg_nic_string = + (char *)NODE_OFFSET_TO_K0(NASID_GET(board), + mfg_nic_offset); + /* There is no manufacturing nic info */ + if (!mfg_nic_string) + return(1); + + str = mfg_nic_string; + /* Look for the key pattern first (if it is specified) + * and then print the serial number corresponding to that. + */ + if (strcmp(key_pattern,"") && + !(str = strstr(mfg_nic_string,key_pattern))) + return(1); + + /* There is no serial number info in the manufacturing + * nic info + */ + if (!(serial_string = strstr(str,serial_pattern))) + return(1); + + serial_string = serial_string + strlen(serial_pattern); + /* Copy the serial number information from the klconfig */ + i = 0; + while (serial_string[i] != ';') { + serial_number[i] = serial_string[i]; + i++; + } + serial_number[i] = 0; + + return(0); +} +/* + * Get the serial number of a board + * Returns 0 if a valid serial number is found + * 1 otherwise. + */ + +int +board_serial_number_get(lboard_t *board,char *serial_number) +{ + ASSERT(board && serial_number); + if (!board || !serial_number) + return(1); + + strcpy(serial_number,""); + switch(KLCLASS(board->brd_type)) { + case KLCLASS_CPU: { /* Node board */ + klhub_t *hub; + + /* Get the hub component information */ + hub = (klhub_t *)find_first_component(board, + KLSTRUCT_HUB); + /* If we don't have a hub component on an IP27 + * then we have a weird klconfig. + */ + if (!hub) + return(1); + /* Get the serial number information from + * the hub's manufacturing nic info + */ + if (component_serial_number_get(board, + hub->hub_mfg_nic, + serial_number, +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + "IP35")) +#else + "IP27")) + /* Try with IP31 key if IP27 key fails */ + if (component_serial_number_get(board, + hub->hub_mfg_nic, + serial_number, + "IP31")) +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + return(1); + break; + } + case KLCLASS_IO: { /* IO board */ + if (KLTYPE(board->brd_type) == KLTYPE_TPU) { + /* Special case for TPU boards */ + kltpu_t *tpu; + + /* Get the tpu component information */ + tpu = (kltpu_t *)find_first_component(board, + KLSTRUCT_TPU); + /* If we don't have a tpu component on a tpu board + * then we have a weird klconfig. + */ + if (!tpu) + return(1); + /* Get the serial number information from + * the tpu's manufacturing nic info + */ + if (component_serial_number_get(board, + tpu->tpu_mfg_nic, + serial_number, + "")) + return(1); + break; + } else if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) || + (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) { + /* Special case for GSN boards */ + klgsn_t *gsn; + + /* Get the gsn component information */ + gsn = (klgsn_t *)find_first_component(board, + ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ? + KLSTRUCT_GSN_A : KLSTRUCT_GSN_B)); + /* If we don't have a gsn component on a gsn board + * then we have a weird klconfig. + */ + if (!gsn) + return(1); + /* Get the serial number information from + * the gsn's manufacturing nic info + */ + if (component_serial_number_get(board, + gsn->gsn_mfg_nic, + serial_number, + "")) + return(1); + break; + } else { + klbri_t *bridge; + + /* Get the bridge component information */ + bridge = (klbri_t *)find_first_component(board, + KLSTRUCT_BRI); + /* If we don't have a bridge component on an IO board + * then we have a weird klconfig. + */ + if (!bridge) + return(1); + /* Get the serial number information from + * the bridge's manufacturing nic info + */ + if (component_serial_number_get(board, + bridge->bri_mfg_nic, + serial_number, + "")) + return(1); + break; + } + } + case KLCLASS_ROUTER: { /* Router board */ + klrou_t *router; + + /* Get the router component information */ + router = (klrou_t *)find_first_component(board, + KLSTRUCT_ROU); + /* If we don't have a router component on a router board + * then we have a weird klconfig. + */ + if (!router) + return(1); + /* Get the serial number information from + * the router's manufacturing nic info + */ + if (component_serial_number_get(board, + router->rou_mfg_nic, + serial_number, + "")) + return(1); + break; + } + case KLCLASS_GFX: { /* Gfx board */ + klgfx_t *graphics; + + /* Get the graphics component information */ + graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX); + /* If we don't have a gfx component on a gfx board + * then we have a weird klconfig. + */ + if (!graphics) + return(1); + /* Get the serial number information from + * the graphics's manufacturing nic info + */ + if (component_serial_number_get(board, + graphics->gfx_mfg_nic, + serial_number, + "")) + return(1); + break; + } + default: + strcpy(serial_number,""); + break; + } + return(0); +} + +#include "asm/sn/sn_private.h" +#ifndef CONFIG_IA64_SGI_IO +/* + * Given a physical address get the name of memory dimm bank + * in a hwgraph name format. + */ +void +membank_pathname_get(paddr_t paddr,char *name) +{ + cnodeid_t cnode; + char slotname[SLOTNUM_MAXLENGTH]; + + cnode = paddr_cnode(paddr); + /* Make sure that we have a valid name buffer */ + if (!name) + return; + + name[0] = 0; + /* Make sure that the cnode is valid */ + if ((cnode == CNODEID_NONE) || (cnode > numnodes)) + return; + /* Given a slotid(class:type) get the slotname */ +#if defined (SN0) + get_slotname(NODE_SLOTID(cnode),slotname); + sprintf(name, + "/hw/"EDGE_LBL_MODULE"/%M/"EDGE_LBL_SLOT"/%s/"EDGE_LBL_NODE + "/"EDGE_LBL_MEMORY"/dimm_bank/%d", + NODE_MODULEID(cnode),slotname,paddr_dimm(paddr)); +#elif defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + sprintf(name, + "/dev/hw/"EDGE_LBL_MODULE"/%M/"EDGE_LBL_NODE + "/"EDGE_LBL_MEMORY"/dimm_bank/%d", + NODE_MODULEID(cnode),paddr_dimm(paddr)); +#endif +} + + + +int +membank_check_mixed_hidensity(nasid_t nasid) +{ + lboard_t *brd; + klmembnk_t *mem; + int min_size = 1024, max_size = 0; + int bank, mem_size; + + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); + ASSERT(brd); + + mem = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK); + ASSERT(mem); + + + for (mem_size = 0, bank = 0; bank < MD_MEM_BANKS; bank++) { + mem_size = KLCONFIG_MEMBNK_SIZE(mem, bank); + if (mem_size < min_size) + min_size = mem_size; + if (mem_size > max_size) + max_size = mem_size; + } + + if ((max_size == 512) && (max_size != min_size)) + return 1; + + return 0; +} + + +int +mem_mixed_hidensity_banks(void) +{ + cnodeid_t cnode; + nasid_t nasid; + + for (cnode = 0; cnode < maxnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + if (nasid == INVALID_NASID) + continue; + if (membank_check_mixed_hidensity(nasid)) + return 1; + } + return 0; + +} +#endif /* CONFIG_IA64_SGI_IO */ + +xwidgetnum_t +nodevertex_widgetnum_get(devfs_handle_t node_vtx) +{ + hubinfo_t hubinfo_p; + + hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, + (arbitrary_info_t *) &hubinfo_p); + return(hubinfo_p->h_widgetid); +} + +devfs_handle_t +nodevertex_xbow_peer_get(devfs_handle_t node_vtx) +{ + hubinfo_t hubinfo_p; + nasid_t xbow_peer_nasid; + cnodeid_t xbow_peer; + + hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, + (arbitrary_info_t *) &hubinfo_p); + xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer; + if(xbow_peer_nasid == INVALID_NASID) + return ( (devfs_handle_t)-1); + xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid); + return(NODEPDA(xbow_peer)->node_vertex); +} + +/* NIC Sorting Support */ + +#define MAX_NICS_PER_STRING 32 +#define MAX_NIC_NAME_LEN 32 + +static char * +get_nic_string(lboard_t *lb) +{ + int i; + klinfo_t *k = NULL ; + klconf_off_t mfg_off = 0 ; + char *mfg_nic = NULL ; + + for (i = 0; i < KLCF_NUM_COMPS(lb); i++) { + k = KLCF_COMP(lb, i) ; + switch(k->struct_type) { + case KLSTRUCT_BRI: + mfg_off = ((klbri_t *)k)->bri_mfg_nic ; + break ; + + case KLSTRUCT_HUB: + mfg_off = ((klhub_t *)k)->hub_mfg_nic ; + break ; + + case KLSTRUCT_ROU: + mfg_off = ((klrou_t *)k)->rou_mfg_nic ; + break ; + + case KLSTRUCT_GFX: + mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ; + break ; + + case KLSTRUCT_TPU: + mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ; + break ; + + case KLSTRUCT_GSN_A: + case KLSTRUCT_GSN_B: + mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ; + break ; + + case KLSTRUCT_XTHD: + mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ; + break; + + default: + mfg_off = 0 ; + break ; + } + if (mfg_off) + break ; + } + + if ((mfg_off) && (k)) + mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ; + + return mfg_nic ; +} + +char * +get_first_string(char **ptrs, int n) +{ + int i ; + char *tmpptr ; + + if ((ptrs == NULL) || (n == 0)) + return NULL ; + + tmpptr = ptrs[0] ; + + if (n == 1) + return tmpptr ; + + for (i = 0 ; i < n ; i++) { + if (strcmp(tmpptr, ptrs[i]) > 0) + tmpptr = ptrs[i] ; + } + + return tmpptr ; +} + +int +get_ptrs(char *idata, char **ptrs, int n, char *label) +{ + int i = 0 ; + char *tmp = idata ; + + if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0)) + return 0 ; + + while ( (tmp = strstr(tmp, label)) ){ + tmp += strlen(label) ; + /* check for empty name field, and last NULL ptr */ + if ((i < (n-1)) && (*tmp != ';')) { + ptrs[i++] = tmp ; + } + } + + ptrs[i] = NULL ; + + return i ; +} + +/* + * sort_nic_names + * + * Does not really do sorting. Find the alphabetically lowest + * name among all the nic names found in a nic string. + * + * Return: + * Nothing + * + * Side Effects: + * + * lb->brd_name gets the new name found + */ + +static void +sort_nic_names(lboard_t *lb) +{ + char *nic_str ; + char *ptrs[MAX_NICS_PER_STRING] ; + char name[MAX_NIC_NAME_LEN] ; + char *tmp, *tmp1 ; + + *name = 0 ; + + /* Get the nic pointer from the lb */ + + if ((nic_str = get_nic_string(lb)) == NULL) + return ; + + tmp = get_first_string(ptrs, + get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ; + + if (tmp == NULL) + return ; + + if ( (tmp1 = strchr(tmp, ';')) ){ + strncpy(name, tmp, tmp1-tmp) ; + name[tmp1-tmp] = 0 ; + } else { + strncpy(name, tmp, (sizeof(name) -1)) ; + name[sizeof(name)-1] = 0 ; + } + + strcpy(lb->brd_name, name) ; +} + + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + +char brick_types[MAX_BRICK_TYPES + 1] = "crikxdp789012345"; + +/* + * Format a module id for printing. + */ +void +format_module_id(char *buffer, moduleid_t m, int fmt) +{ + int rack, position; + char brickchar; + + rack = MODULE_GET_RACK(m); + ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES); + brickchar = MODULE_GET_BTCHAR(m); + position = MODULE_GET_BPOS(m); + + if (fmt == MODULE_FORMAT_BRIEF) { + /* Brief module number format, eg. 002c15 */ + + /* Decompress the rack number */ + *buffer++ = '0' + RACK_GET_CLASS(rack); + *buffer++ = '0' + RACK_GET_GROUP(rack); + *buffer++ = '0' + RACK_GET_NUM(rack); + + /* Add the brick type */ + *buffer++ = brickchar; + } + else if (fmt == MODULE_FORMAT_LONG) { + /* Fuller hwgraph format, eg. rack/002/bay/15 */ + + strcpy(buffer, EDGE_LBL_RACK "/"); buffer += strlen(buffer); + + *buffer++ = '0' + RACK_GET_CLASS(rack); + *buffer++ = '0' + RACK_GET_GROUP(rack); + *buffer++ = '0' + RACK_GET_NUM(rack); + + strcpy(buffer, "/" EDGE_LBL_RPOS "/"); buffer += strlen(buffer); + } + + /* Add the bay position, using at least two digits */ + if (position < 10) + *buffer++ = '0'; + sprintf(buffer, "%d", position); + +} + +/* + * Parse a module id, in either brief or long form. + * Returns < 0 on error. + * The long form does not include a brick type, so it defaults to 0 (CBrick) + */ +int +parse_module_id(char *buffer) +{ + unsigned int v, rack, bay, type, form; + moduleid_t m; + char c; + + if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) { + form = MODULE_FORMAT_LONG; + buffer += strlen(EDGE_LBL_RACK "/"); + + /* A long module ID must be exactly 5 non-template chars. */ + if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5) + return -1; + } + else { + form = MODULE_FORMAT_BRIEF; + + /* A brief module id must be exactly 6 characters */ + if (strlen(buffer) != 6) + return -2; + } + + /* The rack number must be exactly 3 digits */ + if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2]))) + return -3; + + rack = 0; + v = *buffer++ - '0'; + if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) + return -4; + RACK_ADD_CLASS(rack, v); + + v = *buffer++ - '0'; + if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) + return -5; + RACK_ADD_GROUP(rack, v); + + v = *buffer++ - '0'; + /* rack numbers are 1-based */ + if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) + return -6; + RACK_ADD_NUM(rack, v); + + if (form == MODULE_FORMAT_BRIEF) { + /* Next should be a module type character. Accept ucase or lcase. */ + c = *buffer++; + if (!isalpha(c)) + return -7; + + /* strchr() returns a pointer into brick_types[], or NULL */ + type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types); + if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT) + return -8; + } + else { + /* Hardcode the module type, and skip over the boilerplate */ + type = MODULE_CBRICK; + + if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer) + return -9; + + buffer += strlen("/" EDGE_LBL_RPOS "/"); + } + + /* The bay number is last. Make sure it's exactly two digits */ + + if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2])) + return -10; + + bay = 10 * (buffer[0] - '0') + (buffer[1] - '0'); + + if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) + return -11; + + m = RBT_TO_MODULE(rack, bay, type); + + /* avoid sign extending the moduleid_t */ + return (int)(unsigned short)m; +} + +#else /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + +/* + * Format a module id for printing. + */ +void +format_module_id(char *buffer, moduleid_t m, int fmt) +{ + if (fmt == MODULE_FORMAT_BRIEF) { + sprintf(buffer, "%d", m); + } + else if (fmt == MODULE_FORMAT_LONG) { + sprintf(buffer, EDGE_LBL_MODULE "/%d", m); + } +} + +/* + * Parse a module id, in either brief or long form. + * Returns < 0 on error. + */ +int +parse_module_id(char *buffer) +{ + moduleid_t m; + char c; + + if (strstr(buffer, EDGE_LBL_MODULE "/") == buffer) + buffer += strlen(EDGE_LBL_MODULE "/"); + + m = 0; + while(c = *buffer++) { + if (!isdigit(c)) + return -1; + m = 10 * m + (c - '0'); + } + + /* avoid sign extending the moduleid_t */ + return (int)(unsigned short)m; +} + +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/klgraph.c linux-2.4.0-test12-lia/arch/ia64/sn/io/klgraph.c --- linux-2.4.0-test12/arch/ia64/sn/io/klgraph.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/klgraph.c Wed Dec 6 21:54:09 2000 @@ -0,0 +1,971 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* + * klgraph.c- + * This file specifies the interface between the kernel and the PROM's + * configuration data structures. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#ifdef CONFIG_IA64_SGI_IO +#include +#endif +#include +#include +#include +#include +#include + +#define KLGRAPH_DEBUG 1 +#ifdef KLGRAPH_DEBUG +#define GRPRINTF(x) printk x +#define CE_GRPANIC CE_PANIC +#else +#define GRPRINTF(x) +#define CE_GRPANIC CE_PANIC +#endif + +#include + +extern char arg_maxnodes[]; +extern int maxnodes; + +#ifndef BRINGUP +/* + * Gets reason for diagval using table lookup. + */ +static char* +get_diag_string(uint diagcode) +{ + int num_entries; + int i; + num_entries = sizeof(diagval_map) / sizeof(diagval_t); + for (i = 0; i < num_entries; i++){ + if ((unchar)diagval_map[i].dv_code == (unchar)diagcode) + return diagval_map[i].dv_msg; + } + return "Unknown"; +} + +#endif /* ndef BRINGUP */ + + +/* + * Support for verbose inventory via hardware graph. + * klhwg_invent_alloc allocates the necessary size of inventory information + * and fills in the generic information. + */ +invent_generic_t * +klhwg_invent_alloc(cnodeid_t cnode, int class, int size) +{ + invent_generic_t *invent; + + invent = kern_malloc(size); + if (!invent) return NULL; + + invent->ig_module = NODE_MODULEID(cnode); + invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode)); + invent->ig_invclass = class; + + return invent; +} + +/* + * Add information about the baseio prom version number + * as a part of detailed inventory info in the hwgraph. + */ +void +klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode) +{ + invent_miscinfo_t *baseio_inventory; + unsigned char version = 0,revision = 0; + + /* Allocate memory for the "detailed inventory" info + * for the baseio + */ + baseio_inventory = (invent_miscinfo_t *) + klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t)); + baseio_inventory->im_type = INV_IO6PROM; + /* Read the io6prom revision from the nvram */ +#ifndef CONFIG_IA64_SGI_IO + nvram_prom_version_get(&version,&revision); +#endif + /* Store the revision info in the inventory */ + baseio_inventory->im_version = version; + baseio_inventory->im_rev = revision; + /* Put the inventory info in the hardware graph */ + hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t) baseio_inventory); + /* Make the information available to the user programs + * thru hwgfs. + */ + hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, + sizeof(invent_miscinfo_t)); +} + +char *hub_rev[] = { + "0.0", + "1.0", + "2.0", + "2.1", + "2.2", + "2.3" +}; + +/* + * Add detailed cpu inventory info to the hardware graph. + */ +void +klhwg_hub_invent_info(devfs_handle_t hubv, + cnodeid_t cnode, + klhub_t *hub) +{ + invent_miscinfo_t *hub_invent; + + hub_invent = (invent_miscinfo_t *) + klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t)); + if (!hub_invent) + return; + + if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub)) + hub_invent->im_gen.ig_flag = INVENT_ENABLED; + + hub_invent->im_type = INV_HUB; + hub_invent->im_rev = hub->hub_info.revision; + hub_invent->im_speed = hub->hub_speed; + hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t) hub_invent); + hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT, + sizeof(invent_miscinfo_t)); +} + +/* ARGSUSED */ +void +klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode) +{ + devfs_handle_t myhubv; + int rc; + + GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB)); + + (void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv); + rc = device_master_set(myhubv, node_vertex); + +#ifndef CONFIG_IA64_SGI_IO + /* + * Activate when we support hub stats. + */ + rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO, + (arbitrary_info_t)(&NODEPDA(cnode)->hubstats)); +#endif + + if (rc != GRAPH_SUCCESS) { + cmn_err(CE_WARN, + "klhwg_add_hub: Can't add hub info label 0x%p, code %d", + myhubv, rc); + } + + klhwg_hub_invent_info(myhubv, cnode, hub); + +#ifndef BRINGUP + init_hub_stats(cnode, NODEPDA(cnode)); +#endif /* ndef BRINGUP */ + +#ifndef CONFIG_IA64_SGI_IO + sndrv_attach(myhubv); +#else + /* + * Need to call our driver to do the attach? + */ + printk("klhwg_add_hub: Need to add code to do the attach.\n"); +#endif +} + +#ifndef BRINGUP + +void +klhwg_add_rps(devfs_handle_t node_vertex, cnodeid_t cnode, int flag) +{ + devfs_handle_t myrpsv; + invent_rpsinfo_t *rps_invent; + int rc; + + if(cnode == CNODEID_NONE) + return; + + GRPRINTF(("klhwg_add_rps: adding %s to vertex 0x%x\n", EDGE_LBL_RPS, + node_vertex)); + + rc = hwgraph_path_add(node_vertex, EDGE_LBL_RPS, &myrpsv); + if (rc != GRAPH_SUCCESS) + return; + + device_master_set(myrpsv, node_vertex); + + rps_invent = (invent_rpsinfo_t *) + klhwg_invent_alloc(cnode, INV_RPS, sizeof(invent_rpsinfo_t)); + + if (!rps_invent) + return; + + rps_invent->ir_xbox = 0; /* not an xbox RPS */ + + if (flag) + rps_invent->ir_gen.ig_flag = INVENT_ENABLED; + else + rps_invent->ir_gen.ig_flag = 0x0; + + hwgraph_info_add_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t) rps_invent); + hwgraph_info_export_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, + sizeof(invent_rpsinfo_t)); + +} + +/* + * klhwg_update_rps gets invoked when the system controller sends an + * interrupt indicating the power supply has lost/regained the redundancy. + * It's responsible for updating the Hardware graph information. + * rps_state = 0 -> if the rps lost the redundancy + * = 1 -> If it is redundant. + */ +void +klhwg_update_rps(cnodeid_t cnode, int rps_state) +{ + devfs_handle_t node_vertex; + devfs_handle_t rpsv; + invent_rpsinfo_t *rps_invent; + int rc; + if(cnode == CNODEID_NONE) + return; + + node_vertex = cnodeid_to_vertex(cnode); + rc = hwgraph_edge_get(node_vertex, EDGE_LBL_RPS, &rpsv); + if (rc != GRAPH_SUCCESS) { + return; + } + + rc = hwgraph_info_get_LBL(rpsv, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t *)&rps_invent); + if (rc != GRAPH_SUCCESS) { + return; + } + + if (rps_state == 0 ) + rps_invent->ir_gen.ig_flag = 0; + else + rps_invent->ir_gen.ig_flag = INVENT_ENABLED; +} + +void +klhwg_add_xbox_rps(devfs_handle_t node_vertex, cnodeid_t cnode, int flag) +{ + devfs_handle_t myrpsv; + invent_rpsinfo_t *rps_invent; + int rc; + + if(cnode == CNODEID_NONE) + return; + + GRPRINTF(("klhwg_add_rps: adding %s to vertex 0x%x\n", + EDGE_LBL_XBOX_RPS, node_vertex)); + + rc = hwgraph_path_add(node_vertex, EDGE_LBL_XBOX_RPS, &myrpsv); + if (rc != GRAPH_SUCCESS) + return; + + device_master_set(myrpsv, node_vertex); + + rps_invent = (invent_rpsinfo_t *) + klhwg_invent_alloc(cnode, INV_RPS, sizeof(invent_rpsinfo_t)); + + if (!rps_invent) + return; + + rps_invent->ir_xbox = 1; /* xbox RPS */ + + if (flag) + rps_invent->ir_gen.ig_flag = INVENT_ENABLED; + else + rps_invent->ir_gen.ig_flag = 0x0; + + hwgraph_info_add_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t) rps_invent); + hwgraph_info_export_LBL(myrpsv, INFO_LBL_DETAIL_INVENT, + sizeof(invent_rpsinfo_t)); + +} + +/* + * klhwg_update_xbox_rps gets invoked when the xbox system controller + * polls the status register and discovers that the power supply has + * lost/regained the redundancy. + * It's responsible for updating the Hardware graph information. + * rps_state = 0 -> if the rps lost the redundancy + * = 1 -> If it is redundant. + */ +void +klhwg_update_xbox_rps(cnodeid_t cnode, int rps_state) +{ + devfs_handle_t node_vertex; + devfs_handle_t rpsv; + invent_rpsinfo_t *rps_invent; + int rc; + if(cnode == CNODEID_NONE) + return; + + node_vertex = cnodeid_to_vertex(cnode); + rc = hwgraph_edge_get(node_vertex, EDGE_LBL_XBOX_RPS, &rpsv); + if (rc != GRAPH_SUCCESS) { + return; + } + + rc = hwgraph_info_get_LBL(rpsv, INFO_LBL_DETAIL_INVENT, + (arbitrary_info_t *)&rps_invent); + if (rc != GRAPH_SUCCESS) { + return; + } + + if (rps_state == 0 ) + rps_invent->ir_gen.ig_flag = 0; + else + rps_invent->ir_gen.ig_flag = INVENT_ENABLED; +} + +#endif /* ndef BRINGUP */ + +void +klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid) +{ + lboard_t *brd; + klxbow_t *xbow_p; + nasid_t hub_nasid; + cnodeid_t hub_cnode; + int widgetnum; + devfs_handle_t xbow_v, hubv; + /*REFERENCED*/ + graph_error_t err; + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || defined(CONFIG_IA64_GENERIC) + if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_PBRICK_XBOW)) == NULL) + return; +#endif + + if (KL_CONFIG_DUPLICATE_BOARD(brd)) + return; + + GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n", + cnode, nasid)); + + if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW)) + == NULL) + return; + +#ifndef CONFIG_IA64_SGI_IO + /* + * We cannot support this function in devfs .. see below where + * we use hwgraph_path_add() to create this vertex with a known + * name. + */ + err = hwgraph_vertex_create(&xbow_v); + ASSERT(err == GRAPH_SUCCESS); + + xswitch_vertex_init(xbow_v); +#endif /* !CONFIG_IA64_SGI_IO */ + + for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { + if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) + continue; + + hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum); + printk("klhwg_add_xbow: Found xbow port type hub hub_nasid %d widgetnum %d\n", hub_nasid, widgetnum); + if (hub_nasid == INVALID_NASID) { + cmn_err(CE_WARN, "hub widget %d, skipping xbow graph\n", widgetnum); + continue; + } + + hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid); + printk("klhwg_add_xbow: cnode %d cnode %d\n", nasid_to_compact_node[0], nasid_to_compact_node[1]); + + if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) { + continue; + } + + hubv = cnodeid_to_vertex(hub_cnode); + +#ifdef CONFIG_IA64_SGI_IO + printk("klhwg_add_xbow: Hub Vertex found = %p hub_cnode %d\n", hubv, hub_cnode); + err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v); + if (err != GRAPH_SUCCESS) { + if (err == GRAPH_DUP) + cmn_err(CE_WARN, "klhwg_add_xbow: Check for " + "working routers and router links!"); + + cmn_err(CE_GRPANIC, "klhwg_add_xbow: Failed to add " + "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p)," + "error %d\n", + hubv, hubv, xbow_v, xbow_v, err); + } + xswitch_vertex_init(xbow_v); +#endif + + NODEPDA(hub_cnode)->xbow_vhdl = xbow_v; + + /* + * XXX - This won't work is we ever hook up two hubs + * by crosstown through a crossbow. + */ + if (hub_nasid != nasid) { + NODEPDA(hub_cnode)->xbow_peer = nasid; + NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer = + hub_nasid; + } + + GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n", + hub_nasid, EDGE_LBL_XTALK, hubv)); + +#ifndef CONFIG_IA64_SGI_IO + err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK); + if (err != GRAPH_SUCCESS) { + if (err == GRAPH_DUP) + cmn_err(CE_WARN, "klhwg_add_xbow: Check for " + "working routers and router links!"); + + cmn_err(CE_GRPANIC, "klhwg_add_xbow: Failed to add " + "edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), " + "error %d\n", + hubv, hubv, xbow_v, xbow_v, err); + } +#endif + } +} + + +/* ARGSUSED */ +void +klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap) +{ + nasid_t nasid; + lboard_t *brd; + klhub_t *hub; + devfs_handle_t node_vertex = NULL; + char path_buffer[100]; + int rv; + char *s; + int board_disabled = 0; + + nasid = COMPACT_TO_NASID_NODEID(cnode); + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); + GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n", + cnode, nasid, brd)); + ASSERT(brd); + + do { + + /* Generate a hardware graph path for this board. */ + board_to_path(brd, path_buffer); + + GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n", + path_buffer, hwgraph_root)); + rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); + + printk("klhwg_add_node: rv = %d graph success %d node_vertex 0x%p\n", rv, GRAPH_SUCCESS, node_vertex); + if (rv != GRAPH_SUCCESS) + cmn_err(CE_PANIC, "Node vertex creation failed. " + "Path == %s", + path_buffer); + + hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); + ASSERT(hub); + if(hub->hub_info.flags & KLINFO_ENABLE) + board_disabled = 0; + else + board_disabled = 1; + + if(!board_disabled) { + mark_nodevertex_as_node(node_vertex, + cnode + board_disabled * numnodes); + printk("klhwg_add_node: node_vertex %p, cnode %d numnodes %d\n", node_vertex, cnode, numnodes); + + s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer)); + printk("klhwg_add_node: s %s\n", s); + + NODEPDA(cnode)->hwg_node_name = + kmalloc(strlen(s) + 1, + GFP_KERNEL); + ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL); + strcpy(NODEPDA(cnode)->hwg_node_name, s); + + hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo); + + /* Set up node board's slot */ + NODEPDA(cnode)->slotdesc = brd->brd_slot; + + /* Set up the module we're in */ + NODEPDA(cnode)->module_id = brd->brd_module; + NODEPDA(cnode)->module = module_lookup(brd->brd_module); + } + + if(!board_disabled) + klhwg_add_hub(node_vertex, hub, cnode); + + brd = KLCF_NEXT(brd); + if (brd) + brd = find_lboard(brd, KLTYPE_IP27); + else + break; + } while(brd); +} + + +/* ARGSUSED */ +void +klhwg_add_all_routers(devfs_handle_t hwgraph_root) +{ + nasid_t nasid; + cnodeid_t cnode; + lboard_t *brd; + devfs_handle_t node_vertex; + char path_buffer[100]; + int rv; + + for (cnode = 0; cnode < maxnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + + GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n", + cnode)); + + brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_ROUTER); + + if (!brd) + /* No routers stored in this node's memory */ + continue; + + do { + ASSERT(brd); + GRPRINTF(("Router board struct is %p\n", brd)); + + /* Don't add duplicate boards. */ + if (brd->brd_flags & DUPLICATE_BOARD) + continue; + + GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module)); + /* Generate a hardware graph path for this board. */ + board_to_path(brd, path_buffer); + + GRPRINTF(("Router path is %s\n", path_buffer)); + + /* Add the router */ + GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n", + path_buffer, hwgraph_root)); + rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex); + + if (rv != GRAPH_SUCCESS) + cmn_err(CE_PANIC, "Router vertex creation " + "failed. Path == %s", + path_buffer); + + GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n", + brd)); + /* Find the rest of the routers stored on this node. */ + } while ( (brd = find_lboard_class(KLCF_NEXT(brd), + KLTYPE_ROUTER)) ); + + GRPRINTF(("klhwg_add_all_routers: Done.\n")); + } + +} + +/* ARGSUSED */ +void +klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd, + cnodeid_t cnode, nasid_t nasid) +{ + klrou_t *router; + char path_buffer[50]; + char dest_path[50]; + devfs_handle_t router_hndl; + devfs_handle_t dest_hndl; + int rc; + int port; + lboard_t *dest_brd; + + GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n", + cnode)); + + /* Don't add duplicate boards. */ + if (brd->brd_flags & DUPLICATE_BOARD) { + GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n", + brd, cnode)); + return; + } + + /* Generate a hardware graph path for this board. */ + board_to_path(brd, path_buffer); + + rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl); + + if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes)) + return; + + if (rc != GRAPH_SUCCESS) + cmn_err(CE_WARN, "Can't find router: %s", path_buffer); + + /* We don't know what to do with multiple router components */ + if (brd->brd_numcompts != 1) { + cmn_err(CE_PANIC, + "klhwg_connect_one_router: %d cmpts on router\n", + brd->brd_numcompts); + return; + } + + + /* Convert component 0 to klrou_t ptr */ + router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), + brd->brd_compts[0]); + + for (port = 1; port <= MAX_ROUTER_PORTS; port++) { + /* See if the port's active */ + if (router->rou_port[port].port_nasid == INVALID_NASID) { + GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n", + port)); + continue; + } + if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) + == INVALID_CNODEID) { + continue; + } + + dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( + router->rou_port[port].port_nasid, + router->rou_port[port].port_offset); + + /* Generate a hardware graph path for this board. */ + board_to_path(dest_brd, dest_path); + + rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); + + if (rc != GRAPH_SUCCESS) { + if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd)) + continue; + cmn_err(CE_PANIC, "Can't find router: %s", dest_path); + } + GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n", + path_buffer, port, dest_path)); + + sprintf(dest_path, "%d", port); + + rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path); + + if (rc == GRAPH_DUP) { + GRPRINTF(("Skipping port %d. nasid %d %s/%s\n", + port, router->rou_port[port].port_nasid, + path_buffer, dest_path)); + continue; + } + + if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes)) + cmn_err(CE_GRPANIC, "Can't create edge: %s/%s to vertex 0x%p error 0x%x\n", + path_buffer, dest_path, dest_hndl, rc); + + } +} + + +void +klhwg_connect_routers(devfs_handle_t hwgraph_root) +{ + nasid_t nasid; + cnodeid_t cnode; + lboard_t *brd; + + for (cnode = 0; cnode < maxnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + + GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n", + cnode)); + + brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_ROUTER); + + if (!brd) + continue; + + do { + + nasid = COMPACT_TO_NASID_NODEID(cnode); + + klhwg_connect_one_router(hwgraph_root, brd, + cnode, nasid); + + /* Find the rest of the routers stored on this node. */ + } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); + } +} + + + +void +klhwg_connect_hubs(devfs_handle_t hwgraph_root) +{ + nasid_t nasid; + cnodeid_t cnode; + lboard_t *brd; + klhub_t *hub; + lboard_t *dest_brd; + devfs_handle_t hub_hndl; + devfs_handle_t dest_hndl; + char path_buffer[50]; + char dest_path[50]; + graph_error_t rc; + + for (cnode = 0; cnode < maxnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + + GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n", + cnode)); + + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_IP27); + ASSERT(brd); + + hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); + ASSERT(hub); + + /* See if the port's active */ + if (hub->hub_port.port_nasid == INVALID_NASID) { + GRPRINTF(("klhwg_connect_hubs: port inactive.\n")); + continue; + } + + if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID) + continue; + + /* Generate a hardware graph path for this board. */ + board_to_path(brd, path_buffer); + + GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer)); + rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl); + + if (rc != GRAPH_SUCCESS) + cmn_err(CE_WARN, "Can't find hub: %s", path_buffer); + + dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( + hub->hub_port.port_nasid, + hub->hub_port.port_offset); + + /* Generate a hardware graph path for this board. */ + board_to_path(dest_brd, dest_path); + + rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl); + + if (rc != GRAPH_SUCCESS) { + if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd)) + continue; + cmn_err(CE_PANIC, "Can't find board: %s", dest_path); + } else { + + + GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n", + path_buffer, dest_path)); + + rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT); + + if (rc != GRAPH_SUCCESS) + cmn_err(CE_GRPANIC, "Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n", + path_buffer, dest_path, dest_hndl, rc); + + } + } +} + +/* Store the pci/vme disabled board information as extended administrative + * hints which can later be used by the drivers using the device/driver + * admin interface. + */ +void +klhwg_device_disable_hints_add(void) +{ + cnodeid_t cnode; /* node we are looking at */ + nasid_t nasid; /* nasid of the node */ + lboard_t *board; /* board we are looking at */ + int comp_index; /* component index */ + klinfo_t *component; /* component in the board we are + * looking at + */ + char device_name[MAXDEVNAME]; + +#ifndef CONFIG_IA64_SGI_IO + device_admin_table_init(); +#endif + for(cnode = 0; cnode < numnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + board = (lboard_t *)KL_CONFIG_INFO(nasid); + /* Check out all the board info stored on a node */ + while(board) { + /* No need to look at duplicate boards or non-io + * boards + */ + if (KL_CONFIG_DUPLICATE_BOARD(board) || + KLCLASS(board->brd_type) != KLCLASS_IO) { + board = KLCF_NEXT(board); + continue; + } + /* Check out all the components of a board */ + for (comp_index = 0; + comp_index < KLCF_NUM_COMPS(board); + comp_index++) { + component = KLCF_COMP(board,comp_index); + /* If the component is enabled move on to + * the next component + */ + if (KLCONFIG_INFO_ENABLED(component)) + continue; + /* NOTE : Since the prom only supports + * the disabling of pci devices the following + * piece of code makes sense. + * Make sure that this assumption is valid + */ + /* This component is disabled. Store this + * hint in the extended device admin table + */ + /* Get the canonical name of the pci device */ + device_component_canonical_name_get(board, + component, + device_name); +#ifndef CONFIG_IA64_SGI_IO + device_admin_table_update(device_name, + ADMIN_LBL_DISABLED, + "yes"); +#endif +#ifdef DEBUG + printf("%s DISABLED\n",device_name); +#endif + } + /* go to the next board info stored on this + * node + */ + board = KLCF_NEXT(board); + } + } +} + +void +klhwg_add_all_modules(devfs_handle_t hwgraph_root) +{ + cmoduleid_t cm; + char name[128]; + devfs_handle_t vhdl; + int rc; + + /* Add devices under each module */ + + for (cm = 0; cm < nummodules; cm++) { + /* Use module as module vertex fastinfo */ + + sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id); + + rc = hwgraph_path_add(hwgraph_root, name, &vhdl); + ASSERT(rc == GRAPH_SUCCESS); + rc = rc; + + hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]); + + /* Add system controller */ + + sprintf(name, + EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1, + modules[cm]->id); + + rc = hwgraph_path_add(hwgraph_root, name, &vhdl); + ASSERT_ALWAYS(rc == GRAPH_SUCCESS); + rc = rc; + + hwgraph_info_add_LBL(vhdl, + INFO_LBL_ELSC, + (arbitrary_info_t) (__psint_t) 1); + +#ifndef CONFIG_IA64_SGI_IO + sndrv_attach(vhdl); +#else + /* + * We need to call the drivers attach routine .. + */ + FIXME("klhwg_add_all_modules: Need code to call driver attach.\n"); +#endif + } +} + +void +klhwg_add_all_nodes(devfs_handle_t hwgraph_root) +{ + //gda_t *gdap = GDA; + gda_t *gdap; + cnodeid_t cnode; + +#ifdef SIMULATED_KLGRAPH + //gdap = 0xa800000000011000; + gdap = (gda_t *)0xe000000000011000; + printk("klhwg_add_all_nodes: SIMULATED_KLGRAPH FIXME: gdap= 0x%p\n", gdap); +#else + gdap = GDA; +#endif /* SIMULATED_KLGRAPH */ + for (cnode = 0; cnode < numnodes; cnode++) { + ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID); + klhwg_add_node(hwgraph_root, cnode, gdap); + } + + for (cnode = 0; cnode < numnodes; cnode++) { + ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID); + +#ifndef CONFIG_IA64_SGI_IO + klhwg_add_xbow(cnode, gdap->g_nasidtable[cnode]); +#else + printk("klhwg_add_all_nodes: Fix me by getting real nasid\n"); + klhwg_add_xbow(cnode, 0); +#endif + } + + /* + * As for router hardware inventory information, we set this + * up in router.c. + */ + + klhwg_add_all_routers(hwgraph_root); + klhwg_connect_routers(hwgraph_root); + klhwg_connect_hubs(hwgraph_root); + + /* Assign guardian nodes to each of the + * routers in the system. + */ + +#ifndef CONFIG_IA64_SGI_IO + router_guardians_set(hwgraph_root); +#endif + + /* Go through the entire system's klconfig + * to figure out which pci components have been disabled + */ + klhwg_device_disable_hints_add(); + +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/klgraph_hack.c linux-2.4.0-test12-lia/arch/ia64/sn/io/klgraph_hack.c --- linux-2.4.0-test12/arch/ia64/sn/io/klgraph_hack.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/klgraph_hack.c Wed Dec 13 18:59:33 2000 @@ -0,0 +1,847 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + + +/* + * This is a temporary file that statically initializes the expected + * initial klgraph information that is normally provided by prom. + */ + +#include +#include +#include +#include +#include +#include + +void * real_port; +void * real_io_base; +void * real_addr; + +char *BW0 = NULL; + +kl_config_hdr_t *linux_klcfg; + +#ifdef BRINGUP +/* forward declarations */ +extern void dump_ii(void), dump_lb(void), dump_crossbow(void); +extern void clear_ii_error(void); +#endif /* BRINGUP */ + +void +simulated_BW0_init(void) +{ + + unsigned long *cnode0_hub; + unsigned long hub_widget = 0x1000000; + unsigned long hub_offset = 0x800000; + unsigned long hub_reg_base = 0; + extern void * vmalloc(unsigned long); + + memset(&nasid_to_compact_node[0], 0, sizeof(cnodeid_t) * MAX_NASIDS); + + BW0 = vmalloc(0x10000000); + if (BW0 == NULL) { + printk("Darn it .. cannot create space for Big Window 0\n"); + } + printk("BW0: Start Address %p\n", BW0); + + memset(BW0+(0x10000000 - 8), 0xf, 0x8); + + printk("BW0: Last WORD address %p has value 0x%lx\n", (char *)(BW0 +(0x10000000 - 8)), *(long *)(BW0 +(0x10000000 - 8))); + + printk("XWIDGET 8 Address = 0x%p\n", (unsigned long *)(NODE_SWIN_BASE(0, 8)) ); + + /* + * Do some HUB Register Hack .. + */ + hub_reg_base = (unsigned long)BW0 + hub_widget + hub_offset; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_WID); *cnode0_hub = 0x1c110049; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_WSTAT); *cnode0_hub = 0x0; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_WCR); *cnode0_hub = 0x401b; + printk("IIO_WCR address = 0x%p\n", cnode0_hub); + + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILAPR); *cnode0_hub = 0xffffffffffffffff; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILAPO); *cnode0_hub = 0x0; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IOWA); *cnode0_hub = 0xff01; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IIWA); *cnode0_hub = 0xff01; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IIDEM); *cnode0_hub = 0xffffffffffffffff; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILCSR); *cnode0_hub = 0x3fc03ff640a; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILLR); *cnode0_hub = 0x0; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IIDSR); *cnode0_hub = 0x1000040; +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IGFX0); *cnode0_hub = 0x0; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IGFX1); *cnode0_hub = 0x0; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ISCR0); *cnode0_hub = 0x23d; + cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ISCR1); *cnode0_hub = 0x0; +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ +} + +#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) + +int test = 0; + +/* + * Hack to loop for test. + */ +void +test_io_regs(void) +{ + + uint32_t reg_32bits; + uint64_t reg_64bits; + + while (test) { + + reg_32bits = (uint32_t)(*(volatile uint32_t *) SYNERGY_WIDGET); + reg_64bits = (uint64_t) (*(volatile uint64_t *) SYNERGY_WIDGET); + + } + + printk("Synergy Widget Address = 0x%p, Value = 0x%lx\n", SYNERGY_WIDGET, (uint64_t)*(SYNERGY_WIDGET)); + + printk("Synergy swizzle Address = 0x%p, Value = 0x%lx\n", SYNERGY_SWIZZLE, (uint64_t)*(SYNERGY_SWIZZLE)); + printk("HUBREG Address = 0x%p, Value = 0x%lx\n", HUBREG, (uint64_t)*(HUBREG)); + printk("WIDGET0 Address = 0x%p, Value = 0x%lx\n", WIDGET0, (uint64_t)*(WIDGET0)); + printk("WIDGET4 Address = 0x%p, Value = 0x%x\n", WIDGET4, (uint32_t)*(WIDGET4)); + +} + +void +klgraph_hack_init(void) +{ + + kl_config_hdr_t *kl_hdr_ptr; + lboard_t *lb_ptr; + lboard_t *temp_ptr; + klhub_t *klhub_ptr; + klioc3_t *klioc3_ptr; + klbri_t *klbri_ptr; + klxbow_t *klxbow_ptr; + klinfo_t *klinfo_ptr; + klcomp_t *klcomp_ptr; + uint64_t *tmp; + volatile u32 *tmp32; + +#ifdef 0 + /* Preset some values */ + /* Write IOERR clear to clear the CRAZY bit in the status */ + tmp = (uint64_t *)0xc0000a0001c001f8; *tmp = (uint64_t)0xffffffff; + /* set widget control register...setting bedrock widget id to b */ + /* tmp = (uint64_t *)0xc0000a0001c00020; *tmp = (uint64_t)0x801b; */ + /* set io outbound widget access...allow all */ + tmp = (uint64_t *)0xc0000a0001c00110; *tmp = (uint64_t)0xff01; + /* set io inbound widget access...allow all */ + tmp = (uint64_t *)0xc0000a0001c00118; *tmp = (uint64_t)0xff01; + /* set io crb timeout to max */ + tmp = (uint64_t *)0xc0000a0001c003c0; *tmp = (uint64_t)0xffffff; + tmp = (uint64_t *)0xc0000a0001c003c0; *tmp = (uint64_t)0xffffff; + + /* set local block io permission...allow all */ + tmp = (uint64_t *)0xc0000a0001e04010; *tmp = (uint64_t)0xfffffffffffffff; + + /* clear any errors */ + clear_ii_error(); + + /* set default read response buffers in bridge */ + tmp32 = (volatile u32 *)0xc0000a000f000280L; + *tmp32 = 0xba98; + tmp32 = (volatile u32 *)0xc0000a000f000288L; + *tmp32 = 0xba98; +#endif + +printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001e00000, *( (volatile uint64_t *)0xc0000a0001e00000) ); + +printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001c00000, *( (volatile uint64_t *)0xc0000a0001c00000) ); + +printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc000020001e00000, *( (volatile uint64_t *)0xc000020001e00000) ); + + +printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc000020001c00000, *( (volatile uint64_t *)0xc000020001c00000) ); + +printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001e00000, *( (volatile uint64_t *)0xc0000a0001e00000) ); + +printk("Xbow ID Address 0x%p Value 0x%x\n", (uint64_t *)0xc0000a0000000000, *( (volatile uint32_t *)0xc0000a0000000000) ); + +printk("Xbow ID Address 0x%p Value 0x%x\n", (uint64_t *)0xc000020000000004, *( (volatile uint32_t *)0xc000020000000004) ); + + + if ( test ) + test_io_regs(); + /* + * Klconfig header. + */ + kl_hdr_ptr = kmalloc(sizeof(kl_config_hdr_t), GFP_KERNEL); + kl_hdr_ptr->ch_magic = 0xbeedbabe; + kl_hdr_ptr->ch_version = 0x0; + kl_hdr_ptr->ch_malloc_hdr_off = 0x48; + kl_hdr_ptr->ch_cons_off = 0x18; + kl_hdr_ptr->ch_board_info = 0x0; + kl_hdr_ptr->ch_cons_info.uart_base = 0x920000000f820178; + kl_hdr_ptr->ch_cons_info.config_base = 0x920000000f024000; + kl_hdr_ptr->ch_cons_info.memory_base = 0x920000000f800000; + kl_hdr_ptr->ch_cons_info.baud = 0x2580; + kl_hdr_ptr->ch_cons_info.flag = 0x1; + kl_hdr_ptr->ch_cons_info.type = 0x300fafa; + kl_hdr_ptr->ch_cons_info.nasid = 0x0; + kl_hdr_ptr->ch_cons_info.wid = 0xf; + kl_hdr_ptr->ch_cons_info.npci = 0x4; + kl_hdr_ptr->ch_cons_info.baseio_nic = 0x0; + + /* + * We need to know whether we are booting from PROM or + * boot from disk. + */ + linux_klcfg = (kl_config_hdr_t *)0xe000000000030000; + if (linux_klcfg->ch_magic == 0xbeedbabe) { + printk("Linux Kernel Booted from Disk\n"); + } else { + printk("Linux Kernel Booted from PROM\n"); + linux_klcfg = kl_hdr_ptr; + } + + /* + * lboard KLTYPE_IP35 + */ + lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL); + kl_hdr_ptr->ch_board_info = (klconf_off_t) lb_ptr; + temp_ptr = lb_ptr; + printk("First Lboard = %p\n", temp_ptr); + + lb_ptr->brd_next = 0; + lb_ptr->struct_type = 0x1; + lb_ptr->brd_type = 0x11; + lb_ptr->brd_sversion = 0x3; + lb_ptr->brd_brevision = 0x1; + lb_ptr->brd_promver = 0x1; + lb_ptr->brd_promver = 0x1; + lb_ptr->brd_slot = 0x0; + lb_ptr->brd_debugsw = 0x0; + lb_ptr->brd_module = 0x145; + lb_ptr->brd_partition = 0x0; + lb_ptr->brd_diagval = 0x0; + lb_ptr->brd_diagparm = 0x0; + lb_ptr->brd_inventory = 0x0; + lb_ptr->brd_numcompts = 0x5; + lb_ptr->brd_nic = 0x2a0aed35; + lb_ptr->brd_nasid = 0x0; + lb_ptr->brd_errinfo = 0x0; + lb_ptr->brd_parent = 0x0; + lb_ptr->brd_graph_link = (devfs_handle_t)0x26; + lb_ptr->brd_owner = 0x0; + lb_ptr->brd_nic_flags = 0x0; + memcpy(&lb_ptr->brd_name[0], "IP35", 4); + + /* + * Hub Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klhub_ptr = (klhub_t *)klcomp_ptr; + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr; + printk("hub info = %p lboard = %p\n", klhub_ptr, lb_ptr); + + klinfo_ptr = (klinfo_t *)klhub_ptr; + klinfo_ptr->struct_type = 0x2; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0x1; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0x2a0aed35; + klinfo_ptr->physid = 0x0; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0x0; + klinfo_ptr->nasid = 0x0; + + klhub_ptr->hub_flags = 0x0; + klhub_ptr->hub_port.port_nasid = (nasid_t)0x0ffffffff; + klhub_ptr->hub_port.port_flag = 0x0; + klhub_ptr->hub_port.port_offset = 0x0; + klhub_ptr->hub_box_nic = 0x0; + klhub_ptr->hub_mfg_nic = 0x3f420; + klhub_ptr->hub_speed = 0xbebc200; + + /* + * Memory Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[1] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x3; + klinfo_ptr->struct_version = 0x2; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0xff; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0xff; + klinfo_ptr->virtid = 0xffffffff; + klinfo_ptr->widid = 0x0; + klinfo_ptr->nasid = 0x0; + + /* + * KLSTRUCT_HUB_UART Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[2] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x11; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x31; + klinfo_ptr->revision = 0xff; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x0; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0x0; + klinfo_ptr->nasid = 0x0; + + /* + * KLSTRUCT_CPU Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[3] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x1; + klinfo_ptr->struct_version = 0x2; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0xff; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x0; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0x0; + klinfo_ptr->nasid = 0x0; + + /* + * KLSTRUCT_CPU Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[4] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x1; + klinfo_ptr->struct_version = 0x2; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0xff; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x1; + klinfo_ptr->virtid = 0x1; + klinfo_ptr->widid = 0x0; + klinfo_ptr->nasid = 0x0; + + lb_ptr->brd_compts[5] = 0; /* Set the next one to 0 .. end */ + lb_ptr->brd_numcompts = 5; /* 0 to 4 */ + + /* + * lboard(0x42) KLTYPE_PBRICK_XBOW + */ + lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL); + temp_ptr->brd_next = (klconf_off_t)lb_ptr; /* Let the previous point at the new .. */ + temp_ptr = lb_ptr; + printk("Second Lboard = %p\n", temp_ptr); + + lb_ptr->brd_next = 0; + lb_ptr->struct_type = 0x1; + lb_ptr->brd_type = 0x42; + lb_ptr->brd_sversion = 0x2; + lb_ptr->brd_brevision = 0x0; + lb_ptr->brd_promver = 0x1; + lb_ptr->brd_promver = 0x1; + lb_ptr->brd_slot = 0x0; + lb_ptr->brd_debugsw = 0x0; + lb_ptr->brd_module = 0x145; + lb_ptr->brd_partition = 0x1; + lb_ptr->brd_diagval = 0x0; + lb_ptr->brd_diagparm = 0x0; + lb_ptr->brd_inventory = 0x0; + lb_ptr->brd_numcompts = 0x1; + lb_ptr->brd_nic = 0xffffffffffffffff; + lb_ptr->brd_nasid = 0x0; + lb_ptr->brd_errinfo = 0x0; + lb_ptr->brd_parent = (struct lboard_s *)0x9600000000030070; + lb_ptr->brd_graph_link = (devfs_handle_t)0xffffffff; + lb_ptr->brd_owner = 0x0; + lb_ptr->brd_nic_flags = 0x0; + memcpy(&lb_ptr->brd_name[0], "IOBRICK", 7); + + /* + * KLSTRUCT_XBOW Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + memset(klcomp_ptr, 0, sizeof(klcomp_t)); + klxbow_ptr = (klxbow_t *)klcomp_ptr; + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr; + printk("xbow_p 0x%p\n", klcomp_ptr); + + klinfo_ptr->struct_type = 0x4; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0x2; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0xff; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0x0; + klinfo_ptr->nasid = 0x0; + + klxbow_ptr->xbow_master_hub_link = 0xb; + klxbow_ptr->xbow_port_info[0].port_nasid = 0x0; + klxbow_ptr->xbow_port_info[0].port_flag = 0x0; + klxbow_ptr->xbow_port_info[0].port_offset = 0x0; + + klxbow_ptr->xbow_port_info[1].port_nasid = 0x401; + klxbow_ptr->xbow_port_info[1].port_flag = 0x0; + klxbow_ptr->xbow_port_info[1].port_offset = 0x0; + + klxbow_ptr->xbow_port_info[2].port_nasid = 0x0; + klxbow_ptr->xbow_port_info[2].port_flag = 0x0; + klxbow_ptr->xbow_port_info[2].port_offset = 0x0; + + klxbow_ptr->xbow_port_info[3].port_nasid = 0x0; /* ffffffff */ + klxbow_ptr->xbow_port_info[3].port_flag = 0x6; + klxbow_ptr->xbow_port_info[3].port_offset = 0x30070; + + klxbow_ptr->xbow_port_info[4].port_nasid = 0x0; /* ffffff00; */ + klxbow_ptr->xbow_port_info[4].port_flag = 0x0; + klxbow_ptr->xbow_port_info[4].port_offset = 0x0; + + klxbow_ptr->xbow_port_info[5].port_nasid = 0x0; + klxbow_ptr->xbow_port_info[5].port_flag = 0x0; + klxbow_ptr->xbow_port_info[5].port_offset = 0x0; + klxbow_ptr->xbow_port_info[6].port_nasid = 0x0; + klxbow_ptr->xbow_port_info[6].port_flag = 0x5; + klxbow_ptr->xbow_port_info[6].port_offset = 0x30210; + klxbow_ptr->xbow_port_info[7].port_nasid = 0x3; + klxbow_ptr->xbow_port_info[7].port_flag = 0x5; + klxbow_ptr->xbow_port_info[7].port_offset = 0x302e0; + + lb_ptr->brd_compts[1] = 0; + lb_ptr->brd_numcompts = 1; + + + /* + * lboard KLTYPE_PBRICK + */ + lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL); + temp_ptr->brd_next = (klconf_off_t)lb_ptr; /* Let the previous point at the new .. */ + temp_ptr = lb_ptr; + printk("Third Lboard %p\n", lb_ptr); + + lb_ptr->brd_next = 0; + lb_ptr->struct_type = 0x1; + lb_ptr->brd_type = 0x72; + lb_ptr->brd_sversion = 0x2; + lb_ptr->brd_brevision = 0x0; + lb_ptr->brd_promver = 0x1; + lb_ptr->brd_promver = 0x41; + lb_ptr->brd_slot = 0xe; + lb_ptr->brd_debugsw = 0x0; + lb_ptr->brd_module = 0x145; + lb_ptr->brd_partition = 0x1; + lb_ptr->brd_diagval = 0x0; + lb_ptr->brd_diagparm = 0x0; + lb_ptr->brd_inventory = 0x0; + lb_ptr->brd_numcompts = 0x1; + lb_ptr->brd_nic = 0x30e3fd; + lb_ptr->brd_nasid = 0x0; + lb_ptr->brd_errinfo = 0x0; + lb_ptr->brd_parent = (struct lboard_s *)0x9600000000030140; + lb_ptr->brd_graph_link = (devfs_handle_t)0xffffffff; + lb_ptr->brd_owner = 0x0; + lb_ptr->brd_nic_flags = 0x0; + memcpy(&lb_ptr->brd_name[0], "IP35", 4); + + /* + * KLSTRUCT_BRI Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klbri_ptr = (klbri_t *)klcomp_ptr; + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x5; + klinfo_ptr->struct_version = 0x2; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0x2; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0xd002; + klinfo_ptr->nic = 0x30e3fd; + klinfo_ptr->physid = 0xe; + klinfo_ptr->virtid = 0xe; + klinfo_ptr->widid = 0xe; + klinfo_ptr->nasid = 0x0; + + klbri_ptr->bri_eprominfo = 0xff; + klbri_ptr->bri_bustype = 0x7; + klbri_ptr->bri_mfg_nic = 0x3f4a8; + + lb_ptr->brd_compts[1] = 0; + lb_ptr->brd_numcompts = 1; + + /* + * lboard KLTYPE_PBRICK + */ + lb_ptr = kmalloc(sizeof(lboard_t), GFP_KERNEL); + temp_ptr->brd_next = (klconf_off_t)lb_ptr; /* Let the previous point at the new .. */ + temp_ptr = lb_ptr; + printk("Fourth Lboard %p\n", lb_ptr); + + lb_ptr->brd_next = 0x0; + lb_ptr->struct_type = 0x1; + lb_ptr->brd_type = 0x72; + lb_ptr->brd_sversion = 0x2; + lb_ptr->brd_brevision = 0x0; + lb_ptr->brd_promver = 0x1; + lb_ptr->brd_promver = 0x31; + lb_ptr->brd_slot = 0xf; + lb_ptr->brd_debugsw = 0x0; + lb_ptr->brd_module = 0x145; + lb_ptr->brd_partition = 0x1; + lb_ptr->brd_diagval = 0x0; + lb_ptr->brd_diagparm = 0x0; + lb_ptr->brd_inventory = 0x0; + lb_ptr->brd_numcompts = 0x6; + lb_ptr->brd_nic = 0x30e3fd; + lb_ptr->brd_nasid = 0x0; + lb_ptr->brd_errinfo = 0x0; + lb_ptr->brd_parent = (struct lboard_s *)0x9600000000030140; + lb_ptr->brd_graph_link = (devfs_handle_t)0xffffffff; + lb_ptr->brd_owner = 0x0; + lb_ptr->brd_nic_flags = 0x0; + memcpy(&lb_ptr->brd_name[0], "IP35", 4); + + + /* + * KLSTRUCT_BRI Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klbri_ptr = (klbri_t *)klcomp_ptr; + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[0] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x5; + klinfo_ptr->struct_version = 0x2; + klinfo_ptr->flags = 0x1; + klinfo_ptr->revision = 0x2; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0xd002; + klinfo_ptr->nic = 0x30e3fd; + klinfo_ptr->physid = 0xf; + klinfo_ptr->virtid = 0xf; + klinfo_ptr->widid = 0xf; + klinfo_ptr->nasid = 0x0; + + klbri_ptr->bri_eprominfo = 0xff; + klbri_ptr->bri_bustype = 0x7; + klbri_ptr->bri_mfg_nic = 0x3f528; + + /* + * KLSTRUCT_SCSI component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[1] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0xb; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x31; + klinfo_ptr->revision = 0x5; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x1; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0xf; + klinfo_ptr->nasid = 0x0; + + /* + * KLSTRUCT_IOC3 Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klioc3_ptr = (klioc3_t *)klcomp_ptr; + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[2] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x6; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x31; + klinfo_ptr->revision = 0x1; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x4; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0xf; + klinfo_ptr->nasid = 0x0; + + klioc3_ptr->ioc3_ssram = 0x0; + klioc3_ptr->ioc3_nvram = 0x0; + + /* + * KLSTRUCT_UNKNOWN Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[3] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x0; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x31; + klinfo_ptr->revision = 0xff; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x5; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0xf; + klinfo_ptr->nasid = 0x0; + + /* + * KLSTRUCT_SCSI Component + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[4] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0xb; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x31; + klinfo_ptr->revision = 0x1; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x6; + klinfo_ptr->virtid = 0x5; + klinfo_ptr->widid = 0xf; + klinfo_ptr->nasid = 0x0; + + /* + * KLSTRUCT_UNKNOWN + */ + klcomp_ptr = kmalloc(sizeof(klcomp_t), GFP_KERNEL); + klinfo_ptr = (klinfo_t *)klcomp_ptr; + lb_ptr->brd_compts[5] = (klconf_off_t)klcomp_ptr; + + klinfo_ptr->struct_type = 0x0; + klinfo_ptr->struct_version = 0x1; + klinfo_ptr->flags = 0x31; + klinfo_ptr->revision = 0xff; + klinfo_ptr->diagval = 0x0; + klinfo_ptr->diagparm = 0x0; + klinfo_ptr->inventory = 0x0; + klinfo_ptr->partid = 0x0; + klinfo_ptr->nic = 0xffffffffffffffff; + klinfo_ptr->physid = 0x7; + klinfo_ptr->virtid = 0x0; + klinfo_ptr->widid = 0xf; + klinfo_ptr->nasid = 0x0; + + lb_ptr->brd_compts[6] = 0; + lb_ptr->brd_numcompts = 6; + +} + + + + + +#ifdef BRINGUP +/* + * these were useful for printing out registers etc + * during bringup + */ + +void +xdump(long long *addr, int count) +{ + int ii; + volatile long long *xx = addr; + + for ( ii = 0; ii < count; ii++, xx++ ) { + printk("0x%p : 0x%p\n", xx, *xx); + } +} + +void +xdump32(unsigned int *addr, int count) +{ + int ii; + volatile unsigned int *xx = addr; + + for ( ii = 0; ii < count; ii++, xx++ ) { + printk("0x%p : 0x%0x\n", xx, *xx); + } +} + + + +void +clear_ii_error(void) +{ + volatile long long *tmp; + + printk("... WSTAT "); + xdump((long long *)0xc0000a0001c00008, 1); + printk("... WCTRL "); + xdump((long long *)0xc0000a0001c00020, 1); + printk("... WLCSR "); + xdump((long long *)0xc0000a0001c00128, 1); + printk("... IIDSR "); + xdump((long long *)0xc0000a0001c00138, 1); + printk("... IOPRBs "); + xdump((long long *)0xc0000a0001c00198, 9); + printk("... IXSS "); + xdump((long long *)0xc0000a0001c00210, 1); + printk("... IBLS0 "); + xdump((long long *)0xc0000a0001c10000, 1); + printk("... IBLS1 "); + xdump((long long *)0xc0000a0001c20000, 1); + + /* Write IOERR clear to clear the CRAZY bit in the status */ + tmp = (long long *)0xc0000a0001c001f8; *tmp = (long long)0xffffffff; + + /* dump out local block error registers */ + printk("... "); + xdump((long long *)0xc0000a0001e04040, 1); /* LB_ERROR_BITS */ + printk("... "); + xdump((long long *)0xc0000a0001e04050, 1); /* LB_ERROR_HDR1 */ + printk("... "); + xdump((long long *)0xc0000a0001e04058, 1); /* LB_ERROR_HDR2 */ + /* and clear the LB_ERROR_BITS */ + tmp = (long long *)0xc0000a0001e04040; *tmp = 0x0; + printk("clr: "); + xdump((long long *)0xc0000a0001e04040, 1); /* LB_ERROR_BITS */ + tmp = (long long *)0xc0000a0001e04050; *tmp = 0x0; + tmp = (long long *)0xc0000a0001e04058; *tmp = 0x0; +} + + +void +dump_ii() +{ + printk("===== Dump the II regs =====\n"); + xdump((long long *)0xc0000a0001c00000, 2); + xdump((long long *)0xc0000a0001c00020, 1); + xdump((long long *)0xc0000a0001c00100, 37); + xdump((long long *)0xc0000a0001c00300, 98); + xdump((long long *)0xc0000a0001c10000, 6); + xdump((long long *)0xc0000a0001c20000, 6); + xdump((long long *)0xc0000a0001c30000, 2); + + xdump((long long *)0xc0000a0000000000, 1); + xdump((long long *)0xc0000a0001000000, 1); + xdump((long long *)0xc0000a0002000000, 1); + xdump((long long *)0xc0000a0003000000, 1); + xdump((long long *)0xc0000a0004000000, 1); + xdump((long long *)0xc0000a0005000000, 1); + xdump((long long *)0xc0000a0006000000, 1); + xdump((long long *)0xc0000a0007000000, 1); + xdump((long long *)0xc0000a0008000000, 1); + xdump((long long *)0xc0000a0009000000, 1); + xdump((long long *)0xc0000a000a000000, 1); + xdump((long long *)0xc0000a000b000000, 1); + xdump((long long *)0xc0000a000c000000, 1); + xdump((long long *)0xc0000a000d000000, 1); + xdump((long long *)0xc0000a000e000000, 1); + xdump((long long *)0xc0000a000f000000, 1); +} + +void +dump_lb() +{ + printk("===== Dump the LB regs =====\n"); + xdump((long long *)0xc0000a0001e00000, 1); + xdump((long long *)0xc0000a0001e04000, 13); + xdump((long long *)0xc0000a0001e04100, 2); + xdump((long long *)0xc0000a0001e04200, 2); + xdump((long long *)0xc0000a0001e08000, 5); + xdump((long long *)0xc0000a0001e08040, 2); + xdump((long long *)0xc0000a0001e08050, 3); + xdump((long long *)0xc0000a0001e0c000, 3); + xdump((long long *)0xc0000a0001e0c020, 4); +} + +void +dump_crossbow() +{ + printk("===== Dump the Crossbow regs =====\n"); + clear_ii_error(); + xdump32((unsigned int *)0xc0000a0000000004, 1); + clear_ii_error(); + xdump32((unsigned int *)0xc0000a0000000000, 1); + printk("and again..\n"); + xdump32((unsigned int *)0xc0000a0000000000, 1); + xdump32((unsigned int *)0xc0000a0000000000, 1); + + + clear_ii_error(); + + xdump32((unsigned int *)0xc000020000000004, 1); + clear_ii_error(); + xdump32((unsigned int *)0xc000020000000000, 1); + clear_ii_error(); + + xdump32((unsigned int *)0xc0000a0000800004, 1); + clear_ii_error(); + xdump32((unsigned int *)0xc0000a0000800000, 1); + clear_ii_error(); + + xdump32((unsigned int *)0xc000020000800004, 1); + clear_ii_error(); + xdump32((unsigned int *)0xc000020000800000, 1); + clear_ii_error(); + + +} +#endif /* BRINGUP */ diff -urN linux-2.4.0-test12/arch/ia64/sn/io/l1.c linux-2.4.0-test12-lia/arch/ia64/sn/io/l1.c --- linux-2.4.0-test12/arch/ia64/sn/io/l1.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/l1.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,2974 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* 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 interfaces (there are two): + * (1) "elscuart", used in the IP35prom and (maybe) some + * debugging situations elsewhere, and + * (2) "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. Their names are leftover from early SN0, + * when the "module system controller" (msc) was known as the "entry level + * system controller" (elsc). The names and signatures of those functions + * remain unchanged in order to keep the SN0 -> SN1 system controller + * changes fairly localized. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#if defined(EEPROM_DEBUG) +#define db_printf(x) printk x +#else +#define db_printf(x) +#endif + +// From irix/kern/sys/SN/SN1/bdrkhspecregs.h +#define HSPEC_UART_0 0x00000080 /* UART Registers */ + +/********************************************************************* + * Hardware-level (UART) driver routines. + */ + +/* macros for reading/writing registers */ + +#define LD(x) (*(volatile uint64_t *)(x)) +#define SD(x, v) (LD(x) = (uint64_t) (v)) + +/* location of uart receive/xmit data register */ +#define L1_UART_BASE(n) ((ulong)REMOTE_HSPEC_ADDR((n), HSPEC_UART_0)) +#define LOCAL_HUB LOCAL_HUB_ADDR + +#define ADDR_L1_REG(n, r) \ + (L1_UART_BASE(n) | ( (r) << 3 )) + +#define READ_L1_UART_REG(n, r) \ + ( LD(ADDR_L1_REG((n), (r))) ) + +#define WRITE_L1_UART_REG(n, r, v) \ + ( SD(ADDR_L1_REG((n), (r)), (v)) ) + + +/* Avoid conflicts with symmon...*/ +#define CONS_HW_LOCK(x) +#define CONS_HW_UNLOCK(x) + +#define L1_CONS_HW_LOCK(sc) CONS_HW_LOCK(sc->uart == BRL1_LOCALUART) +#define L1_CONS_HW_UNLOCK(sc) CONS_HW_UNLOCK(sc->uart == BRL1_LOCALUART) + +#if DEBUG +static int debuglock_ospl; /* For CONS_HW_LOCK macro */ +#endif + +/* UART-related #defines */ + +#define UART_BAUD_RATE 57600 +#define UART_FIFO_DEPTH 16 +#define UART_DELAY_SPAN 10 +#define UART_PUTC_TIMEOUT 50000 +#define UART_INIT_TIMEOUT 100000 + +/* error codes */ +#define UART_SUCCESS 0 +#define UART_TIMEOUT (-1) +#define UART_LINK (-2) +#define UART_NO_CHAR (-3) +#define UART_VECTOR (-4) + +#ifdef BRINGUP +#define UART_DELAY(x) { int i; i = x * 1000; while (--i); } +#else +#define UART_DELAY(x) us_delay(x) +#endif + +/* + * Some macros for handling Endian-ness + */ + +#ifdef LITTLE_ENDIAN +#define COPY_INT_TO_BUFFER(_b, _i, _n) \ + { \ + _b[_i++] = (_n >> 24) & 0xff; \ + _b[_i++] = (_n >> 16) & 0xff; \ + _b[_i++] = (_n >> 8) & 0xff; \ + _b[_i++] = _n & 0xff; \ + } + +#define COPY_BUFFER_TO_INT(_b, _i, _n) \ + { \ + _n = (_b[_i++] << 24) & 0xff; \ + _n |= (_b[_i++] << 16) & 0xff; \ + _n |= (_b[_i++] << 8) & 0xff; \ + _n |= _b[_i++] & 0xff; \ + } + +#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn) \ + { \ + char *_xyz = (char *)_bn; \ + _xyz[3] = _b[_i++]; \ + _xyz[2] = _b[_i++]; \ + _xyz[1] = _b[_i++]; \ + _xyz[0] = _b[_i++]; \ + } +#else /* BIG_ENDIAN */ +#define COPY_INT_TO_BUFFER(_b, _i, _n) \ + { \ + bcopy((char *)&_n, _b, sizeof(_n)); \ + _i += sizeof(_n); \ + } + +#define COPY_BUFFER_TO_INT(_b, _i, _n) \ + { \ + bcopy(&_b[_i], &_n, sizeof(_n)); \ + _i += sizeof(_n); \ + } + +#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn) \ + { \ + bcopy(&(_b[_i]), _bn, sizeof(int)); \ + _i += sizeof(int); \ + } +#endif /* LITTLE_ENDIAN */ + +int atomicAddInt(int *int_ptr, int value); +int atomicClearInt(int *int_ptr, int value); +void kmem_free(void *where, int size); + +#define BCOPY(x,y,z) memcpy(y,x,z) + +extern char *bcopy(const char * src, char * dest, int count); + + +int +get_L1_baud(void) +{ + return UART_BAUD_RATE; +} + + +/* uart driver functions */ + +static void +uart_delay( rtc_time_t delay_span ) +{ + UART_DELAY( delay_span ); +} + +#define UART_PUTC_READY(n) (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE) + +static int +uart_putc( l1sc_t *sc ) +{ +#ifdef BRINGUP + /* need a delay to avoid dropping chars */ + UART_DELAY(57); +#endif + WRITE_L1_UART_REG( sc->nasid, REG_DAT, + sc->send[sc->sent] ); + return UART_SUCCESS; +} + + +static int +uart_getc( l1sc_t *sc ) +{ + u_char lsr_reg = 0; + nasid_t nasid = sc->nasid; + + if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & + (LSR_RCA | LSR_PARERR | LSR_FRMERR) ) + { + if( lsr_reg & LSR_RCA ) + return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) ); + else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) { + return UART_LINK; + } + } + + return UART_NO_CHAR; +} + + +#define PROM_SER_CLK_SPEED 12000000 +#define PROM_SER_DIVISOR(x) (PROM_SER_CLK_SPEED / ((x) * 16)) + +static void +uart_init( l1sc_t *sc, int baud ) +{ + rtc_time_t expire; + int clkdiv; + nasid_t nasid; + + clkdiv = PROM_SER_DIVISOR(baud); + expire = rtc_time() + UART_INIT_TIMEOUT; + nasid = sc->nasid; + + /* make sure the transmit FIFO is empty */ + while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) { + uart_delay( UART_DELAY_SPAN ); + if( rtc_time() > expire ) { + break; + } + } + + L1_CONS_HW_LOCK( sc ); + + WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB ); + uart_delay( UART_DELAY_SPAN ); + WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff ); + uart_delay( UART_DELAY_SPAN ); + WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff ); + uart_delay( UART_DELAY_SPAN ); + + /* set operating parameters and set DLAB to 0 */ + WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 ); + uart_delay( UART_DELAY_SPAN ); + WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE ); + uart_delay( UART_DELAY_SPAN ); + + /* disable interrupts */ + WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 ); + uart_delay( UART_DELAY_SPAN ); + + /* enable FIFO mode and reset both FIFOs */ + WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN ); + uart_delay( UART_DELAY_SPAN ); + WRITE_L1_UART_REG( nasid, REG_FCR, + FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO ); + + L1_CONS_HW_UNLOCK( sc ); +} + +static void +uart_intr_enable( l1sc_t *sc, u_char mask ) +{ + u_char lcr_reg, icr_reg; + nasid_t nasid = sc->nasid; + + L1_CONS_HW_LOCK(sc); + + /* make sure that the DLAB bit in the LCR register is 0 + */ + lcr_reg = READ_L1_UART_REG( nasid, REG_LCR ); + lcr_reg &= ~(LCR_DLAB); + WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg ); + + /* enable indicated interrupts + */ + icr_reg = READ_L1_UART_REG( nasid, REG_ICR ); + icr_reg |= mask; + WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ ); + + L1_CONS_HW_UNLOCK(sc); +} + +static void +uart_intr_disable( l1sc_t *sc, u_char mask ) +{ + u_char lcr_reg, icr_reg; + nasid_t nasid = sc->nasid; + + L1_CONS_HW_LOCK(sc); + + /* make sure that the DLAB bit in the LCR register is 0 + */ + lcr_reg = READ_L1_UART_REG( nasid, REG_LCR ); + lcr_reg &= ~(LCR_DLAB); + WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg ); + + /* enable indicated interrupts + */ + icr_reg = READ_L1_UART_REG( nasid, REG_ICR ); + icr_reg &= mask; + WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ ); + + L1_CONS_HW_UNLOCK(sc); +} + +#define uart_enable_xmit_intr(sc) \ + uart_intr_enable((sc), ICR_TIEN) + +#define uart_disable_xmit_intr(sc) \ + uart_intr_disable((sc), ~(ICR_TIEN)) + +#define uart_enable_recv_intr(sc) \ + uart_intr_enable((sc), ICR_RIEN) + +#define uart_disable_recv_intr(sc) \ + uart_intr_disable((sc), ~(ICR_RIEN)) + + +/********************************************************************* + * Routines for accessing a remote (router) UART + */ + +#define READ_RTR_L1_UART_REG(p, n, r, v) \ + { \ + if( vector_read_node( (p), (n), 0, \ + RR_JBUS1(r), (v) ) ) { \ + return UART_VECTOR; \ + } \ + } + +#define WRITE_RTR_L1_UART_REG(p, n, r, v) \ + { \ + if( vector_write_node( (p), (n), 0, \ + RR_JBUS1(r), (v) ) ) { \ + return UART_VECTOR; \ + } \ + } + +#ifdef SABLE +#define RTR_UART_PUTC_TIMEOUT 0 +#define RTR_UART_DELAY_SPAN 0 +#define RTR_UART_INIT_TIMEOUT 0 +#else +#define RTR_UART_PUTC_TIMEOUT UART_PUTC_TIMEOUT*10 +#define RTR_UART_DELAY_SPAN UART_DELAY_SPAN +#define RTR_UART_INIT_TIMEOUT UART_INIT_TIMEOUT*10 +#endif + +static int +rtr_uart_putc( l1sc_t *sc ) +{ + uint64_t regval, c; + nasid_t nasid = sc->nasid; + net_vec_t path = sc->uart; + rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT; + + c = (sc->send[sc->sent] & 0xffULL); + + while( 1 ) + { + /* Check for "tx hold reg empty" bit. */ + READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); + if( regval & LSR_XHRE ) + { + WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c ); + return UART_SUCCESS; + } + + if( rtc_time() >= expire ) + { + return UART_TIMEOUT; + } + uart_delay( RTR_UART_DELAY_SPAN ); + } +} + + +static int +rtr_uart_getc( l1sc_t *sc ) +{ + uint64_t regval; + nasid_t nasid = sc->nasid; + net_vec_t path = sc->uart; + + READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); + if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) ) + { + if( regval & LSR_RCA ) + { + READ_RTR_L1_UART_REG( path, nasid, REG_DAT, ®val ); + return( (int)regval ); + } + else + { + return UART_LINK; + } + } + + return UART_NO_CHAR; +} + + +static int +rtr_uart_init( l1sc_t *sc, int baud ) +{ + rtc_time_t expire; + int clkdiv; + nasid_t nasid; + net_vec_t path; + uint64_t regval; + + clkdiv = PROM_SER_DIVISOR(baud); + expire = rtc_time() + RTR_UART_INIT_TIMEOUT; + nasid = sc->nasid; + path = sc->uart; + + /* make sure the transmit FIFO is empty */ + while(1) { + READ_RTR_L1_UART_REG( path, nasid, REG_LSR, ®val ); + if( regval & LSR_XSRE ) { + break; + } + if( rtc_time() > expire ) { + break; + } + uart_delay( RTR_UART_DELAY_SPAN ); + } + + WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB ); + uart_delay( UART_DELAY_SPAN ); + WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff ); + uart_delay( UART_DELAY_SPAN ); + WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff ); + uart_delay( UART_DELAY_SPAN ); + + /* set operating parameters and set DLAB to 0 */ + WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 ); + uart_delay( UART_DELAY_SPAN ); + WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE ); + uart_delay( UART_DELAY_SPAN ); + + /* disable interrupts */ + WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0 ); + uart_delay( UART_DELAY_SPAN ); + + /* enable FIFO mode and reset both FIFOs */ + WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN ); + uart_delay( UART_DELAY_SPAN ); + WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, + FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO ); + + return 0; +} + + + +/********************************************************************* + * locking macros + */ + +#define L1SC_SEND_LOCK(l,pl) \ + { if( (l)->uart == BRL1_LOCALUART ) \ + (pl) = mutex_spinlock_spl( &((l)->send_lock), spl7 ); } + +#define L1SC_SEND_UNLOCK(l,pl) \ + { if( (l)->uart == BRL1_LOCALUART ) \ + mutex_spinunlock( &((l)->send_lock), (pl)); } + +#define L1SC_RECV_LOCK(l,pl) \ + { if( (l)->uart == BRL1_LOCALUART ) \ + (pl) = mutex_spinlock_spl( &((l)->recv_lock), spl7 ); } + +#define L1SC_RECV_UNLOCK(l,pl) \ + { if( (l)->uart == BRL1_LOCALUART ) \ + mutex_spinunlock( &((l)->recv_lock), (pl)); } + + +/********************************************************************* + * subchannel manipulation + * + * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel + * allocation. SUBCH_DATA_[UN]LOCK control access to data structures + * associated with particular subchannels (e.g., receive queues). + * + */ + + +#ifdef SPINLOCKS_WORK +#define SUBCH_LOCK(sc,pl) \ + (pl) = mutex_spinlock_spl( &((sc)->subch_lock), spl7 ) +#define SUBCH_UNLOCK(sc,pl) \ + mutex_spinunlock( &((sc)->subch_lock), (pl) ) + +#define SUBCH_DATA_LOCK(sbch,pl) \ + (pl) = mutex_spinlock_spl( &((sbch)->data_lock), spl7 ) +#define SUBCH_DATA_UNLOCK(sbch,pl) \ + mutex_spinunlock( &((sbch)->data_lock), (pl) ) +#else +#define SUBCH_LOCK(sc,pl) +#define SUBCH_UNLOCK(sc,pl) +#define SUBCH_DATA_LOCK(sbch,pl) +#define SUBCH_DATA_UNLOCK(sbch,pl) +#endif /* SPINLOCKS_WORK */ + +/* + * set a function to be called for subchannel ch in the event of + * a transmission low-water interrupt from the uart + */ +void +subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func ) +{ + int pl; + L1SC_SEND_LOCK( sc, pl ); + sc->subch[ch].tx_notify = func; + + /* some upper layer is asking to be notified of low-water, but if the + * send buffer isn't already in use, we're going to need to get the + * interrupts going on the uart... + */ + if( func && !sc->send_in_use ) + uart_enable_xmit_intr( sc ); + L1SC_SEND_UNLOCK(sc, pl ); +} + +/* + * set a function to be called for subchannel ch when data is received + */ +void +subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func ) +{ +#ifdef SPINLOCKS_WORK + int pl; +#endif + brl1_sch_t *subch = &(sc->subch[ch]); + + SUBCH_DATA_LOCK( subch, pl ); + sc->subch[ch].rx_notify = func; + SUBCH_DATA_UNLOCK( subch, pl ); +} + + + +/* get_myid is an internal function that reads the PI_CPU_NUM + * register of the local bedrock to determine which of the + * four possible CPU's "this" one is + */ +static int +get_myid( void ) +{ + return( LD(LOCAL_HUB(PI_CPU_NUM)) ); +} + + + +/********************************************************************* + * Queue manipulation macros + * + * + */ +#define NEXT(p) (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */ + +#define cq_init(q) bzero((q), sizeof (*(q))) +#define cq_empty(q) ((q)->ipos == (q)->opos) +#define cq_full(q) (NEXT((q)->ipos) == (q)->opos) +#define cq_used(q) ((q)->opos <= (q)->ipos ? \ + (q)->ipos - (q)->opos : \ + BRL1_QSIZE + (q)->ipos - (q)->opos) +#define cq_room(q) ((q)->opos <= (q)->ipos ? \ + BRL1_QSIZE - 1 + (q)->opos - (q)->ipos : \ + (q)->opos - (q)->ipos - 1) +#define cq_add(q, c) ((q)->buf[(q)->ipos] = (u_char) (c), \ + (q)->ipos = NEXT((q)->ipos)) +#define cq_rem(q, c) ((c) = (q)->buf[(q)->opos], \ + (q)->opos = NEXT((q)->opos)) +#define cq_discard(q) ((q)->opos = NEXT((q)->opos)) + +#define cq_tent_full(q) (NEXT((q)->tent_next) == (q)->opos) +#define cq_tent_len(q) ((q)->ipos <= (q)->tent_next ? \ + (q)->tent_next - (q)->ipos : \ + BRL1_QSIZE + (q)->tent_next - (q)->ipos) +#define cq_tent_add(q, c) \ + ((q)->buf[(q)->tent_next] = (u_char) (c), \ + (q)->tent_next = NEXT((q)->tent_next)) +#define cq_commit_tent(q) \ + ((q)->ipos = (q)->tent_next) +#define cq_discard_tent(q) \ + ((q)->tent_next = (q)->ipos) + + + + +/********************************************************************* + * CRC-16 (for checking bedrock/L1 packets). + * + * These are based on RFC 1662 ("PPP in HDLC-like framing"). + */ + +static unsigned short fcstab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#define INIT_CRC 0xFFFF /* initial CRC value */ +#define GOOD_CRC 0xF0B8 /* "good" final CRC value */ + +static unsigned short crc16_calc( unsigned short crc, u_char c ) +{ + return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] ); +} + + +/*********************************************************************** + * The following functions implement the PPP-like bedrock/L1 protocol + * layer. + * + */ + +#define BRL1_FLAG_CH 0x7e +#define BRL1_ESC_CH 0x7d +#define BRL1_XOR_CH 0x20 + +/* L1<->Bedrock packet types */ +#define BRL1_REQUEST 0x00 +#define BRL1_RESPONSE 0x20 +#define BRL1_EVENT 0x40 + +#define BRL1_PKT_TYPE_MASK 0xE0 +#define BRL1_SUBCH_MASK 0x1F + +#define PKT_TYPE(tsb) ((tsb) & BRL1_PKT_TYPE_MASK) +#define SUBCH(tsb) ((tsb) & BRL1_SUBCH_MASK) + +/* timeouts */ +#define BRL1_INIT_TIMEOUT 500000 + +extern l1sc_t * get_elsc( void ); + +/* + * brl1_discard_packet is a dummy "receive callback" used to get rid + * of packets we don't want + */ +void brl1_discard_packet( l1sc_t *sc, int ch ) +{ + int pl; + brl1_sch_t *subch = &sc->subch[ch]; + sc_cq_t *q = subch->iqp; + SUBCH_DATA_LOCK( subch, pl ); + q->opos = q->ipos; + atomicClearInt( &(subch->packet_arrived), ~((unsigned)0) ); + SUBCH_DATA_UNLOCK( subch, pl ); +} + + +/* + * brl1_send_chars sends the send buffer in the l1sc_t structure + * out through the uart. Assumes that the caller has locked the + * UART (or send buffer in the kernel). + * + * This routine doesn't block-- if you want it to, call it in + * a loop. + */ +static int +brl1_send_chars( l1sc_t *sc ) +{ + /* In the kernel, we track the depth of the C brick's UART's + * fifo in software, and only check if the UART is accepting + * characters when our count indicates that the fifo should + * be full. + * + * For remote (router) UARTs, and also for the local (C brick) + * UART in the prom, we check with the UART before sending every + * character. + */ + if( sc->uart == BRL1_LOCALUART ) + { + CONS_HW_LOCK(1); + if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) ) +// sc->fifo_space = UART_FIFO_DEPTH; + sc->fifo_space = 1000; + + while( (sc->sent < sc->send_len) && (sc->fifo_space) ) { + uart_putc( sc ); + sc->fifo_space--; + sc->sent++; + } + + CONS_HW_UNLOCK(1); + } + + else + + /* The following applies to all UARTs in the prom, and to remote + * (router) UARTs in the kernel... + */ + +#define TIMEOUT_RETRIES 30 + + { + int result; + int tries = 0; + + while( sc->sent < sc->send_len ) { + result = sc->putc_f( sc ); + if( result >= 0 ) { + (sc->sent)++; + continue; + } + if( result == UART_TIMEOUT ) { + tries++; + /* send this character in TIMEOUT_RETRIES... */ + if( tries < TIMEOUT_RETRIES ) { + continue; + } + /* ...or else... */ + else { + /* ...drop the packet. */ + sc->sent = sc->send_len; + return sc->send_len; + } + } + if( result < 0 ) { + return result; + } + } + } + + return sc->sent; +} + + +/* brl1_send formats up a packet and (at least begins to) send it + * to the uart. If the send buffer is in use when this routine obtains + * the lock, it will behave differently depending on the "wait" parameter. + * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"), + * hopefully encouraging the caller to back off (unlock any high-level + * spinlocks) and allow the buffer some time to drain. For wait==1 (high- + * priority I/O along the lines of kernel error messages), we will flush + * the current contents of the send buffer and beat on the uart + * until our message has been completely transmitted. + */ + +int +brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait ) +{ + int pl; + int index; + int pkt_len = 0; + unsigned short crc = INIT_CRC; + char *send_ptr = sc->send; + + L1SC_SEND_LOCK(sc, pl); + + if( sc->send_in_use ) { + if( !wait ) { + L1SC_SEND_UNLOCK(sc, pl); + return 0; /* couldn't send anything; wait for buffer to drain */ + } + else { + /* buffer's in use, but we're synchronous I/O, so we're going + * to send whatever's in there right now and take the buffer + */ + while( sc->sent < sc->send_len ) + brl1_send_chars( sc ); + } + } + else { + sc->send_in_use = 1; + } + *send_ptr++ = BRL1_FLAG_CH; + *send_ptr++ = type_and_subch; + pkt_len += 2; + crc = crc16_calc( crc, type_and_subch ); + + /* limit number of characters accepted to max payload size */ + if( len > (BRL1_QSIZE - 1) ) + len = (BRL1_QSIZE - 1); + + /* copy in the message buffer (inserting PPP + * framing info where necessary) + */ + for( index = 0; index < len; index++ ) { + + switch( *msg ) { + + case BRL1_FLAG_CH: + *send_ptr++ = BRL1_ESC_CH; + *send_ptr++ = (*msg) ^ BRL1_XOR_CH; + pkt_len += 2; + break; + + case BRL1_ESC_CH: + *send_ptr++ = BRL1_ESC_CH; + *send_ptr++ = (*msg) ^ BRL1_XOR_CH; + pkt_len += 2; + break; + + default: + *send_ptr++ = *msg; + pkt_len++; + } + crc = crc16_calc( crc, *msg ); + msg++; + } + crc ^= 0xffff; + + for( index = 0; index < sizeof(crc); index++ ) { + char crc_char = (char)(crc & 0x00FF); + if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { + *send_ptr++ = BRL1_ESC_CH; + pkt_len++; + crc_char ^= BRL1_XOR_CH; + } + *send_ptr++ = crc_char; + pkt_len++; + crc >>= 8; + } + + *send_ptr++ = BRL1_FLAG_CH; + pkt_len++; + + sc->send_len = pkt_len; + sc->sent = 0; + + do { + brl1_send_chars( sc ); + } while( (sc->sent < sc->send_len) && wait ); + + if( sc->sent == sc->send_len ) { + /* success! release the send buffer */ + sc->send_in_use = 0; + } + else if( !wait ) { + /* enable low-water interrupts so buffer will be drained */ + uart_enable_xmit_intr(sc); + } + L1SC_SEND_UNLOCK(sc, pl); + return len; +} + + +/* brl1_send_cont is intended to be called as an interrupt service + * routine. It sends until the UART won't accept any more characters, + * or until an error is encountered (in which case we surrender the + * send buffer and give up trying to send the packet). Once the + * last character in the packet has been sent, this routine releases + * the send buffer and calls any previously-registered "low-water" + * output routines. + */ +int +brl1_send_cont( l1sc_t *sc ) +{ + int pl; + int done = 0; + brl1_notif_t callups[BRL1_NUM_SUBCHANS]; + brl1_notif_t *callup; + brl1_sch_t *subch; + int index; + + L1SC_SEND_LOCK(sc, pl); + brl1_send_chars( sc ); + done = (sc->sent == sc->send_len); + if( done ) { + + sc->send_in_use = 0; + uart_disable_xmit_intr(sc); + + /* collect pointers to callups *before* unlocking */ + subch = sc->subch; + callup = callups; + for( index = 0; index < BRL1_NUM_SUBCHANS; index++ ) { + *callup = subch->tx_notify; + subch++; + callup++; + } + } + L1SC_SEND_UNLOCK(sc, pl); + + if( done ) { + /* call any upper layer that's asked for low-water notification */ + callup = callups; + for( index = 0; index < BRL1_NUM_SUBCHANS; index++ ) { + if( *callup ) + (*(*callup))( sc, index ); + callup++; + } + } + return 0; +} + + +/* internal function -- used by brl1_receive to read a character + * from the uart and check whether errors occurred in the process. + */ +static int +read_uart( l1sc_t *sc, int *c, int *result ) +{ + *c = sc->getc_f( sc ); + + /* no character is available */ + if( *c == UART_NO_CHAR ) { + *result = BRL1_NO_MESSAGE; + return 0; + } + + /* some error in UART */ + if( *c < 0 ) { + *result = BRL1_LINK; + return 0; + } + + /* everything's fine */ + *result = BRL1_VALID; + return 1; +} + + +/* + * brl1_receive + * + * This function reads a Bedrock-L1 protocol packet into the l1sc_t + * response buffer. + * + * The operation of this function can be expressed as a finite state + * machine: + * + +START STATE INPUT TRANSITION +========================================================== +BRL1_IDLE (reset or error) flag BRL1_FLAG + other BRL1_IDLE@ + +BRL1_FLAG (saw a flag (0x7e)) flag BRL1_FLAG + escape BRL1_IDLE@ + header byte BRL1_HDR + other BRL1_IDLE@ + +BRL1_HDR (saw a type/subch byte)(see below) BRL1_BODY + BRL1_HDR + +BRL1_BODY (reading packet body) flag BRL1_FLAG + escape BRL1_ESC + other BRL1_BODY + +BRL1_ESC (saw an escape (0x7d)) flag BRL1_FLAG@ + escape BRL1_IDLE@ + other BRL1_BODY +========================================================== + +"@" denotes an error transition. + + * The BRL1_HDR state is a transient state which doesn't read input, + * but just provides a way in to code which decides to whom an + * incoming packet should be directed. + * + * brl1_receive can be used to poll for input from the L1, or as + * an interrupt service routine. It reads as much data as is + * ready from the junk bus UART and places into the appropriate + * input queues according to subchannel. The header byte is + * stripped from console-type data, but is retained for message- + * type data (L1 responses). A length byte will also be + * prepended to message-type packets. + * + * This routine is non-blocking; if the caller needs to block + * for input, it must call brl1_receive in a loop. + * + * brl1_receive returns when there is no more input, the queue + * for the current incoming message is full, or there is an + * error (parity error, bad header, bad CRC, etc.). + */ + +#define STATE_SET(l,s) ((l)->brl1_state = (s)) +#define STATE_GET(l) ((l)->brl1_state) + +#define LAST_HDR_SET(l,h) ((l)->brl1_last_hdr = (h)) +#define LAST_HDR_GET(l) ((l)->brl1_last_hdr) + +#define SEQSTAMP_INCR(l) +#define SEQSTAMP_GET(l) + +#define VALID_HDR(c) \ + ( SUBCH((c)) <= SC_CONS_SYSTEM \ + ? PKT_TYPE((c)) == BRL1_REQUEST \ + : ( PKT_TYPE((c)) == BRL1_RESPONSE || \ + PKT_TYPE((c)) == BRL1_EVENT ) ) + +#define IS_TTY_PKT(l) \ + ( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 ) + + +int +brl1_receive( l1sc_t *sc ) +{ + int result; /* value to be returned by brl1_receive */ + int c; /* most-recently-read character */ + int pl; /* priority level for UART receive lock */ + int done; /* set done to break out of recv loop */ + sc_cq_t *q; /* pointer to queue we're working with */ + + result = BRL1_NO_MESSAGE; + + L1SC_RECV_LOCK( sc, pl ); + L1_CONS_HW_LOCK( sc ); + + done = 0; + while( !done ) + { + switch( STATE_GET(sc) ) + { + + case BRL1_IDLE: + /* Initial or error state. Waiting for a flag character + * to resynchronize with the L1. + */ + + if( !read_uart( sc, &c, &result ) ) { + + /* error reading uart */ + done = 1; + continue; + } + + if( c == BRL1_FLAG_CH ) { + /* saw a flag character */ + STATE_SET( sc, BRL1_FLAG ); + continue; + } + break; + + case BRL1_FLAG: + /* One or more flag characters have been read; look for + * the beginning of a packet (header byte). + */ + + if( !read_uart( sc, &c, &result ) ) { + + /* error reading uart */ + if( c != UART_NO_CHAR ) + STATE_SET( sc, BRL1_IDLE ); + + done = 1; + continue; + } + + if( c == BRL1_FLAG_CH ) { + /* multiple flags are OK */ + continue; + } + + if( !VALID_HDR( c ) ) { + /* if c isn't a flag it should have been + * a valid header, so we have an error + */ + result = BRL1_PROTOCOL; + STATE_SET( sc, BRL1_IDLE ); + done = 1; + continue; + } + + /* we have a valid header byte */ + LAST_HDR_SET( sc, c ); + STATE_SET( sc, BRL1_HDR ); + + break; + + case BRL1_HDR: + /* A header byte has been read. Do some bookkeeping. */ + q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; + ASSERT(q); + + if( !IS_TTY_PKT(sc) ) { + /* if this is an event or command response rather + * than console I/O, we need to reserve a couple + * of extra spaces in the queue for the header + * byte and a length byte; if we can't, stay in + * the BRL1_HDR state. + */ + if( cq_room( q ) < 2 ) { + result = BRL1_FULL_Q; + done = 1; + continue; + } + cq_tent_add( q, 0 ); /* reserve length byte */ + cq_tent_add( q, LAST_HDR_GET( sc ) ); /* record header byte */ + } + STATE_SET( sc, BRL1_BODY ); + + break; + + case BRL1_BODY: + /* A header byte has been read. We are now attempting + * to receive the packet body. + */ + + q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; + ASSERT(q); + + /* if the queue we want to write into is full, don't read from + * the uart (this provides backpressure to the L1 side) + */ + if( cq_tent_full( q ) ) { + result = BRL1_FULL_Q; + done = 1; + continue; + } + + if( !read_uart( sc, &c, &result ) ) { + + /* error reading uart */ + if( c != UART_NO_CHAR ) + STATE_SET( sc, BRL1_IDLE ); + done = 1; + continue; + } + + if( c == BRL1_ESC_CH ) { + /* prepare to unescape the next character */ + STATE_SET( sc, BRL1_ESC ); + continue; + } + + if( c == BRL1_FLAG_CH ) { + /* flag signifies the end of a packet */ + + unsigned short crc; /* holds the crc as we calculate it */ + int i; /* index variable */ + brl1_sch_t *subch; /* subchannel for received packet */ + int sch_pl; /* cookie for subchannel lock */ + brl1_notif_t callup; /* "data ready" callup */ + + /* whatever else may happen, we've seen a flag and we're + * starting a new packet + */ + STATE_SET( sc, BRL1_FLAG ); + SEQSTAMP_INCR(sc); /* bump the packet sequence counter */ + + /* if the packet body has less than 2 characters, + * it can't be a well-formed packet. Discard it. + */ + if( cq_tent_len( q ) < /* 2 + possible length byte */ + (2 + (IS_TTY_PKT(sc) ? 0 : 1)) ) + { + result = BRL1_PROTOCOL; + cq_discard_tent( q ); + STATE_SET( sc, BRL1_FLAG ); + done = 1; + continue; + } + + /* check CRC */ + + /* accumulate CRC, starting with the header byte and + * ending with the transmitted CRC. This should + * result in a known good value. + */ + crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) ); + for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE; + i != q->tent_next; + i = (i + 1) % BRL1_QSIZE ) + { + crc = crc16_calc( crc, q->buf[i] ); + } + + /* verify the caclulated crc against the "good" crc value; + * if we fail, discard the bad packet and return an error. + */ + if( crc != (unsigned short)GOOD_CRC ) { + result = BRL1_CRC; + cq_discard_tent( q ); + STATE_SET( sc, BRL1_FLAG ); + done = 1; + continue; + } + + /* so the crc check was ok. Now we discard the CRC + * from the end of the received bytes. + */ + q->tent_next += (BRL1_QSIZE - 2); + q->tent_next %= BRL1_QSIZE; + + /* get the subchannel and lock it */ + subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]); + SUBCH_DATA_LOCK( subch, sch_pl ); + + /* if this isn't a console packet, we need to record + * a length byte + */ + if( !IS_TTY_PKT(sc) ) { + q->buf[q->ipos] = cq_tent_len( q ) - 1; + } + + /* record packet for posterity */ + cq_commit_tent( q ); + result = BRL1_VALID; + + /* notify subchannel owner that there's something + * on the queue for them + */ + atomicAddInt( &(subch->packet_arrived), 1); + callup = subch->rx_notify; + SUBCH_DATA_UNLOCK( subch, sch_pl ); + + if( callup ) { + L1_CONS_HW_UNLOCK( sc ); + L1SC_RECV_UNLOCK( sc, pl ); + (*callup)( sc, SUBCH(LAST_HDR_GET(sc)) ); + L1SC_RECV_LOCK( sc, pl ); + L1_CONS_HW_LOCK( sc ); + } + continue; /* go back for more! */ + } + + /* none of the special cases applied; we've got a normal + * body character + */ + cq_tent_add( q, c ); + + break; + + case BRL1_ESC: + /* saw an escape character. The next character will need + * to be unescaped. + */ + + q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp; + ASSERT(q); + + /* if the queue we want to write into is full, don't read from + * the uart (this provides backpressure to the L1 side) + */ + if( cq_tent_full( q ) ) { + result = BRL1_FULL_Q; + done = 1; + continue; + } + + if( !read_uart( sc, &c, &result ) ) { + + /* error reading uart */ + if( c != UART_NO_CHAR ) { + cq_discard_tent( q ); + STATE_SET( sc, BRL1_IDLE ); + } + done = 1; + continue; + } + + if( c == BRL1_FLAG_CH ) { + /* flag after escape is an error */ + STATE_SET( sc, BRL1_FLAG ); + cq_discard_tent( q ); + result = BRL1_PROTOCOL; + done = 1; + continue; + } + + if( c == BRL1_ESC_CH ) { + /* two consecutive escapes is an error */ + STATE_SET( sc, BRL1_IDLE ); + cq_discard_tent( q ); + result = BRL1_PROTOCOL; + done = 1; + continue; + } + + /* otherwise, we've got a character that needs + * to be unescaped + */ + cq_tent_add( q, (c ^ BRL1_XOR_CH) ); + STATE_SET( sc, BRL1_BODY ); + + break; + + } /* end of switch( STATE_GET(sc) ) */ + } /* end of while(!done) */ + + L1_CONS_HW_UNLOCK( sc ); + L1SC_RECV_UNLOCK(sc, pl); + + return result; +} + + +/* brl1_init initializes the Bedrock/L1 protocol layer. This includes + * zeroing out the send and receive state information. + */ + +void +brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) +{ + int i; + brl1_sch_t *subch; + + bzero( sc, sizeof( *sc ) ); + sc->nasid = nasid; + sc->uart = uart; + sc->getc_f = (uart == BRL1_LOCALUART ? uart_getc : rtr_uart_getc); + sc->putc_f = (uart == BRL1_LOCALUART ? uart_putc : rtr_uart_putc); + sc->sol = 1; + subch = sc->subch; + + /* initialize L1 subchannels + */ + + /* assign processor TTY channels */ + for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) { + subch->use = BRL1_SUBCH_RSVD; + subch->packet_arrived = 0; + spinlock_init( &(subch->data_lock), NULL ); + sv_init( &(subch->arrive_sv), SV_FIFO, NULL ); + subch->tx_notify = NULL; + /* (for now, drop elscuart packets in the kernel) */ + subch->rx_notify = brl1_discard_packet; + subch->iqp = &sc->garbage_q; + } + + /* assign system TTY channel (first free subchannel after each + * processor's individual TTY channel has been assigned) + */ + subch->use = BRL1_SUBCH_RSVD; + subch->packet_arrived = 0; + spinlock_init( &(subch->data_lock), NULL ); + sv_init( &(subch->arrive_sv), SV_FIFO, NULL ); + subch->tx_notify = NULL; + if( sc->uart == BRL1_LOCALUART ) { + subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, + NASID_TO_COMPACT_NODEID(nasid) ); + ASSERT( subch->iqp ); + cq_init( subch->iqp ); + subch->rx_notify = NULL; + } + else { + /* we shouldn't be getting console input from remote UARTs */ + subch->iqp = &sc->garbage_q; + subch->rx_notify = brl1_discard_packet; + } + subch++; i++; + + /* "reserved" subchannels (0x05-0x0F); for now, throw away + * incoming packets + */ + for( ; i < 0x10; i++, subch++ ) { + subch->use = BRL1_SUBCH_FREE; + subch->packet_arrived = 0; + subch->tx_notify = NULL; + subch->rx_notify = brl1_discard_packet; + subch->iqp = &sc->garbage_q; + } + + /* remaining subchannels are free */ + for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) { + subch->use = BRL1_SUBCH_FREE; + subch->packet_arrived = 0; + subch->tx_notify = NULL; + subch->rx_notify = brl1_discard_packet; + subch->iqp = &sc->garbage_q; + } + + /* initialize synchronization structures + */ + spinlock_init( &(sc->send_lock), NULL ); + spinlock_init( &(sc->recv_lock), NULL ); + spinlock_init( &(sc->subch_lock), NULL ); + + if( sc->uart == BRL1_LOCALUART ) { + uart_init( sc, UART_BAUD_RATE ); + } + else { + rtr_uart_init( sc, UART_BAUD_RATE ); + } + + /* Set up remaining fields using L1 command functions-- elsc_module_get + * to read the module id, elsc_debug_get to see whether or not we're + * in verbose mode. + */ + { + extern int elsc_module_get(l1sc_t *); + + sc->modid = elsc_module_get( sc ); + sc->modid = + (sc->modid < 0 ? INVALID_MODULE : sc->modid); + + sc->verbose = 1; + } +} + + +/********************************************************************* + * These are interrupt-related functions used in the kernel to service + * the L1. + */ + +/* + * brl1_intrd is the function which is called in a loop by the + * xthread that services L1 interrupts. + */ +#ifdef IRIX +void +brl1_intrd( struct eframe_s *ep ) +{ + u_char isr_reg; + l1sc_t *sc = get_elsc(); + + isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR); + + while( isr_reg & (ISR_RxRDY | ISR_TxRDY) ) { + + if( isr_reg & ISR_RxRDY ) { + brl1_receive(sc); + } + if( (isr_reg & ISR_TxRDY) || + (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) + { + brl1_send_cont(sc); + } + isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR); + } + + /* uart interrupts were blocked at bedrock when the the interrupt + * was initially answered; reenable them now + */ + intr_unblock_bit( sc->intr_cpu, UART_INTR ); + ep = ep; /* placate the compiler */ +} +#endif + + + +/* brl1_intr is called directly from the uart interrupt; after it runs, the + * interrupt "daemon" xthread is signalled to continue. + */ +#ifdef IRIX +void +brl1_intr( struct eframe_s *ep ) +{ + /* Disable the UART interrupt, giving the xthread time to respond. + * When the daemon (xthread) finishes doing its thing, it will + * unblock the interrupt. + */ + intr_block_bit( get_elsc()->intr_cpu, UART_INTR ); + ep = ep; /* placate the compiler */ +} + + +/* set up uart interrupt handling for this node's uart + */ +void +brl1_connect_intr( l1sc_t *sc ) +{ + cpuid_t last_cpu; + + sc->intr_cpu = nodepda->node_first_cpu; + + if( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, + (intr_func_t)brl1_intrd, 0, + (intr_func_t)brl1_intr) ) + cmn_err(CE_PANIC, "brl1_connect_intr: Can't connect UART interrupt."); + + uart_enable_recv_intr( sc ); +} +#endif /* IRIX */ + +#ifdef SABLE +/* this function is called periodically to generate fake interrupts + * and allow brl1_intrd to send/receive characters + */ +void +hubuart_service( void ) +{ + l1sc_t *sc = get_elsc(); + /* note that we'll lose error state by reading the lsr_reg. + * This is probably ok in the frictionless domain of sable. + */ + int lsr_reg; + nasid_t nasid = sc->nasid; + lsr_reg = READ_L1_UART_REG( nasid, REG_LSR ); + if( lsr_reg & (LSR_RCA | LSR_XSRE) ) { + REMOTE_HUB_PI_SEND_INTR(0, 0, UART_INTR); + } +} +#endif /* SABLE */ + + +/********************************************************************* + * The following function allows the kernel to "go around" the + * uninitialized l1sc structure to allow console output during + * early system startup. + */ + +/* These are functions to use from serial_in/out when in protocol + * mode to send and receive uart control regs. + */ +void +brl1_send_control(int offset, int value) +{ + nasid_t nasid = get_nasid(); + WRITE_L1_UART_REG(nasid, offset, value); +} + +int +brl1_get_control(int offset) +{ + nasid_t nasid = get_nasid(); + return(READ_L1_UART_REG(nasid, offset)); +} + +#define PUTCHAR(ch) \ + { \ + while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE) ); \ + WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \ + } + +int +brl1_send_console_packet( char *str, int len ) +{ + int sent = len; + char crc_char; + unsigned short crc = INIT_CRC; + nasid_t nasid = get_nasid(); + + PUTCHAR( BRL1_FLAG_CH ); + PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM ); + crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) ); + + while( len ) { + + if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) { + PUTCHAR( BRL1_ESC_CH ); + PUTCHAR( (*str) ^ BRL1_XOR_CH ); + } + else { + PUTCHAR( *str ); + } + + crc = crc16_calc( crc, *str ); + + str++; len--; + } + + crc ^= 0xffff; + crc_char = crc & 0xff; + if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { + crc_char ^= BRL1_XOR_CH; + PUTCHAR( BRL1_ESC_CH ); + } + PUTCHAR( crc_char ); + crc_char = (crc >> 8) & 0xff; + if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) { + crc_char ^= BRL1_XOR_CH; + PUTCHAR( BRL1_ESC_CH ); + } + PUTCHAR( crc_char ); + PUTCHAR( BRL1_FLAG_CH ); + + return sent - len; +} + + +/********************************************************************* + * l1_cons functions + * + * These allow the L1 to act as the system console. They're intended + * to abstract away most of the br/l1 internal details from the + * _L1_cons_* functions (in the prom-- see "l1_console.c") and + * l1_* functions (in the kernel-- see "sio_l1.c") that they support. + * + */ + +int +l1_cons_poll( l1sc_t *sc ) +{ + /* in case this gets called before the l1sc_t structure for the module_t + * struct for this node is initialized (i.e., if we're called with a + * zero l1sc_t pointer)... + */ + if( !sc ) { + return 0; + } + + if( sc->subch[SC_CONS_SYSTEM].packet_arrived ) { + return 1; + } + + brl1_receive( sc ); + + if( sc->subch[SC_CONS_SYSTEM].packet_arrived ) { + return 1; + } + return 0; +} + + +/* pull a character off of the system console queue (if one is available) + */ +int +l1_cons_getc( l1sc_t *sc ) +{ + int c; +#ifdef SPINLOCKS_WORK + int pl; +#endif + brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]); + sc_cq_t *q = subch->iqp; + + if( !l1_cons_poll( sc ) ) { + return 0; + } + + SUBCH_DATA_LOCK( subch, pl ); + if( cq_empty( q ) ) { + subch->packet_arrived = 0; + SUBCH_DATA_UNLOCK( subch, pl ); + return 0; + } + cq_rem( q, c ); + if( cq_empty( q ) ) + subch->packet_arrived = 0; + SUBCH_DATA_UNLOCK( subch, pl ); + + return c; +} + + +/* initialize the system console subchannel + */ +void +l1_cons_init( l1sc_t *sc ) +{ +#ifdef SPINLOCKS_WORK + int pl; +#endif + brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]); + + SUBCH_DATA_LOCK( subch, pl ); + subch->packet_arrived = 0; + cq_init( subch->iqp ); + SUBCH_DATA_UNLOCK( subch, pl ); +} + + +/* + * Write a message to the L1 on the system console subchannel. + * + * Danger: don't use a non-zero value for the wait parameter unless you're + * someone important (like a kernel error message). + */ +int +l1_cons_write( l1sc_t *sc, char *msg, int len, int wait ) +{ + return( brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait ) ); +} + + +/* + * Read as many characters from the system console receive queue as are + * available there (up to avail bytes). + */ +int +l1_cons_read( l1sc_t *sc, char *buf, int avail ) +{ + int pl; + int before_wrap, after_wrap; + brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]); + sc_cq_t *q = subch->iqp; + + if( !(subch->packet_arrived) ) + return 0; + + SUBCH_DATA_LOCK( subch, pl ); + if( q->opos > q->ipos ) { + before_wrap = BRL1_QSIZE - q->opos; + if( before_wrap >= avail ) { + before_wrap = avail; + after_wrap = 0; + } + else { + avail -= before_wrap; + after_wrap = q->ipos; + if( after_wrap > avail ) + after_wrap = avail; + } + } + else { + before_wrap = q->ipos - q->opos; + if( before_wrap > avail ) + before_wrap = avail; + after_wrap = 0; + } + + + BCOPY( q->buf + q->opos, buf, before_wrap ); + if( after_wrap ) + BCOPY( q->buf, buf + before_wrap, after_wrap ); + q->opos = ((q->opos + before_wrap + after_wrap) % BRL1_QSIZE); + + subch->packet_arrived = 0; + SUBCH_DATA_UNLOCK( subch, pl ); + + return( before_wrap + after_wrap ); +} + + +/* + * Install a callback function for the system console subchannel + * to allow an upper layer to be notified when the send buffer + * has been emptied. + */ +void +l1_cons_tx_notif( l1sc_t *sc, brl1_notif_t func ) +{ + subch_set_tx_notify( sc, SC_CONS_SYSTEM, func ); +} + + +/* + * Install a callback function for the system console subchannel + * to allow an upper layer to be notified when a packet has been + * received. + */ +void +l1_cons_rx_notif( l1sc_t *sc, brl1_notif_t func ) +{ + subch_set_rx_notify( sc, SC_CONS_SYSTEM, func ); +} + + + + +/********************************************************************* + * The following functions and definitions implement the "message"- + * style interface to the L1 system controller. + * + * Note that throughout this file, "sc" generally stands for "system + * controller", while "subchannels" tend to be represented by + * variables with names like subch or ch. + * + */ + +#ifdef L1_DEBUG +#define L1_DBG_PRF(x) printf x +#else +#define L1_DBG_PRF(x) +#endif + +/* sc_data_ready is called to signal threads that are blocked on + * l1 input. + */ +void +sc_data_ready( l1sc_t *sc, int ch ) +{ + brl1_sch_t *subch = &(sc->subch[ch]); + sv_signal( &(subch->arrive_sv) ); +} + +/* sc_open reserves a subchannel to send a request to the L1 (the + * L1's response will arrive on the same channel). The number + * returned by sc_open is the system controller subchannel + * acquired. + */ +int +sc_open( l1sc_t *sc, uint target ) +{ + /* The kernel version implements a locking scheme to arbitrate + * subchannel assignment. + */ + int ch; + int pl; + brl1_sch_t *subch; + + SUBCH_LOCK( sc, pl ); + + /* Look for a free subchannel. Subchannels 0-15 are reserved + * for other purposes. + */ + for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; + ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) { + if( subch->use == BRL1_SUBCH_FREE ) + break; + } + + if( ch == BRL1_NUM_SUBCHANS ) { + /* there were no subchannels available! */ + SUBCH_UNLOCK( sc, pl ); + return SC_NSUBCH; + } + + subch->use = BRL1_SUBCH_RSVD; + SUBCH_UNLOCK( sc, pl ); + + subch->packet_arrived = 0; + subch->target = target; + sv_init( &(subch->arrive_sv), SV_FIFO, NULL ); + spinlock_init( &(subch->data_lock), NULL ); + subch->tx_notify = NULL; + subch->rx_notify = sc_data_ready; + subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, + NASID_TO_COMPACT_NODEID(sc->nasid) ); + ASSERT( subch->iqp ); + cq_init( subch->iqp ); + + return ch; +} + + +/* sc_close frees a Bedrock<->L1 subchannel. + */ +int +sc_close( l1sc_t *sc, int ch ) +{ + brl1_sch_t *subch; + int pl; + + SUBCH_LOCK( sc, pl ); + subch = &(sc->subch[ch]); + if( subch->use != BRL1_SUBCH_RSVD ) { + /* we're trying to close a subchannel that's not open */ + return SC_NOPEN; + } + + subch->packet_arrived = 0; + subch->use = BRL1_SUBCH_FREE; + + sv_broadcast( &(subch->arrive_sv) ); + sv_destroy( &(subch->arrive_sv) ); + spinlock_destroy( &(subch->data_lock) ); + + ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) ); + kmem_free( subch->iqp, sizeof(sc_cq_t) ); + subch->iqp = &sc->garbage_q; + + SUBCH_UNLOCK( sc, pl ); + + return SC_SUCCESS; +} + + +/* sc_construct_msg builds a bedrock-to-L1 request in the supplied + * buffer. Returns the length of the message. The + * safest course when passing a buffer to be filled in is to use + * BRL1_QSIZE as the buffer size. + * + * Command arguments are passed as type/argument pairs, i.e., to + * pass the number 5 as an argument to an L1 command, call + * sc_construct_msg as follows: + * + * char msg[BRL1_QSIZE]; + * msg_len = sc_construct_msg( msg, + * BRL1_QSIZE, + * target_component, + * L1_ADDR_TASK_BOGUSTASK, + * L1_BOGUSTASK_REQ_BOGUSREQ, + * 2, + * L1_ARG_INT, 5 ); + * + * To pass an additional ASCII argument, you'd do the following: + * + * char *str; + * ... str points to a null-terminated ascii string ... + * msg_len = sc_construct_msg( msg, + * BRL1_QSIZE, + * target_component, + * L1_ADDR_TASK_BOGUSTASK, + * L1_BOGUSTASK_REQ_BOGUSREQ, + * 4, + * L1_ARG_INT, 5, + * L1_ARG_ASCII, str ); + * + * Finally, arbitrary data of unknown type is passed using the argtype + * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g. + * + * msg_len = sc_construct_msg( msg, + * BRL1_QSIZE, + * target_component, + * L1_ADDR_TASK_BOGUSTASK, + * L1_BOGUSTASK_REQ_BOGUSREQ, + * 3, + * L1_ARG_UNKNOWN, 32, bufptr ); + * + * ...passes 32 bytes of data starting at bufptr. Note that no string or + * "unknown"-type argument should be long enough to overflow the message + * buffer. + * + * To construct a message for an L1 command that requires no arguments, + * you'd use the following: + * + * msg_len = sc_construct_msg( msg, + * BRL1_QSIZE, + * target_component, + * L1_ADDR_TASK_BOGUSTASK, + * L1_BOGUSTASK_REQ_BOGUSREQ, + * 0 ); + * + * The final 0 means "no varargs". Notice that this parameter is used to hold + * the number of additional arguments to sc_construct_msg, _not_ the actual + * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII] + * type argument, and 3 per L1_ARG_UNKOWN type argument). A call to construct + * an L1 command which required three integer arguments and two arguments of + * some arbitrary (unknown) type would pass 12 as the value for this parameter. + * + * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth + * between byte arrays and four-byte big-endian integers. Depending on the + * system controller connection and endianness of future architectures, some + * rewriting might be necessary. + */ +int +sc_construct_msg( l1sc_t *sc, /* system controller struct */ + int ch, /* subchannel for this message */ + char *msg, /* message buffer */ + int msg_len, /* size of message buffer */ + l1addr_t addr_task, /* target system controller task */ + short req_code, /* 16-bit request code */ + int req_nargs, /* # of arguments (varargs) passed */ + ... ) /* any additional parameters */ +{ + uint32_t buf32; /* 32-bit buffer used to bounce things around */ + void *bufptr; /* used to hold command argument addresses */ + va_list al; /* variable argument list */ + int index; /* current index into msg buffer */ + int argno; /* current position in varargs list */ + int l1_argno; /* running total of arguments to l1 */ + int l1_arg_t; /* argument type/length */ + int l1_argno_byte; /* offset of argument count byte */ + + index = argno = 0; + + /* set up destination address */ + if( (msg_len -= sizeof( buf32 )) < 0 ) + return -1; + L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task ); + COPY_INT_TO_BUFFER(msg, index, buf32); + + /* copy request code */ + if( (msg_len -= 2) < 0 ) + return( -1 ); + msg[index++] = ((req_code >> 8) & 0xff); + msg[index++] = (req_code & 0xff); + + if( !req_nargs ) { + return index; + } + + /* reserve a byte for the argument count */ + if( (msg_len -= 1) < 0 ) + return( -1 ); + l1_argno_byte = index++; + l1_argno = 0; + + /* copy additional arguments */ + va_start( al, req_nargs ); + while( argno < req_nargs ) { + l1_argno++; + l1_arg_t = va_arg( al, int ); argno++; + switch( l1_arg_t ) + { + case L1_ARG_INT: + if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 ) + return( -1 ); + msg[index++] = L1_ARG_INT; + buf32 = (unsigned)va_arg( al, int ); argno++; + COPY_INT_TO_BUFFER(msg, index, buf32); + break; + + case L1_ARG_ASCII: + bufptr = va_arg( al, char* ); argno++; + if( (msg_len -= (strlen( bufptr ) + 2)) < 0 ) + return( -1 ); + msg[index++] = L1_ARG_ASCII; + strcpy( (char *)&(msg[index]), (char *)bufptr ); + index += (strlen( bufptr ) + 1); /* include terminating null */ + break; + + case L1_ARG_UNKNOWN: + { + int arglen; + + arglen = va_arg( al, int ); argno++; + bufptr = va_arg( al, void* ); argno++; + if( (msg_len -= (arglen + 1)) < 0 ) + return( -1 ); + msg[index++] = L1_ARG_UNKNOWN | arglen; + BCOPY( bufptr, &(msg[index]), arglen ); + index += arglen; + break; + } + + default: /* unhandled argument type */ + return -1; + } + } + + va_end( al ); + msg[l1_argno_byte] = l1_argno; + + return index; +} + + + +/* sc_interpret_resp verifies an L1 response to a bedrock request, and + * breaks the response data up into the constituent parts. If the + * response message indicates error, or if a mismatch is found in the + * expected number and type of arguments, an error is returned. The + * arguments to this function work very much like the arguments to + * sc_construct_msg, above, except that L1_ARG_INTs must be followed + * by a _pointer_ to an integer that can be filled in by this function. + */ +int +sc_interpret_resp( char *resp, /* buffer received from L1 */ + int resp_nargs, /* number of _varargs_ passed in */ + ... ) +{ + uint32_t buf32; /* 32-bit buffer used to bounce things around */ + void *bufptr; /* used to hold response field addresses */ + va_list al; /* variable argument list */ + int index; /* current index into response buffer */ + int argno; /* current position in varargs list */ + int l1_fldno; /* number of resp fields received from l1 */ + int l1_fld_t; /* field type/length */ + + index = argno = 0; + +#if defined(L1_DEBUG) +#define DUMP_RESP \ + { \ + int ix; \ + char outbuf[512]; \ + sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \ + for( ix = 0; ix < 16; ix++ ) { \ + sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] ); \ + } \ + printk( "%s\n", outbuf ); \ + } +#else +#define DUMP_RESP +#endif /* L1_DEBUG */ + + /* check response code */ + COPY_BUFFER_TO_INT(resp, index, buf32); + if( buf32 != L1_RESP_OK ) { + DUMP_RESP; + return buf32; + } + + /* get number of response fields */ + l1_fldno = resp[index++]; + + va_start( al, resp_nargs ); + + /* copy out response fields */ + while( argno < resp_nargs ) { + l1_fldno--; + l1_fld_t = va_arg( al, int ); argno++; + switch( l1_fld_t ) + { + case L1_ARG_INT: + if( resp[index++] != L1_ARG_INT ) { + /* type mismatch */ + va_end( al ); + DUMP_RESP; + return -1; + } + bufptr = va_arg( al, int* ); argno++; + COPY_BUFFER_TO_BUFFER(resp, index, bufptr); + break; + + case L1_ARG_ASCII: + if( resp[index++] != L1_ARG_ASCII ) { + /* type mismatch */ + va_end( al ); + DUMP_RESP; + return -1; + } + bufptr = va_arg( al, char* ); argno++; + strcpy( (char *)bufptr, (char *)&(resp[index]) ); + /* include terminating null */ + index += (strlen( &(resp[index]) ) + 1); + break; + + default: + if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN ) + { + int *arglen; + + arglen = va_arg( al, int* ); argno++; + bufptr = va_arg( al, void* ); argno++; + *arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff); + BCOPY( &(resp[index]), bufptr, *arglen ); + index += (*arglen); + } + + else { + /* unhandled type */ + va_end( al ); + DUMP_RESP; + return -1; + } + } + } + va_end( al ); + + if( (l1_fldno != 0) || (argno != resp_nargs) ) { + /* wrong number of arguments */ + DUMP_RESP; + return -1; + } + return 0; +} + + + + +/* sc_send takes as arguments a system controller struct, a + * buffer which contains a Bedrock<->L1 "request" message, + * the message length, and the subchannel (presumably obtained + * from an earlier invocation of sc_open) over which the + * message is to be sent. The final argument ("wait") indicates + * whether the send is to be performed synchronously or not. + * + * sc_send returns either zero or an error value. Synchronous sends + * (wait != 0) will not return until the data has actually been sent + * to the UART. Synchronous sends generally receive privileged + * treatment. The intent is that they be used sparingly, for such + * purposes as kernel printf's (the "ducons" routines). Run-of-the-mill + * console output and L1 requests should NOT use a non-zero value + * for wait. + */ +int +sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait ) +{ + char type_and_subch; + int result; + + if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) { + return SC_BADSUBCH; + } + + /* Verify that this is an open subchannel + */ + if( sc->subch[ch].use == BRL1_SUBCH_FREE ) + { + return SC_NOPEN; + } + + type_and_subch = (BRL1_REQUEST | ((u_char)ch)); + result = brl1_send( sc, msg, len, type_and_subch, wait ); + + /* If we sent as much as we asked to, return "ok". */ + if( result == len ) + return( SC_SUCCESS ); + + /* Or, if we sent less, than either the UART is busy or + * we're trying to send too large a packet anyway. + */ + else if( result >= 0 && result < len ) + return( SC_BUSY ); + + /* Or, if something else went wrong (result < 0), then + * return that error value. + */ + else + return( result ); +} + + + +/* subch_pull_msg pulls a message off the receive queue for subch + * and places it the buffer pointed to by msg. This routine should only + * be called when the caller already knows a message is available on the + * receive queue (and, in the kernel, only when the subchannel data lock + * is held by the caller). + */ +static void +subch_pull_msg( brl1_sch_t *subch, char *msg, int *len ) +{ + sc_cq_t *q; /* receive queue */ + int before_wrap, /* packet may be split into two different */ + after_wrap; /* pieces to acommodate queue wraparound */ + + /* pull message off the receive queue */ + q = subch->iqp; + + cq_rem( q, *len ); /* remove length byte and store */ + cq_discard( q ); /* remove type/subch byte and discard */ + + if ( *len > 0 ) + (*len)--; /* don't count type/subch byte in length returned */ + + if( (q->opos + (*len)) > BRL1_QSIZE ) { + before_wrap = BRL1_QSIZE - q->opos; + after_wrap = (*len) - before_wrap; + } + else { + before_wrap = (*len); + after_wrap = 0; + } + + BCOPY( q->buf + q->opos, msg, before_wrap ); + if( after_wrap ) { + BCOPY( q->buf, msg + before_wrap, after_wrap ); + q->opos = after_wrap; + } + else { + q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1)); + } + atomicAddInt( &(subch->packet_arrived), -1 ); +} + + +/* sc_recv_poll can be called as a blocking or non-blocking function; + * it attempts to pull a message off of the subchannel specified + * in the argument list (ch). + * + * The "block" argument, if non-zero, is interpreted as a timeout + * delay (to avoid permanent waiting). + */ + +int +sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ) +{ + int pl; /* lock cookie */ + int is_msg = 0; + brl1_sch_t *subch = &(sc->subch[ch]); + + rtc_time_t exp_time = rtc_time() + block; + + /* sanity check-- make sure this is an open subchannel */ + if( subch->use == BRL1_SUBCH_FREE ) + return( SC_NOPEN ); + + do { + + /* kick the next lower layer and see if it pulls anything in + */ + brl1_receive( sc ); + is_msg = subch->packet_arrived; + + } while( block && !is_msg && (rtc_time() < exp_time) ); + + if( !is_msg ) { + /* no message and we didn't care to wait for one */ + return( SC_NMSG ); + } + + SUBCH_DATA_LOCK( subch, pl ); + subch_pull_msg( subch, msg, len ); + SUBCH_DATA_UNLOCK( subch, pl ); + + return( SC_SUCCESS ); +} + + +/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking + * or non-blocking mode. Rather than polling until an appointed timeout, + * however, sc_recv_intr sleeps on a syncrhonization variable until a + * signal from the lower layer tells us that a packet has arrived. + * + * sc_recv_intr can't be used with remote (router) L1s. + */ +int +sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ) +{ + int pl; /* lock cookie */ + int is_msg = 0; + brl1_sch_t *subch = &(sc->subch[ch]); + + do { + SUBCH_DATA_LOCK(subch, pl); + is_msg = subch->packet_arrived; + if( !is_msg && block ) { + /* wake me when you've got something */ + subch->rx_notify = sc_data_ready; + sv_wait( &(subch->arrive_sv), 0, &(subch->data_lock), pl ); + if( subch->use == BRL1_SUBCH_FREE ) { + /* oops-- somebody closed our subchannel while we were + * sleeping! + */ + + /* no need to unlock since the channel's closed anyhow */ + return( SC_NOPEN ); + } + } + } while( !is_msg && block ); + + if( !is_msg ) { + /* no message and we didn't care to wait for one */ + SUBCH_DATA_UNLOCK( subch, pl ); + return( SC_NMSG ); + } + + subch_pull_msg( subch, msg, len ); + SUBCH_DATA_UNLOCK( subch, pl ); + + return( SC_SUCCESS ); +} + +/* sc_command implements a (blocking) combination of sc_send and sc_recv. + * It is intended to be the SN1 equivalent of SN0's "elsc_command", which + * issued a system controller command and then waited for a response from + * the system controller before returning. + * + * cmd points to the outgoing command; resp points to the buffer in + * which the response is to be stored. Both buffers are assumed to + * be the same length; if there is any doubt as to whether the + * response buffer is long enough to hold the L1's response, then + * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any + * bigger. + * + * Be careful using the same buffer for both cmd and resp; it could get + * hairy if there were ever an L1 command reqeuest that spanned multiple + * packets. (On the other hand, that would require some additional + * rewriting of the L1 command interface anyway.) + */ +#define __RETRIES 50 +#define __WAIT_SEND ( sc->uart != BRL1_LOCALUART ) +#define __WAIT_RECV 10000000 + + +int +sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ) +{ +#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL + return SC_NMSG; +#else + int result; + int retries; + + if ( IS_RUNNING_ON_SIMULATOR() ) + return SC_NMSG; + + retries = __RETRIES; + + while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) { + if( result == SC_BUSY ) { + retries--; + if( retries <= 0 ) + return result; + uart_delay(500); + } + else { + return result; + } + } + + /* block on sc_recv_* */ +#ifdef notyet + if( sc->uart == BRL1_LOCALUART ) { + return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) ); + } + else +#endif + { + return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) ); + } +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + +/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command + * used in situations where the kernel has a command that shouldn't be + * delayed until the send buffer clears. sc_command should be used instead + * under most circumstances. + */ +int +sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ) +{ +#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL + return SC_NMSG; +#else + int result; + + if ( IS_RUNNING_ON_SIMULATOR() ) + return SC_NMSG; + + if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) { + return result; + } + + return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) ); +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + + +/* sc_poll checks the queue corresponding to the given + * subchannel to see if there's anything available. If + * not, it kicks the brl1 layer and then checks again. + * + * Returns 1 if input is available on the given queue, + * 0 otherwise. + */ +int +sc_poll( l1sc_t *sc, int ch ) +{ + brl1_sch_t *subch = &(sc->subch[ch]); + + if( subch->packet_arrived ) + return 1; + + brl1_receive( sc ); + + if( subch->packet_arrived ) + return 1; + + return 0; +} + +/* for now, sc_init just calls brl1_init + */ +void +sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ) +{ + if ( !IS_RUNNING_ON_SIMULATOR() ) + brl1_init( sc, nasid, uart ); +} + +/* sc_dispatch_env_event handles events sent from the system control + * network's environmental monitor tasks. + */ +static void +sc_dispatch_env_event( uint code, int argc, char *args, int maxlen ) +{ + int j, i = 0; + uint32_t ESPcode; + + switch( code ) { + /* for now, all codes do the same thing: grab two arguments + * and print a cmn_err_tag message */ + default: + /* check number of arguments */ + if( argc != 2 ) { + L1_DBG_PRF(( "sc_dispatch_env_event: " + "expected 2 arguments, got %d\n", argc )); + return; + } + + /* get ESP code (integer argument) */ + if( args[i++] != L1_ARG_INT ) { + L1_DBG_PRF(( "sc_dispatch_env_event: " + "expected integer argument\n" )); + return; + } + /* WARNING: highly endian */ + COPY_BUFFER_TO_INT(args, i, ESPcode); + + /* verify string argument */ + if( args[i++] != L1_ARG_ASCII ) { + L1_DBG_PRF(( "sc_dispatch_env_event: " + "expected an ASCII string\n" )); + return; + } + for( j = i; j < maxlen; j++ ) { + if( args[j] == '\0' ) break; /* found string termination */ + } + if( j == maxlen ) { + j--; + L1_DBG_PRF(( "sc_dispatch_env_event: " + "message too long-- truncating\n" )); + } + + /* strip out trailing cr/lf */ + for( ; + j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); + j-- ); + args[j] = '\0'; + + /* strip out leading cr/lf */ + for( ; + i < j && ((args[i] == 0xd) || (args[i] == 0xa)); + i++ ); + + /* write the event to syslog */ +#ifdef IRIX + cmn_err_tag( ESPcode, CE_WARN, &(args[i]) ); +#endif + } +} + + +/* sc_event waits for events to arrive from the system controller, and + * prints appropriate messages to the syslog. + */ +static void +sc_event( l1sc_t *sc, int ch ) +{ + char event[BRL1_QSIZE]; + int i; + int result; + int event_len; + uint32_t ev_src; + uint32_t ev_code; + int ev_argc; + + while(1) { + + bzero( event, BRL1_QSIZE ); + + /* + * wait for an event + */ + result = sc_recv_intr( sc, ch, event, &event_len, 1 ); + if( result != SC_SUCCESS ) { + cmn_err( CE_WARN, "Error receiving sysctl event on nasid %d\n", + sc->nasid ); + } + else { + /* + * an event arrived; break it down into useful pieces + */ +#if defined(L1_DEBUG) && 0 + int ix; + printf( "Event packet received:\n" ); + for (ix = 0; ix < 64; ix++) { + printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)), + (event[ix] & ((uint64_t)0xf)) ); + if( (ix % 16) == 0xf ) printf( "\n" ); + } +#endif /* L1_DEBUG */ + + i = 0; + + /* get event source */ + COPY_BUFFER_TO_INT(event, i, ev_src); + COPY_BUFFER_TO_INT(event, i, ev_code); + + /* get arg count */ + ev_argc = (event[i++] & 0xffUL); + + /* dispatch events by task */ + switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT ) + { + case L1_ADDR_TASK_ENV: /* environmental monitor event */ + sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), + BRL1_QSIZE - i ); + break; + + default: /* unhandled task type */ + L1_DBG_PRF(( "Unhandled event type received from system " + "controllers: source task %x\n", + (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT + )); + } + } + + } +} + +/* sc_listen sets up a service thread to listen for incoming events. + */ +void +sc_listen( l1sc_t *sc ) +{ + int pl; + int result; + brl1_sch_t *subch; + + char msg[BRL1_QSIZE]; + int len; /* length of message being sent */ + int ch; /* system controller subchannel used */ + + extern int msc_shutdown_pri; + + /* grab the designated "event subchannel" */ + SUBCH_LOCK( sc, pl ); + subch = &(sc->subch[BRL1_EVENT_SUBCH]); + if( subch->use != BRL1_SUBCH_FREE ) { + SUBCH_UNLOCK( sc, pl ); + cmn_err( CE_WARN, "sysctl event subchannel in use! " + "Not monitoring sysctl events.\n" ); + return; + } + subch->use = BRL1_SUBCH_RSVD; + SUBCH_UNLOCK( sc, pl ); + + subch->packet_arrived = 0; + subch->target = BRL1_LOCALUART; + sv_init( &(subch->arrive_sv), SV_FIFO, NULL ); + spinlock_init( &(subch->data_lock), NULL ); + subch->tx_notify = NULL; + subch->rx_notify = sc_data_ready; + subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, + NASID_TO_COMPACT_NODEID(sc->nasid) ); + ASSERT( subch->iqp ); + cq_init( subch->iqp ); + +#ifdef LINUX_KERNEL_THREADS + /* set up a thread to listen for events */ + sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri, + KT_PS, (st_func_t *) sc_event, + (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 ); +#endif + + /* signal the L1 to begin sending events */ + bzero( msg, BRL1_QSIZE ); + ch = sc_open( sc, L1_ADDR_LOCAL ); + + if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_EVENT_SUBCH, 2, + L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 ) + { + sc_close( sc, ch ); + L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len )); + goto err_return; + } + + result = sc_command_kern( sc, ch, msg, msg, &len ); + if( result < 0 ) + { + sc_close( sc, ch ); + L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result )); + goto err_return; + } + + sc_close( sc, ch ); + + result = sc_interpret_resp( msg, 0 ); + if( result < 0 ) + { + L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result )); + goto err_return; + } + + /* everything went fine; just return */ + return; + +err_return: + /* there was a problem; complain */ + cmn_err( CE_WARN, "failed to set sysctl event-monitoring subchannel. " + "Sysctl events will not be monitored.\n" ); +} + + +/********************************************************************* + * elscuart functions. These provide a uart-like interface to the + * bedrock/l1 protocol console channels. They are similar in form + * and intent to the elscuart_* functions defined for SN0 in elsc.c. + * + */ + +int _elscuart_flush( l1sc_t *sc ); + +/* Leave room in queue for CR/LF */ +#define ELSCUART_LINE_MAX (BRL1_QSIZE - 2) + + +/* + * _elscuart_putc provides an entry point to the L1 interface driver; + * writes a single character to the output queue. Flushes at the + * end of each line, and translates newlines into CR/LF. + * + * The kernel should generally use l1_cons_write instead, since it assumes + * buffering, translation, prefixing, etc. are done at a higher + * level. + * + */ +int +_elscuart_putc( l1sc_t *sc, int c ) +{ + sc_cq_t *q; + + q = &(sc->oq[ MAP_OQ(L1_ELSCUART_SUBCH(get_myid())) ]); + + if( c != '\n' && c != '\r' && cq_used(q) >= ELSCUART_LINE_MAX ) { + cq_add( q, '\r' ); + cq_add( q, '\n' ); + _elscuart_flush( sc ); + sc->sol = 1; + } + + if( sc->sol && c != '\r' ) { + char prefix[16], *s; + + if( cq_room( q ) < 8 && _elscuart_flush(sc) < 0 ) + { + return -1; + } + + if( sc->verbose ) + { +#ifdef SUPPORT_PRINTING_M_FORMAT + sprintf( prefix, + "%c %d%d%d %M:", + 'A' + get_myid(), + sc->nasid / 100, + (sc->nasid / 10) % 10, + sc->nasid / 10, + sc->modid ); +#else + sprintf( prefix, + "%c %d%d%d 0x%x:", + 'A' + get_myid(), + sc->nasid / 100, + (sc->nasid / 10) % 10, + sc->nasid / 10, + sc->modid ); +#endif + + for( s = prefix; *s; s++ ) + cq_add( q, *s ); + } + sc->sol = 0; + + } + + if( cq_room( q ) < 2 && _elscuart_flush(sc) < 0 ) + { + return -1; + } + + if( c == '\n' ) { + cq_add( q, '\r' ); + sc->sol = 1; + } + + cq_add( q, (u_char) c ); + + if( c == '\n' ) { + /* flush buffered line */ + if( _elscuart_flush( sc ) < 0 ) + { + return -1; + } + } + + if( c== '\r' ) + { + sc->sol = 1; + } + + return 0; +} + + +/* + * _elscuart_getc reads a character from the input queue. This + * routine blocks. + */ +int +_elscuart_getc( l1sc_t *sc ) +{ + int r; + + while( (r = _elscuart_poll( sc )) == 0 ); + + if( r < 0 ) { + /* some error occured */ + return r; + } + + return _elscuart_readc( sc ); +} + + + +/* + * _elscuart_poll returns 1 if characters are ready for the + * calling processor, 0 if they are not + */ +int +_elscuart_poll( l1sc_t *sc ) +{ + int result; + + if( sc->cons_listen ) { + result = l1_cons_poll( sc ); + if( result ) + return result; + } + + return sc_poll( sc, L1_ELSCUART_SUBCH(get_myid()) ); +} + + + +/* _elscuart_readc is to be used only when _elscuart_poll has + * indicated that a character is waiting. Pulls a character + * of this processor's console queue and returns it. + * + */ +int +_elscuart_readc( l1sc_t *sc ) +{ + int c, pl; + sc_cq_t *q; + brl1_sch_t *subch; + + if( sc->cons_listen ) { + subch = &(sc->subch[ SC_CONS_SYSTEM ]); + q = subch->iqp; + + SUBCH_DATA_LOCK( subch, pl ); + if( !cq_empty( q ) ) { + cq_rem( q, c ); + if( cq_empty( q ) ) { + subch->packet_arrived = 0; + } + SUBCH_DATA_UNLOCK( subch, pl ); + return c; + } + SUBCH_DATA_UNLOCK( subch, pl ); + } + + subch = &(sc->subch[ L1_ELSCUART_SUBCH(get_myid()) ]); + q = subch->iqp; + + SUBCH_DATA_LOCK( subch, pl ); + if( cq_empty( q ) ) { + SUBCH_DATA_UNLOCK( subch, pl ); + return -1; + } + + cq_rem( q, c ); + if( cq_empty ( q ) ) { + subch->packet_arrived = 0; + } + SUBCH_DATA_UNLOCK( subch, pl ); + + return c; +} + + +/* + * _elscuart_flush flushes queued output to the the L1. + * This routine blocks until the queue is flushed. + */ +int +_elscuart_flush( l1sc_t *sc ) +{ + int r, n; + char buf[BRL1_QSIZE]; + sc_cq_t *q = &(sc->oq[ MAP_OQ(L1_ELSCUART_SUBCH(get_myid())) ]); + + while( (n = cq_used(q)) ) { + + /* buffer queue contents */ + r = BRL1_QSIZE - q->opos; + + if( n > r ) { + BCOPY( q->buf + q->opos, buf, r ); + BCOPY( q->buf, buf + r, n - r ); + } else { + BCOPY( q->buf + q->opos, buf, n ); + } + + /* attempt to send buffer contents */ + r = brl1_send( sc, buf, cq_used( q ), + (BRL1_EVENT | L1_ELSCUART_SUBCH(get_myid())), 1 ); + + /* if no error, dequeue the sent characters; otherwise, + * return the error + */ + if( r >= SC_SUCCESS ) { + q->opos = (q->opos + r) % BRL1_QSIZE; + } + else { + return r; + } + } + + return 0; +} + + + +/* _elscuart_probe returns non-zero if the L1 (and + * consequently the elscuart) can be accessed + */ +int +_elscuart_probe( l1sc_t *sc ) +{ +#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL + return 0; +#else + char ver[BRL1_QSIZE]; + extern int elsc_version( l1sc_t *, char * ); + if ( IS_RUNNING_ON_SIMULATOR() ) + return 0; + return( elsc_version(sc, ver) >= 0 ); +#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */ +} + + + +/* _elscuart_init zeroes out the l1sc_t console + * queues for this processor's console subchannel. + */ +void +_elscuart_init( l1sc_t *sc ) +{ + int pl; + brl1_sch_t *subch = &sc->subch[L1_ELSCUART_SUBCH(get_myid())]; + + SUBCH_DATA_LOCK(subch, pl); + + subch->packet_arrived = 0; + cq_init( subch->iqp ); + cq_init( &sc->oq[MAP_OQ(L1_ELSCUART_SUBCH(get_myid()))] ); + + SUBCH_DATA_UNLOCK(subch, pl); +} + + +#ifdef IRIX + +/* elscuart_syscon_listen causes the processor on which it's + * invoked to "listen" to the system console subchannel (that + * is, subchannel 4) for console input. + */ +void +elscuart_syscon_listen( l1sc_t *sc ) +{ + int pl; + brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]); + + /* if we're already listening, don't bother */ + if( sc->cons_listen ) + return; + + SUBCH_DATA_LOCK( subch, pl ); + + subch->use = BRL1_SUBCH_RSVD; + subch->packet_arrived = 0; + + SUBCH_DATA_UNLOCK( subch, pl ); + + + sc->cons_listen = 1; +} +#endif /* IRIX */ diff -urN linux-2.4.0-test12/arch/ia64/sn/io/l1_command.c linux-2.4.0-test12-lia/arch/ia64/sn/io/l1_command.c --- linux-2.4.0-test12/arch/ia64/sn/io/l1_command.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/l1_command.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,1357 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ELSC_TIMEOUT 1000000 /* ELSC response timeout (usec) */ +#define LOCK_TIMEOUT 5000000 /* Hub lock timeout (usec) */ + +#define LOCAL_HUB LOCAL_HUB_ADDR +#define LD(x) (*(volatile uint64_t *)(x)) +#define SD(x, v) (LD(x) = (uint64_t) (v)) + +#define hub_cpu_get() 0 + +#define LBYTE(caddr) (*(char *) caddr) + +extern char *bcopy(const char * src, char * dest, int count); + +#define LDEBUG 0 + +/* + * ELSC data is in NVRAM page 7 at the following offsets. + */ + +#define NVRAM_MAGIC_AD 0x700 /* magic number used for init */ +#define NVRAM_PASS_WD 0x701 /* password (4 bytes in length) */ +#define NVRAM_DBG1 0x705 /* virtual XOR debug switches */ +#define NVRAM_DBG2 0x706 /* physical XOR debug switches */ +#define NVRAM_CFG 0x707 /* ELSC Configuration info */ +#define NVRAM_MODULE 0x708 /* system module number */ +#define NVRAM_BIST_FLG 0x709 /* BIST flags (2 bits per nodeboard) */ +#define NVRAM_PARTITION 0x70a /* module's partition id */ +#define NVRAM_DOMAIN 0x70b /* module's domain id */ +#define NVRAM_CLUSTER 0x70c /* module's cluster id */ +#define NVRAM_CELL 0x70d /* module's cellid */ + +#define NVRAM_MAGIC_NO 0x37 /* value of magic number */ +#define NVRAM_SIZE 16 /* 16 bytes in nvram */ + +/* + * Declare a static ELSC NVRAM buffer to hold all data read from + * and written to NVRAM. This nvram "cache" will be used only during the + * IP27prom execution. + */ +static char elsc_nvram_buffer[NVRAM_SIZE]; + +#define SC_COMMAND sc_command + + +/* + * elsc_init + * + * Initialize ELSC structure + */ + +void elsc_init(elsc_t *e, nasid_t nasid) +{ + sc_init((l1sc_t *)e, nasid, BRL1_LOCALUART); +} + + +/* + * elsc_errmsg + * + * Given a negative error code, + * returns a corresponding static error string. + */ + +char *elsc_errmsg(int code) +{ + switch (code) { + case ELSC_ERROR_CMD_SEND: + return "Command send error"; + case ELSC_ERROR_CMD_CHECKSUM: + return "Command packet checksum error"; + case ELSC_ERROR_CMD_UNKNOWN: + return "Unknown command"; + case ELSC_ERROR_CMD_ARGS: + return "Invalid command argument(s)"; + case ELSC_ERROR_CMD_PERM: + return "Permission denied"; + case ELSC_ERROR_RESP_TIMEOUT: + return "System controller response timeout"; + case ELSC_ERROR_RESP_CHECKSUM: + return "Response packet checksum error"; + case ELSC_ERROR_RESP_FORMAT: + return "Response format error"; + case ELSC_ERROR_RESP_DIR: + return "Response direction error"; + case ELSC_ERROR_MSG_LOST: + return "Message lost because queue is full"; + case ELSC_ERROR_LOCK_TIMEOUT: + return "Timed out getting ELSC lock"; + case ELSC_ERROR_DATA_SEND: + return "Error sending data"; + case ELSC_ERROR_NIC: + return "NIC protocol error"; + case ELSC_ERROR_NVMAGIC: + return "Bad magic number in NVRAM"; + case ELSC_ERROR_MODULE: + return "Module location protocol error"; + default: + return "Unknown error"; + } +} + +/* + * elsc_nvram_init + * + * Initializes reads and writes to NVRAM. This will perform a single + * read to NVRAM, getting all data at once. When the PROM tries to + * read NVRAM, it returns the data from the buffer being read. If the + * PROM tries to write out to NVRAM, the write is done, and the internal + * buffer is updated. + */ + +void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data) +{ + /* This might require implementation of multiple-packet request/responses + * if it's to provide the same behavior that was available in SN0. + */ + nasid = nasid; + elsc_nvram_data = elsc_nvram_data; +} + +/* + * elsc_nvram_copy + * + * Copies the content of a buffer into the static buffer in this library. + */ + +void elsc_nvram_copy(uchar_t *elsc_nvram_data) +{ + memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE); +} + +/* + * elsc_nvram_write + * + * Copies bytes from 'buf' into NVRAM, starting at NVRAM address + * 'addr' which must be between 0 and 2047. + * + * If 'len' is non-negative, the routine copies 'len' bytes. + * + * If 'len' is negative, the routine treats the data as a string and + * copies bytes up to and including a NUL-terminating zero, but not + * to exceed '-len' bytes. + */ + +int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len) +{ + /* Here again, we might need to work out the details of a + * multiple-packet protocol. + */ + + /* For now, pretend it worked. */ + e = e; + addr = addr; + buf = buf; + return (len < 0 ? -len : len); +} + +/* + * elsc_nvram_read + * + * Copies bytes from NVRAM into 'buf', starting at NVRAM address + * 'addr' which must be between 0 and 2047. + * + * If 'len' is non-negative, the routine copies 'len' bytes. + * + * If 'len' is negative, the routine treats the data as a string and + * copies bytes up to and including a NUL-terminating zero, but not + * to exceed '-len' bytes. NOTE: This method is no longer supported. + * It was never used in the first place. + */ + +int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len) +{ + /* multiple packets? */ + e = e; + addr = addr; + buf = buf; + len = len; + return -1; +} + +/* + * Command Set + */ + +int elsc_version(elsc_t *e, char *result) +{ + char msg[BRL1_QSIZE]; + int len; /* length of message being sent */ + int subch; /* system controller subchannel used */ + int major, /* major rev number */ + minor, /* minor rev number */ + bugfix; /* bugfix rev number */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL ); + + if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_FW_REV, 0 )) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( (l1sc_t *)e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major, + L1_ARG_INT, &minor, L1_ARG_INT, &bugfix ) + < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + sprintf( result, "%d.%d.%d", major, minor, bugfix ); + + return 0; +} + +int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2) +{ + /* shush compiler */ + e = e; + byte1 = byte1; + byte2 = byte2; + + /* fill in a buffer with the opcode & params; call sc_command */ + + return 0; +} + +int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2) +{ + char msg[BRL1_QSIZE]; + int subch; /* system controller subchannel used */ + int dbg_sw; /* holds debug switch settings */ + int len; /* number of msg buffer bytes used */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) { + return( ELSC_ERROR_CMD_SEND ); + } + + if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_RDBG, 0 ) ) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( (l1sc_t *)e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + /* copy out debug switch settings (last two bytes of the + * integer response) + */ + *byte1 = ((dbg_sw >> 8) & 0xFF); + *byte2 = (dbg_sw & 0xFF); + + return 0; +} + +/* + * elsc_rack_bay_get fills in the two int * arguments with the + * rack number and bay number of the L1 being addressed + */ +int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + uint32_t buf32; /* used to copy 32-bit rack/bay out of msg */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) { + return( ELSC_ERROR_CMD_SEND ); + } + + if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_RRACK, 0 )) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + + /* send the request to the L1 */ + if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close(e, subch); + + /* check response */ + if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + /* extract rack/bay info + * + * note that the 32-bit value returned by the L1 actually + * only uses the low-order sixteen bits for rack and bay + * information. A "normal" L1 address puts rack and bay + * information in bit positions 12 through 28. So if + * we initially shift the value returned 12 bits to the left, + * we can use the L1 addressing #define's to extract the + * values we need (see ksys/l1.h for a complete list of the + * various fields of an L1 address). + */ + buf32 <<= L1_ADDR_BAY_SHFT; + + *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; + *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; + + return 0; +} + + +/* elsc_rack_bay_type_get fills in the three int * arguments with the + * rack number, bay number and brick type of the L1 being addressed. Note + * that if the L1 operation fails and this function returns an error value, + * garbage may be written to brick_type. + */ +int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, + uint *bay, uint *brick_type ) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + uint32_t buf32; /* used to copy 32-bit rack & bay out of msg */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) { + return ELSC_ERROR_CMD_SEND; + } + + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_RRBT, 0 )) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( SC_COMMAND( sc, subch, msg, msg, &len ) ) { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( sc, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, + L1_ARG_INT, brick_type ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + /* extract rack/bay info + * + * note that the 32-bit value returned by the L1 actually + * only uses the low-order sixteen bits for rack and bay + * information. A "normal" L1 address puts rack and bay + * information in bit positions 12 through 28. So if + * we initially shift the value returned 12 bits to the left, + * we can use the L1 addressing #define's to extract the + * values we need (see ksys/l1.h for a complete list of the + * various fields of an L1 address). + */ + buf32 <<= L1_ADDR_BAY_SHFT; + + *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; + *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; + + /* convert brick_type to lower case */ + *brick_type = *brick_type - 'A' + 'a'; + + return 0; +} + + +int elsc_module_get(elsc_t *e) +{ + extern char brick_types[]; + uint rnum, rack, bay, bricktype, t; + int ret; + + /* construct module ID from rack and slot info */ + + if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) + return ret; + + /* report unset location info. with a special, otherwise invalid modid */ + if (rnum == 0 && bay == 0) + return MODULE_NOT_SET; + + if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) + return ELSC_ERROR_MODULE; + + /* Build a moduleid_t-compatible rack number */ + + rack = 0; + t = rnum / 100; /* rack class (CPU/IO) */ + if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_CLASS(rack, t); + rnum %= 100; + + t = rnum / 10; /* rack group */ + if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_GROUP(rack, t); + + t = rnum % 10; /* rack number (one-based) */ + if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_NUM(rack, t); + + for( t = 0; t < MAX_BRICK_TYPES; t++ ) { + if( brick_types[t] == bricktype ) + return RBT_TO_MODULE(rack, bay, t); + } + + return ELSC_ERROR_MODULE; +} + +int elsc_partition_set(elsc_t *e, int partition) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { + return ELSC_ERROR_CMD_SEND; + } + + if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_PARTITION_SET, 2, + L1_ARG_INT, partition )) < 0 ) + { + + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( e, subch, msg, msg, &len ) ) { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 0 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return( 0 ); +} + +int elsc_partition_get(elsc_t *e) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + uint32_t partition_id; /* used to copy partition id out of msg */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { + return ELSC_ERROR_CMD_SEND; + } + + if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_PARTITION_GET, 0 )) < 0 ) + + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( e, subch, msg, msg, &len ) ) { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return( partition_id ); +} + + +/* + * elsc_cons_subch selects the "active" console subchannel for this node + * (i.e., the one that will currently receive input) + */ +int elsc_cons_subch(elsc_t *e, uint ch) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + subch = sc_open( e, L1_ADDR_LOCAL ); + + if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_CONS_SUBCH, 2, + L1_ARG_INT, ch)) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( SC_COMMAND( e, subch, msg, msg, &len ) ) { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 0 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return 0; +} + + +/* + * elsc_cons_node should only be executed by one node. It declares to + * the system controller that the node from which it is called will be + * the owner of the system console. + */ +int elsc_cons_node(elsc_t *e) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + subch = sc_open( e, L1_ADDR_LOCAL ); + + if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_CONS_NODE, 0 )) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( SC_COMMAND( e, subch, msg, msg, &len ) ) { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 0 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return 0; +} + + +/* elsc_display_line writes up to 12 characters to either the top or bottom + * line of the L1 display. line points to a buffer containing the message + * to be displayed. The zero-based line number is specified by lnum (so + * lnum == 0 specifies the top line and lnum == 1 specifies the bottom). + * Lines longer than 12 characters, or line numbers not less than + * L1_DISPLAY_LINES, cause elsc_display_line to return an error. + */ +int elsc_display_line(elsc_t *e, char *line, int lnum) +{ + char msg[BRL1_QSIZE]; + int subch; /* system controller subchannel used */ + int len; /* number of msg buffer bytes used */ + + /* argument sanity checking */ + if( !(lnum < L1_DISPLAY_LINES) ) + return( ELSC_ERROR_CMD_ARGS ); + if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) ) + return( ELSC_ERROR_CMD_ARGS ); + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL ); + + if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + (L1_REQ_DISP1+lnum), 2, + L1_ARG_ASCII, line )) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( (l1sc_t *)e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 0 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return 0; +} + + +/* elsc_display_mesg silently drops message characters beyond the 12th. + */ +int elsc_display_mesg(elsc_t *e, char *chr) +{ + + char line[L1_DISPLAY_LINE_LENGTH+1]; + int numlines, i; + int result; + + numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) / + L1_DISPLAY_LINE_LENGTH; + + if( numlines > L1_DISPLAY_LINES ) + numlines = L1_DISPLAY_LINES; + + for( i = 0; i < numlines; i++ ) + { + strncpy( line, chr, L1_DISPLAY_LINE_LENGTH ); + line[L1_DISPLAY_LINE_LENGTH] = '\0'; + + /* generally we want to leave the first line of the L1 display + * alone (so the L1 can manipulate it). If you need to be able + * to display to both lines (for debugging purposes), define + * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES + * to your 'defs file. + */ +#if defined(L1_DISP_2LINES) + if( (result = elsc_display_line( e, line, i )) < 0 ) +#else + if( (result = elsc_display_line( e, line, i+1 )) < 0 ) +#endif + + return result; + + chr += L1_DISPLAY_LINE_LENGTH; + } + + return 0; +} + + +int elsc_password_set(elsc_t *e, char *password) +{ + /* shush compiler */ + e = e; + password = password; + + /* fill in buffer with the opcode & params; call elsc_command */ + + return 0; +} + +int elsc_password_get(elsc_t *e, char *password) +{ + /* shush compiler */ + e = e; + password = password; + + /* fill in buffer with the opcode & params; call elsc_command */ + + return 0; +} + + +/* + * sc_portspeed_get + * + * retrieve the current portspeed setting for the bedrock II + */ +int sc_portspeed_get(l1sc_t *sc) +{ + char msg[BRL1_QSIZE]; + int len; /* length of message being sent */ + int subch; /* system controller subchannel used */ + int portspeed_a, portspeed_b; + /* ioport clock rates */ + + bzero( msg, BRL1_QSIZE ); + subch = sc_open( sc, L1_ADDR_LOCAL ); + + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_PORTSPEED, + 0 )) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( sc, subch, msg, msg, &len ) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( sc, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 4, + L1_ARG_INT, &portspeed_a, + L1_ARG_INT, &portspeed_b ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + /* for the c-brick, we ignore the portspeed_b value */ + return (portspeed_a ? 600 : 400); +} + +/* + * elsc_power_query + * + * To be used after system reset, this command returns 1 if the reset + * was the result of a power-on, 0 otherwise. + * + * The power query status is cleared to 0 after it is read. + */ + +int elsc_power_query(elsc_t *e) +{ + e = e; /* shush the compiler */ + + /* fill in buffer with the opcode & params; call elsc_command */ + + return 1; +} + +int elsc_rpwr_query(elsc_t *e, int is_master) +{ + /* shush the compiler */ + e = e; + is_master = is_master; + + /* fill in buffer with the opcode & params; call elsc_command */ + + return 0; +} + +/* + * elsc_power_down + * + * Sets up system to shut down in "sec" seconds (or modifies the + * shutdown time if one is already in effect). Use 0 to power + * down immediately. + */ + +int elsc_power_down(elsc_t *e, int sec) +{ + /* shush compiler */ + e = e; + sec = sec; + + /* fill in buffer with the opcode & params; call elsc_command */ + + return 0; +} + + +int elsc_system_reset(elsc_t *e) +{ + char msg[BRL1_QSIZE]; + int subch; /* system controller subchannel used */ + int len; /* number of msg buffer bytes used */ + int result; + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) { + return ELSC_ERROR_CMD_SEND; + } + + if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_RESET, 0 )) < 0 ) + { + sc_close( e, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( (result = sc_command( e, subch, msg, msg, &len )) ) { + sc_close( e, subch ); + if( result == SC_NMSG ) { + /* timeout is OK. We've sent the reset. Now it's just + * a matter of time... + */ + return( 0 ); + } + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( e, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 0 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return 0; +} + + +int elsc_power_cycle(elsc_t *e) +{ + /* shush compiler */ + e = e; + + /* fill in buffer with the opcode & params; call sc_command */ + + return 0; +} + + +/* + * L1 Support for reading + * cbrick uid. + */ + +int elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose) +{ + /* this parameter included only for SN0 compatibility */ + verbose = verbose; + + /* We don't go straight to the bedrock/L1 protocol on this one, but let + * the eeprom layer prepare the eeprom data as we would like it to + * appear to the caller + */ + return cbrick_uid_get( e->nasid, nic ); +} + +int _elsc_hbt(elsc_t *e, int ival, int rdly) +{ + e = e; + ival = ival; + rdly = rdly; + + /* fill in buffer with the opcode & params; call elsc_command */ + + return 0; +} + + +/* send a command string to an L1 */ +int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay, + char *cmd ) +{ + char msg[BRL1_QSIZE]; + int len; /* length of message being sent */ + int subch; /* system controller subchannel used */ + l1addr_t target; /* target system controller for command */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + subch = sc_open( sc, L1_ADDR_LOCAL ); + + L1_BUILD_ADDR( &target, compt, rack, bay, L1_ADDR_TASK_CMD ); + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + target, L1_REQ_EXEC_CMD, 2, + L1_ARG_ASCII, cmd )) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( sc, subch, msg, msg, &len ) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( sc, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 0 ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + return 0; +} + + +/* + * Routines for reading the R-brick's L1 + */ + +int router_module_get( nasid_t nasid, net_vec_t path ) +{ + uint rnum, rack, bay, t; + int ret; + l1sc_t sc; + + /* prepare l1sc_t struct */ + sc_init( &sc, nasid, path ); + + /* construct module ID from rack and slot info */ + + if ((ret = elsc_rack_bay_get(&sc, &rnum, &bay)) < 0) + return ret; + + /* report unset location info. with a special, otherwise invalid modid */ + if (rnum == 0 && bay == 0) + return MODULE_NOT_SET; + + if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) + return ELSC_ERROR_MODULE; + + /* Build a moduleid_t-compatible rack number */ + + rack = 0; + t = rnum / 100; /* rack class (CPU/IO) */ + if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_CLASS(rack, t); + rnum %= 100; + + t = rnum / 10; /* rack group */ + if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_GROUP(rack, t); + + t = rnum % 10; /* rack number (one-based) */ + if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_NUM(rack, t); + + ret = RBT_TO_MODULE(rack, bay, MODULE_RBRICK); + return ret; +} + + +/* + * iobrick routines + */ + +/* iobrick_rack_bay_type_get fills in the three int * arguments with the + * rack number, bay number and brick type of the L1 being addressed. Note + * that if the L1 operation fails and this function returns an error value, + * garbage may be written to brick_type. + */ +int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, + uint *bay, uint *brick_type ) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + uint32_t buf32; /* used to copy 32-bit rack & bay out of msg */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) { + return( ELSC_ERROR_CMD_SEND ); + } + + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_RRBT, 0 )) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( sc, subch, msg, msg, &len ) ) { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( sc, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, + L1_ARG_INT, brick_type ) < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + /* extract rack/bay info + * + * note that the 32-bit value returned by the L1 actually + * only uses the low-order sixteen bits for rack and bay + * information. A "normal" L1 address puts rack and bay + * information in bit positions 12 through 28. So if + * we initially shift the value returned 12 bits to the left, + * we can use the L1 addressing #define's to extract the + * values we need (see ksys/l1.h for a complete list of the + * various fields of an L1 address). + */ + buf32 <<= L1_ADDR_BAY_SHFT; + + *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT; + *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT; + + return 0; +} + + +int iobrick_module_get(l1sc_t *sc) +{ + uint rnum, rack, bay, brick_type, t; + int ret; + + /* construct module ID from rack and slot info */ + + if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0) + return ret; + + /* report unset location info. with a special, otherwise invalid modid */ + if (rnum == 0 && bay == 0) + return MODULE_NOT_SET; + + if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT) + return ELSC_ERROR_MODULE; + + /* Build a moduleid_t-compatible rack number */ + + rack = 0; + t = rnum / 100; /* rack class (CPU/IO) */ + if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_CLASS(rack, t); + rnum %= 100; + + t = rnum / 10; /* rack group */ + if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_GROUP(rack, t); + + t = rnum % 10; /* rack number (one-based) */ + if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack)) + return ELSC_ERROR_MODULE; + RACK_ADD_NUM(rack, t); + + switch( brick_type ) { + case 'I': + brick_type = MODULE_IBRICK; break; + case 'P': + brick_type = MODULE_PBRICK; break; + case 'X': + brick_type = MODULE_XBRICK; break; + } + + ret = RBT_TO_MODULE(rack, bay, brick_type); + + return ret; +} + +/* iobrick_get_sys_snum asks the attached iobrick for the system + * serial number. This function will only be relevant to the master + * cbrick (the one attached to the bootmaster ibrick); other nodes + * may call the function, but the value returned to the master node + * will be the one used as the system serial number by the kernel. + */ + +int +iobrick_get_sys_snum( l1sc_t *sc, char *snum_str ) +{ + char msg[BRL1_QSIZE]; /* L1 request/response info */ + int subch; /* system controller subchannel used */ + int len; /* length of message */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) { + return( ELSC_ERROR_CMD_SEND ); + } + + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_SYS_SERIAL, 0 )) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( sc_command( sc, subch, msg, msg, &len ) ) { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( sc, subch ); + + /* check response */ + return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) ); +} + + +/* + * The following functions apply (or cut off) power to the specified + * pci bus or slot. + */ + +int +iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up ) +{ + char cmd[BRL1_QSIZE]; + unsigned rack, bay, brick_type; + if( iobrick_rack_bay_type_get( sc, &rack, &bay, &brick_type ) < 0 ) + return( ELSC_ERROR_CMD_SEND ); + sprintf( cmd, "pci %d %d %s", bus, slot, + (up ? "u" : "d") ); + return( sc_command_interp + ( sc, L1_ADDR_TYPE_L1, rack, bay, cmd ) ); +} + +int +iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up ) +{ + char cmd[BRL1_QSIZE]; + unsigned rack, bay, brick_type; + if( iobrick_rack_bay_type_get( sc, &rack, &bay, &brick_type ) < 0 ) + return( ELSC_ERROR_CMD_SEND ); + sprintf( cmd, "pci %d %s", bus, (up ? "u" : "d") ); + return( sc_command_interp + ( sc, L1_ADDR_TYPE_L1, rack, bay, cmd ) ); +} + + +/* get the L1 firmware version for an iobrick */ +int +iobrick_sc_version( l1sc_t *sc, char *result ) +{ + char msg[BRL1_QSIZE]; + int len; /* length of message being sent */ + int subch; /* system controller subchannel used */ + int major, /* major rev number */ + minor, /* minor rev number */ + bugfix; /* bugfix rev number */ + + /* fill in msg with the opcode & params */ + bzero( msg, BRL1_QSIZE ); + subch = sc_open( sc, L1_ADDR_LOCALIO ); + + if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE, + L1_ADDR_TASK_GENERAL, + L1_REQ_FW_REV, 0 )) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_ARGS ); + } + + /* send the request to the L1 */ + if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 ) + { + sc_close( sc, subch ); + return( ELSC_ERROR_CMD_SEND ); + } + + /* free up subchannel */ + sc_close( sc, subch ); + + /* check response */ + if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major, + L1_ARG_INT, &minor, L1_ARG_INT, &bugfix ) + < 0 ) + { + return( ELSC_ERROR_RESP_FORMAT ); + } + + sprintf( result, "%d.%d.%d", major, minor, bugfix ); + + return 0; +} + + + +/* elscuart routines + * + * Most of the elscuart functionality is implemented in l1.c. The following + * is directly "recycled" from elsc.c. + */ + + +/* + * _elscuart_puts + */ + +int _elscuart_puts(elsc_t *e, char *s) +{ + int c; + + if (s == 0) + s = ""; + + while ((c = LBYTE(s)) != 0) { + if (_elscuart_putc(e, c) < 0) + return -1; + s++; + } + + return 0; +} + + +/* + * elscuart wrapper routines + * + * The following routines are similar to their counterparts in l1.c, + * except instead of taking an elsc_t pointer directly, they call + * a global routine "get_elsc" to obtain the pointer. + * This is useful when the elsc is employed for stdio. + */ + +int elscuart_probe(void) +{ + return _elscuart_probe(get_elsc()); +} + +void elscuart_init(void *init_data) +{ + _elscuart_init(get_elsc()); + /* dummy variable included for driver compatability */ + init_data = init_data; +} + +int elscuart_poll(void) +{ + return _elscuart_poll(get_elsc()); +} + +int elscuart_readc(void) +{ + return _elscuart_readc(get_elsc()); +} + +int elscuart_getc(void) +{ + return _elscuart_getc(get_elsc()); +} + +int elscuart_puts(char *s) +{ + return _elscuart_puts(get_elsc(), s); +} + +int elscuart_putc(int c) +{ + return _elscuart_putc(get_elsc(), c); +} + +int elscuart_flush(void) +{ + return _elscuart_flush(get_elsc()); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/labelcl.c linux-2.4.0-test12-lia/arch/ia64/sn/io/labelcl.c --- linux-2.4.0-test12/arch/ia64/sn/io/labelcl.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/labelcl.c Thu Dec 14 02:16:18 2000 @@ -0,0 +1,667 @@ +/* labelcl - SGI's Hwgraph Compatibility Layer. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Colin Ngam may be reached by email at cngam@sgi.com + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +** Very simple and dumb string table that supports only find/insert. +** In practice, if this table gets too large, we may need a more +** efficient data structure. Also note that currently there is no +** way to delete an item once it's added. Therefore, name collision +** will return an error. +*/ + +struct string_table label_string_table; + + + +/* + * string_table_init - Initialize the given string table. + */ +void +string_table_init(struct string_table *string_table) +{ + string_table->string_table_head = NULL; + string_table->string_table_generation = 0; + + /* + * We nedd to initialize locks here! + */ + + return; +} + + +/* + * string_table_destroy - Destroy the given string table. + */ +void +string_table_destroy(struct string_table *string_table) +{ + struct string_table_item *item, *next_item; + + item = string_table->string_table_head; + while (item) { + next_item = item->next; + + STRTBL_FREE(item); + item = next_item; + } + + /* + * We need to destroy whatever lock we have here + */ + + return; +} + + + +/* + * string_table_insert - Insert an entry in the string table .. duplicate + * names are not allowed. + */ +char * +string_table_insert(struct string_table *string_table, char *name) +{ + struct string_table_item *item, *new_item = NULL, *last_item = NULL; + +again: + /* + * Need to lock the table .. + */ + item = string_table->string_table_head; + last_item = NULL; + + while (item) { + if (!strcmp(item->string, name)) { + /* + * If we allocated space for the string and the found that + * someone else already entered it into the string table, + * free the space we just allocated. + */ + if (new_item) + STRTBL_FREE(new_item); + + + /* + * Search optimization: move the found item to the head + * of the list. + */ + if (last_item != NULL) { + last_item->next = item->next; + item->next = string_table->string_table_head; + string_table->string_table_head = item; + } + goto out; + } + last_item = item; + item=item->next; + } + + /* + * name was not found, so add it to the string table. + */ + if (new_item == NULL) { + long old_generation = string_table->string_table_generation; + + new_item = STRTBL_ALLOC(strlen(name)); + + strcpy(new_item->string, name); + + /* + * While we allocated memory for the new string, someone else + * changed the string table. + */ + if (old_generation != string_table->string_table_generation) { + goto again; + } + } else { + /* At this we only have the string table lock in access mode. + * Promote the access lock to an update lock for the string + * table insertion below. + */ + long old_generation = + string_table->string_table_generation; + + /* + * After we did the unlock and wer waiting for update + * lock someone could have potentially updated + * the string table. Check the generation number + * for this case. If it is the case we have to + * try all over again. + */ + if (old_generation != + string_table->string_table_generation) { + goto again; + } + } + + /* + * At this point, we're committed to adding new_item to the string table. + */ + new_item->next = string_table->string_table_head; + item = string_table->string_table_head = new_item; + string_table->string_table_generation++; + +out: + /* + * Need to unlock here. + */ + return(item->string); +} + +/* + * labelcl_info_create - Creates the data structure that will hold the + * device private information asscoiated with a devfs entry. + * The pointer to this structure is what gets stored in the devfs + * (void * info). + */ +labelcl_info_t * +labelcl_info_create() +{ + + labelcl_info_t *new = NULL; + + /* Initial allocation does not include any area for labels */ + if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL ) + return NULL; + + memset (new, 0, sizeof(labelcl_info_t)); + new->hwcl_magic = LABELCL_MAGIC; + return( new); + +} + +/* + * labelcl_info_destroy - Frees the data structure that holds the + * device private information asscoiated with a devfs entry. This + * data structure was created by device_info_create(). + * + * The caller is responsible for nulling the (void *info) in the + * corresponding devfs entry. + */ +int +labelcl_info_destroy(labelcl_info_t *labelcl_info) +{ + + if (labelcl_info == NULL) + return(0); + + /* Free the label list */ + if (labelcl_info->label_list) + kfree(labelcl_info->label_list); + + /* Now free the label info area */ + labelcl_info->hwcl_magic = 0; + kfree(labelcl_info); + + return(0); +} + +/* + * labelcl_info_add_LBL - Adds a new label entry in the labelcl info + * structure. + * + * Error is returned if we find another label with the same name. + */ +int +labelcl_info_add_LBL(devfs_handle_t de, + char *info_name, + arb_info_desc_t info_desc, + arbitrary_info_t info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + int new_label_list_size; + label_info_t *old_label_list, *new_label_list = NULL; + char *name; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if (info_name == NULL) + return(-1); + + if (strlen(info_name) >= LABEL_LENGTH_MAX) + return(-1); + + name = string_table_insert(&label_string_table, info_name); + + num_labels = labelcl_info->num_labels; + new_label_list_size = sizeof(label_info_t) * (num_labels+1); + + /* + * Create a new label info area. + */ + if (new_label_list_size != 0) { + new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); + + if (new_label_list == NULL) + return(-1); + } + + /* + * At this point, we are committed to adding the labelled info, + * if there isn't already information there with the same name. + */ + old_label_list = labelcl_info->label_list; + + /* + * Look for matching info name. + */ + for (i=0; inum_labels = num_labels+1; + labelcl_info->label_list = new_label_list; + + if (old_label_list != NULL) + kfree(old_label_list); + + return(0); +} + +/* + * labelcl_info_remove_LBL - Remove a label entry. + */ +int +labelcl_info_remove_LBL(devfs_handle_t de, + char *info_name, + arb_info_desc_t *info_desc, + arbitrary_info_t *info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + int new_label_list_size; + label_info_t *old_label_list, *new_label_list = NULL; + arb_info_desc_t label_desc_found; + arbitrary_info_t label_info_found; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + /* + * Create a new info area. + */ + new_label_list_size = sizeof(label_info_t) * (num_labels-1); + if (new_label_list_size) { + new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL); + if (new_label_list == NULL) + return(-1); + } + + /* + * At this point, we are committed to removing the labelled info, + * if it still exists. + */ + old_label_list = labelcl_info->label_list; + + /* + * Find matching info name. + */ + for (i=0; inum_labels = num_labels+1; + labelcl_info->label_list = new_label_list; + + kfree(old_label_list); + + if (info != NULL) + *info = label_info_found; + + if (info_desc != NULL) + *info_desc = label_desc_found; + + return(0); +} + + +/* + * labelcl_info_replace_LBL - Replace an existing label entry with the + * given new information. + * + * Label entry must exist. + */ +int +labelcl_info_replace_LBL(devfs_handle_t de, + char *info_name, + arb_info_desc_t info_desc, + arbitrary_info_t info, + arb_info_desc_t *old_info_desc, + arbitrary_info_t *old_info) +{ + labelcl_info_t *labelcl_info = NULL; + int num_labels; + label_info_t *label_list; + int i; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + if (info_name == NULL) + return(-1); + + label_list = labelcl_info->label_list; + + /* + * Verify that information under info_name already exists. + */ + for (i=0; ihwcl_magic != LABELCL_MAGIC) + return(-1); + + num_labels = labelcl_info->num_labels; + if (num_labels == 0) { + return(-1); + } + + label_list = labelcl_info->label_list; + + /* + * Find information under info_name. + */ + for (i=0; ihwcl_magic != LABELCL_MAGIC) + return(-1); + + which_info = *placeptr; + + if (which_info >= labelcl_info->num_labels) { + return(-1); + } + + label_list = (label_info_t *) labelcl_info->label_list; + + if (buffer != NULL) + strcpy(buffer, label_list[which_info].name); + + if (infop) + *infop = label_list[which_info].info; + + if (info_descp) + *info_descp = label_list[which_info].desc; + + *placeptr = which_info + 1; + + return(0); +} + + +int +labelcl_info_replace_IDX(devfs_handle_t de, + int index, + arbitrary_info_t info, + arbitrary_info_t *old_info) +{ + arbitrary_info_t *info_list_IDX; + labelcl_info_t *labelcl_info = NULL; + + if (de == NULL) { + printk(KERN_ALERT "labelcl: NULL devfs handle given.\n"); + return(-1); + } + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) { + printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n"); + return(-1); + } + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) + return(-1); + + /* + * Replace information at the appropriate index in this vertex with + * the new info. + */ + info_list_IDX = labelcl_info->IDX_list; + if (old_info != NULL) + *old_info = info_list_IDX[index]; + info_list_IDX[index] = info; + + return(0); + +} + +/* + * labelcl_info_connectpt_set - Sets the connectpt. + */ +int +labelcl_info_connectpt_set(struct devfs_entry *de, + struct devfs_entry *connect_de) +{ + arbitrary_info_t old_info; + int rv; + + rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, + (arbitrary_info_t) connect_de, &old_info); + + if (rv) { + return(rv); + } + + return(0); +} + + +/* + * labelcl_info_get_IDX - Returns the information pointed at by index. + * + */ +int +labelcl_info_get_IDX(devfs_handle_t de, + int index, + arbitrary_info_t *info) +{ + arbitrary_info_t *info_list_IDX; + labelcl_info_t *labelcl_info = NULL; + + if (de == NULL) + return(-1); + + labelcl_info = devfs_get_info(de); + if (labelcl_info == NULL) + return(-1); + + if (labelcl_info->hwcl_magic != LABELCL_MAGIC) + return(-1); + + if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) ) + return(-1); + + /* + * Return information at the appropriate index in this vertex. + */ + info_list_IDX = labelcl_info->IDX_list; + if (info != NULL) + *info = info_list_IDX[index]; + + return(0); +} + +/* + * labelcl_info_connectpt_get - Retrieve the connect point for a device entry. + */ +struct devfs_entry * +labelcl_info_connectpt_get(struct devfs_entry *de) +{ + int rv; + arbitrary_info_t info; + + rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info); + if (rv) + return(NULL); + + return((struct devfs_entry *)info); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/mem_refcnt.c linux-2.4.0-test12-lia/arch/ia64/sn/io/mem_refcnt.c --- linux-2.4.0-test12/arch/ia64/sn/io/mem_refcnt.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/mem_refcnt.c Wed Nov 15 19:11:34 2000 @@ -0,0 +1,234 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// From numa_hw.h + +#define MIGR_COUNTER_MAX_GET(nodeid) \ + (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference) +/* + * Get the Absolute Theshold + */ +#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \ + MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid))) +/* + * Get the current Differential Threshold + */ +#define MIGR_THRESHOLD_DIFF_GET(nodeid) \ + (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold) + +#define NUM_OF_HW_PAGES_PER_SW_PAGE() (NBPP / MD_PAGE_SIZE) + +// #include "migr_control.h" + +int +mem_refcnt_attach(devfs_handle_t hub) +{ + devfs_handle_t refcnt_dev; + + hwgraph_char_device_add(hub, + "refcnt", + "hubspc_", + &refcnt_dev); + device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS); + + return (0); +} + + +/*ARGSUSED*/ +int +mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp) +{ + cnodeid_t node; +#ifndef CONFIG_IA64_SGI_SN1 + extern int numnodes; +#endif + + ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(*devp) == HUBSPC_REFCOUNTERS ); + + if (!cap_able(CAP_MEMORY_MGT)) { + return (EPERM); + } + + node = master_node_get(*devp); + + ASSERT( (node >= 0) && (node < numnodes) ); + + if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) { + return (ENODEV); + } + + ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); + ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 ); + + return (0); +} + +/*ARGSUSED*/ +int +mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) +{ + return 0; +} + +/*ARGSUSED*/ +int +mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) +{ + cnodeid_t node; + int errcode; + char* buffer; + size_t blen; +#ifndef CONFIG_IA64_SGI_SN1 + extern int numnodes; +#endif + + ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS ); + + node = master_node_get(dev); + + ASSERT( (node >= 0) && (node < numnodes) ); + + ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL); + ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); + ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 ); + + /* + * XXXX deal with prot's somewhere around here.... + */ + + buffer = NODEPDA(node)->migr_refcnt_counterbuffer; + blen = NODEPDA(node)->migr_refcnt_cbsize; + + /* + * Force offset to be a multiple of sizeof(refcnt_t) + * We round up. + */ + + off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t); + + if ( ((buffer + blen) - (buffer + off + len)) < 0 ) { + return (EPERM); + } + + errcode = v_mapphys(vt, + buffer + off, + len); + + return errcode; +} + +/*ARGSUSED*/ +int +mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt) +{ + return 0; +} + +/* ARGSUSED */ +int +mem_refcnt_ioctl(devfs_handle_t dev, + int cmd, + void *arg, + int mode, + cred_t *cred_p, + int *rvalp) +{ + cnodeid_t node; + int errcode; + extern int numnodes; + + ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS ); + + node = master_node_get(dev); + + ASSERT( (node >= 0) && (node < numnodes) ); + + ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL); + ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL ); + ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 ); + + errcode = 0; + + switch (cmd) { + case RCB_INFO_GET: + { + rcb_info_t rcb; + + rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize; + + rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets; + rcb.rcb_sw_counters_per_set = numnodes; + rcb.rcb_sw_counter_size = sizeof(refcnt_t); + + rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets / + NUM_OF_HW_PAGES_PER_SW_PAGE(); + rcb.rcb_base_page_size = NBPP; + rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0)); + + rcb.rcb_cnodeid = node; + rcb.rcb_granularity = MD_PAGE_SIZE; +#ifdef notyet + rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node); + rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node); +#endif + rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node); + rcb.rcb_num_slots = node_getnumslots(node); + + if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) { + errcode = EFAULT; + } + + break; + } + case RCB_SLOT_GET: + { + rcb_slot_t slot[MAX_MEM_SLOTS]; + int s; + int nslots; + + nslots = node_getnumslots(node); + ASSERT(nslots <= MAX_MEM_SLOTS); + for (s = 0; s < nslots; s++) { + slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s)); +#ifdef notyet + slot[s].size = (uint64_t)ctob(slot_getsize(node, s)); +#else + slot[s].size = (uint64_t)1; +#endif + } + if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) { + errcode = EFAULT; + } + + *rvalp = nslots; + break; + } + + default: + errcode = EINVAL; + break; + + } + + return errcode; +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/ml_SN_init.c linux-2.4.0-test12-lia/arch/ia64/sn/io/ml_SN_init.c --- linux-2.4.0-test12/arch/ia64/sn/io/ml_SN_init.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/ml_SN_init.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,661 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#include +#include +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + + +extern int numcpus; +extern char arg_maxnodes[]; +extern cpuid_t master_procid; +extern void * kmem_alloc_node(register size_t, register int , cnodeid_t); +extern synergy_da_t *Synergy_da_indr[]; + +extern int hasmetarouter; + +int maxcpus; +cpumask_t boot_cpumask; +hubreg_t region_mask = 0; + + +extern xwidgetnum_t hub_widget_id(nasid_t); + +#ifndef CONFIG_IA64_SGI_IO +#if defined (IP27) +short cputype = CPU_IP27; +#elif defined (IP33) +short cputype = CPU_IP33; +#elif defined (IP35) +short cputype = CPU_IP35; +#else +#error +#endif +#endif /* CONFIG_IA64_SGI_IO */ + +static int fine_mode = 0; + +#ifndef CONFIG_IA64_SGI_IO +/* Global variables */ +pdaindr_t pdaindr[MAXCPUS]; +#endif + +static cnodemask_t hub_init_mask; /* Mask of cpu in a node doing init */ +static volatile cnodemask_t hub_init_done_mask; + /* Node mask where we wait for + * per hub initialization + */ +spinlock_t hub_mask_lock; /* Lock for hub_init_mask above. */ + +extern int valid_icache_reasons; /* Reasons to flush the icache */ +extern int valid_dcache_reasons; /* Reasons to flush the dcache */ +extern int numnodes; +extern u_char miniroot; +extern volatile int need_utlbmiss_patch; +extern void iograph_early_init(void); + +nasid_t master_nasid = INVALID_NASID; + + +/* + * mlreset(int slave) + * very early machine reset - at this point NO interrupts have been + * enabled; nor is memory, tlb, p0, etc setup. + * + * slave is zero when mlreset is called for the master processor and + * is nonzero thereafter. + */ + + +void +mlreset(int slave) +{ + if (!slave) { + /* + * We are the master cpu and node. + */ + master_nasid = get_nasid(); + set_master_bridge_base(); + FIXME("mlreset: Enable when we support ioc3 .."); +#ifndef CONFIG_IA64_SGI_IO + if (get_console_nasid() == master_nasid) + /* Set up the IOC3 */ + ioc3_mlreset((ioc3_cfg_t *)KL_CONFIG_CH_CONS_INFO(master_nasid)->config_base, + (ioc3_mem_t *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base); + + /* + * Initialize Master nvram base. + */ + nvram_baseinit(); + + fine_mode = is_fine_dirmode(); +#endif /* CONFIG_IA64_SGI_IO */ + + /* We're the master processor */ + master_procid = smp_processor_id(); + master_nasid = cpuid_to_nasid(master_procid); + + /* + * master_nasid we get back better be same as one from + * get_nasid() + */ + ASSERT_ALWAYS(master_nasid == get_nasid()); + +#ifndef CONFIG_IA64_SGI_IO + + /* + * Activate when calias is implemented. + */ + /* Set all nodes' calias sizes to 8k */ + for (i = 0; i < maxnodes; i++) { + nasid_t nasid; + int sn; + + nasid = COMPACT_TO_NASID_NODEID(i); + + /* + * Always have node 0 in the region mask, otherwise CALIAS accesses + * get exceptions since the hub thinks it is a node 0 address. + */ + for (sn=0; snpdinfo = (void *)hubinfo; + hubinfo->h_nodepda = npda; + hubinfo->h_cnodeid = node; + hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node); + + printk("init_platform_nodepda: hubinfo 0x%p, &hubinfo->h_crblock 0x%p\n", hubinfo, &hubinfo->h_crblock); + + spin_lock_init(&hubinfo->h_crblock); + + hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid); + npda->xbow_peer = INVALID_NASID; + /* Initialize the linked list of + * router info pointers to the dependent routers + */ + npda->npda_rip_first = NULL; + /* npda_rip_last always points to the place + * where the next element is to be inserted + * into the list + */ + npda->npda_rip_last = &npda->npda_rip_first; + npda->dependent_routers = 0; + npda->module_id = INVALID_MODULE; + + /* + * Initialize the subnodePDA. + */ + for (sn=0; snprof_count = 0; + SNPDA(npda,sn)->next_prof_timeout = 0; +// ajm +#ifndef CONFIG_IA64_SGI_IO + intr_init_vecblk(npda, node, sn); +#endif + } + + npda->vector_unit_busy = 0; + + spin_lock_init(&npda->vector_lock); + init_MUTEX_LOCKED(&npda->xbow_sema); /* init it locked? */ + spin_lock_init(&npda->fprom_lock); + + spin_lock_init(&npda->node_utlbswitchlock); + npda->ni_error_print = 0; +#ifndef CONFIG_IA64_SGI_IO + if (need_utlbmiss_patch) { + npda->node_need_utlbmiss_patch = 1; + npda->node_utlbmiss_patched = 1; + } +#endif + + /* + * Clear out the nasid mask. + */ + for (i = 0; i < NASID_MASK_BYTES; i++) + npda->nasid_mask[i] = 0; + + for (i = 0; i < numnodes; i++) { + nasid_t nasid = COMPACT_TO_NASID_NODEID(i); + + /* Set my mask bit */ + npda->nasid_mask[nasid / 8] |= (1 << nasid % 8); + } + +#ifndef CONFIG_IA64_SGI_IO + npda->node_first_cpu = get_cnode_cpu(node); +#endif + + if (npda->node_first_cpu != CPU_NONE) { + /* + * Count number of cpus only if first CPU is valid. + */ + numcpus_p = &npda->node_num_cpus; + *numcpus_p = 0; + for (i = npda->node_first_cpu; i < MAXCPUS; i++) { + if (CPUID_TO_COMPACT_NODEID(i) != node) + break; + else + (*numcpus_p)++; + } + } else { + npda->node_num_cpus = 0; + } + + /* Allocate memory for the dump stack on each node + * This is useful during nmi handling since we + * may not be guaranteed shared memory at that time + * which precludes depending on a global dump stack + */ +#ifndef CONFIG_IA64_SGI_IO + npda->dump_stack = (uint64_t *)kmem_zalloc_node(DUMP_STACK_SIZE,VM_NOSLEEP, + node); + ASSERT_ALWAYS(npda->dump_stack); + ASSERT(npda->dump_stack); +#endif + /* Initialize the counter which prevents + * both the cpus on a node to proceed with nmi + * handling. + */ +#ifndef CONFIG_IA64_SGI_IO + npda->dump_count = 0; + + /* Setup the (module,slot) --> nic mapping for all the routers + * in the system. This is useful during error handling when + * there is no shared memory. + */ + router_map_init(npda); + + /* Allocate memory for the per-node router traversal queue */ + router_queue_init(npda,node); + npda->sbe_info = kmem_zalloc_node_hint(sizeof (sbe_info_t), 0, node); + ASSERT(npda->sbe_info); + +#ifdef CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC + /* + * Initialize bte info pointers to NULL + */ + for (i = 0; i < BTES_PER_NODE; i++) { + npda->node_bte_info[i] = (bteinfo_t *)NULL; + } +#endif +#endif /* CONFIG_IA64_SGI_IO */ +} + +/* XXX - Move the interrupt stuff to intr.c ? */ +/* + * Set up the platform-dependent fields in the processor pda. + * Must be done _after_ init_platform_nodepda(). + * If we need a lock here, something else is wrong! + */ +// void init_platform_pda(pda_t *ppda, cpuid_t cpu) +void init_platform_pda(cpuid_t cpu) +{ + hub_intmasks_t *intmasks; + cpuinfo_t cpuinfo; + int i; + cnodeid_t cnode; + synergy_da_t *sda; + int which_synergy; + +#ifndef CONFIG_IA64_SGI_IO + /* Allocate per-cpu platform-dependent data */ + cpuinfo = (cpuinfo_t)kmem_alloc_node(sizeof(struct cpuinfo_s), GFP_ATOMIC, cputocnode(cpu)); + ASSERT_ALWAYS(cpuinfo); + ppda->pdinfo = (void *)cpuinfo; + cpuinfo->ci_cpupda = ppda; + cpuinfo->ci_cpuid = cpu; +#endif + + cnode = cpuid_to_cnodeid(cpu); + which_synergy = cpuid_to_synergy(cpu); + sda = Synergy_da_indr[(cnode * 2) + which_synergy]; + // intmasks = &ppda->p_intmasks; + intmasks = &sda->s_intmasks; + +#ifndef CONFIG_IA64_SGI_IO + ASSERT_ALWAYS(&ppda->p_nodepda); +#endif + + /* Clear INT_PEND0 masks. */ + for (i = 0; i < N_INTPEND0_MASKS; i++) + intmasks->intpend0_masks[i] = 0; + + /* Set up pointer to the vector block in the nodepda. */ + /* (Cant use SUBNODEPDA - not working yet) */ + intmasks->dispatch0 = &Nodepdaindr[cnode]->snpda[cputosubnode(cpu)].intr_dispatch0; + intmasks->dispatch1 = &Nodepdaindr[cnode]->snpda[cputosubnode(cpu)].intr_dispatch1; + + /* Clear INT_PEND1 masks. */ + for (i = 0; i < N_INTPEND1_MASKS; i++) + intmasks->intpend1_masks[i] = 0; + + +#ifndef CONFIG_IA64_SGI_IO + /* Don't read the routers unless we're the master. */ + ppda->p_routertick = 0; +#endif + +} + +#if (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && !defined(BRINGUP) /* protect low mem for IP35/7 */ +#error "need protect_hub_calias, protect_nmi_handler_data" +#endif + +#ifndef CONFIG_IA64_SGI_IO +/* + * For now, just protect the first page (exception handlers). We + * may want to protect more stuff later. + */ +void +protect_hub_calias(nasid_t nasid) +{ + paddr_t pa = NODE_OFFSET(nasid) + 0; /* page 0 on node nasid */ + int i; + + for (i = 0; i < MAX_REGIONS; i++) { + if (i == nasid_to_region(nasid)) + continue; +#ifndef BRINGUP + /* Protect the exception handlers. */ + *(__psunsigned_t *)BDPRT_ENTRY(pa, i) = MD_PROT_NO; + + /* Protect the ARCS SPB. */ + *(__psunsigned_t *)BDPRT_ENTRY(pa + 4096, i) = MD_PROT_NO; +#endif + } +} + +/* + * Protect the page of low memory used to communicate with the NMI handler. + */ +void +protect_nmi_handler_data(nasid_t nasid, int slice) +{ + paddr_t pa = NODE_OFFSET(nasid) + NMI_OFFSET(nasid, slice); + int i; + + for (i = 0; i < MAX_REGIONS; i++) { + if (i == nasid_to_region(nasid)) + continue; +#ifndef BRINGUP + *(__psunsigned_t *)BDPRT_ENTRY(pa, i) = MD_PROT_NO; +#endif + } +} +#endif /* CONFIG_IA64_SGI_IO */ + + +#ifdef IRIX +/* + * Protect areas of memory that we access uncached by marking them as + * poisoned so the T5 can't read them speculatively and erroneously + * mark them dirty in its cache only to write them back with old data + * later. + */ +static void +protect_low_memory(nasid_t nasid) +{ + /* Protect low memory directory */ + poison_state_alter_range(KLDIR_ADDR(nasid), KLDIR_SIZE, 1); + + /* Protect klconfig area */ + poison_state_alter_range(KLCONFIG_ADDR(nasid), KLCONFIG_SIZE(nasid), 1); + + /* Protect the PI error spool area. */ + poison_state_alter_range(PI_ERROR_ADDR(nasid), PI_ERROR_SIZE(nasid), 1); + + /* Protect CPU A's cache error eframe area. */ + poison_state_alter_range(TO_NODE_UNCAC(nasid, CACHE_ERR_EFRAME), + CACHE_ERR_AREA_SIZE, 1); + + /* Protect CPU B's area */ + poison_state_alter_range(TO_NODE_UNCAC(nasid, CACHE_ERR_EFRAME) + ^ UALIAS_FLIP_BIT, + CACHE_ERR_AREA_SIZE, 1); +#error "SN1 not handled correctly" +} +#endif /* IRIX */ + +/* + * per_hub_init + * + * This code is executed once for each Hub chip. + */ +void +per_hub_init(cnodeid_t cnode) +{ + uint64_t done; + nasid_t nasid; + nodepda_t *npdap; +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) /* SN1 specific */ + ii_icmr_u_t ii_icmr; + ii_ibcr_u_t ii_ibcr; +#endif +#ifndef CONFIG_IA64_SGI_IO + int i; +#endif + +#ifdef SIMULATED_KLGRAPH + compact_to_nasid_node[0] = 0; + nasid_to_compact_node[0] = 0; + FIXME("per_hub_init: SIMULATED_KLCONFIG: compact_to_nasid_node[0] = 0\n"); +#endif /* SIMULATED_KLGRAPH */ + nasid = COMPACT_TO_NASID_NODEID(cnode); + + ASSERT(nasid != INVALID_NASID); + ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode); + + /* Grab the hub_mask lock. */ + spin_lock(&hub_mask_lock); + + /* Test our bit. */ + if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) { + + /* Turn our bit on in the mask. */ + CNODEMASK_SETB(hub_init_mask, cnode); + } + +#if defined(SN0_HWDEBUG) + hub_config_setup(); +#endif + /* Release the hub_mask lock. */ + spin_unlock(&hub_mask_lock); + + /* + * Do the actual initialization if it hasn't been done yet. + * We don't need to hold a lock for this work. + */ + if (!done) { + npdap = NODEPDA(cnode); + + npdap->hub_chip_rev = get_hub_chiprev(nasid); + +#ifndef CONFIG_IA64_SGI_IO + for (i = 0; i < CPUS_PER_NODE; i++) { + cpu = cnode_slice_to_cpuid(cnode, i); + if (!cpu_enabled(cpu)) + SET_CPU_LEDS(nasid, i, 0xf); + } +#endif /* CONFIG_IA64_SGI_IO */ + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) /* SN1 specific */ + + /* + * Set the total number of CRBs that can be used. + */ + ii_icmr.ii_icmr_regval= 0x0; + ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF; + REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval); + + /* + * Set the number of CRBs that both of the BTEs combined + * can use minus 1. + */ + ii_ibcr.ii_ibcr_regval= 0x0; + ii_ibcr.ii_ibcr_fld_s.i_count = 0x8; + REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval); + + /* + * Set CRB timeout to be 10ms. + */ + REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 ); + REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); + +#endif /* SN0_HWDEBUG */ + + +#ifndef CONFIG_IA64_SGI_IO + + /* Reserve all of the hardwired interrupt levels. */ + intr_reserve_hardwired(cnode); + + /* Initialize error interrupts for this hub. */ + hub_error_init(cnode); + + /* Set up correctable memory/directory ECC error interrupt. */ + install_eccintr(cnode); + + /* Protect our exception vectors from accidental corruption. */ + protect_hub_calias(nasid); + + /* Enable RT clock interrupts */ + hub_rtc_init(cnode); + hub_migrintr_init(cnode); /* Enable migration interrupt */ +#endif + + spin_lock(&hub_mask_lock); + CNODEMASK_SETB(hub_init_done_mask, cnode); + spin_unlock(&hub_mask_lock); + + } else { + /* + * Wait for the other CPU to complete the initialization. + */ + while (CNODEMASK_TSTB(hub_init_done_mask, cnode) == 0) + /* LOOP */ + ; + } +} + +extern void +update_node_information(cnodeid_t cnodeid) +{ + nodepda_t *npda = NODEPDA(cnodeid); + nodepda_router_info_t *npda_rip; + + /* Go through the list of router info + * structures and copy some frequently + * accessed info from the info hanging + * off the corresponding router vertices + */ + npda_rip = npda->npda_rip_first; + while(npda_rip) { + if (npda_rip->router_infop) { + npda_rip->router_portmask = + npda_rip->router_infop->ri_portmask; + npda_rip->router_slot = + npda_rip->router_infop->ri_slotnum; + } else { + /* No router, no ports. */ + npda_rip->router_portmask = 0; + } + npda_rip = npda_rip->router_next; + } +} + +hubreg_t +get_region(cnodeid_t cnode) +{ + if (fine_mode) + return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; + else + return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; +} + +hubreg_t +nasid_to_region(nasid_t nasid) +{ + if (fine_mode) + return nasid >> NASID_TO_FINEREG_SHFT; + else + return nasid >> NASID_TO_COARSEREG_SHFT; +} + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/ml_SN_intr.c linux-2.4.0-test12-lia/arch/ia64/sn/io/ml_SN_intr.c --- linux-2.4.0-test12/arch/ia64/sn/io/ml_SN_intr.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/ml_SN_intr.c Wed Dec 13 18:59:33 2000 @@ -0,0 +1,1738 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Alan Mayer + */ + +/* + * intr.c- + * This file contains all of the routines necessary to set up and + * handle interrupts on an IP27 board. + */ + +#ident "$Revision: 1.167 $" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if defined (CONFIG_SGI_IP35) + +#include /* For SN1 + pcibr Addressing Limitation */ +#include /* For SN1 + pcibr Addressing Limitation */ +#include /* For SN1 + pcibr Addressing Limitation */ +#endif /* SN1 */ + +#if DEBUG_INTR_TSTAMP_DEBUG +#include +#include +#include +void do_splx_log(int, int); +void spldebug_log_event(int); +#endif + +// FIXME - BRINGUP +#ifdef CONFIG_SMP +extern unsigned long cpu_online_map; +#endif +#define cpu_allows_intr(cpu) (1) +// If I understand what's going on with this, 32 should work. +// physmem_maxradius seems to be the maximum number of router +// hops to get from one end of the system to the other. With +// a maximally configured machine, with the dumbest possible +// topology, we would make 32 router hops. For what we're using +// it for, the dumbest possible should suffice. +#define physmem_maxradius() 32 + +#define SUBNODE_ANY -1 + +extern int nmied; +extern int hub_intr_wakeup_cnt; +extern synergy_da_t *Synergy_da_indr[]; +extern cpuid_t master_procid; + +extern cnodeid_t master_node_get(devfs_handle_t vhdl); + + +#define INTR_LOCK(vecblk) \ + (s = mutex_spinlock(&(vecblk)->vector_lock)) +#define INTR_UNLOCK(vecblk) \ + mutex_spinunlock(&(vecblk)->vector_lock, s) + +/* + * REACT/Pro + */ + + + +/* + * Find first bit set + * Used outside this file also + */ +int ms1bit(unsigned long x) +{ + int b; + + if (x >> 32) b = 32, x >>= 32; + else b = 0; + if (x >> 16) b += 16, x >>= 16; + if (x >> 8) b += 8, x >>= 8; + if (x >> 4) b += 4, x >>= 4; + if (x >> 2) b += 2, x >>= 2; + + return b + (int) (x >> 1); +} + +/* ARGSUSED */ +void +intr_stray(void *lvl) +{ + printk("Stray Interrupt - level %ld to cpu %d", (long)lvl, cpuid()); +} + +#if defined(DEBUG) + +/* Infrastructure to gather the device - target cpu mapping info */ +#define MAX_DEVICES 1000 /* Reasonable large number . Need not be + * the exact maximum # devices possible. + */ +#define MAX_NAME 100 +typedef struct { + dev_t dev; /* device */ + cpuid_t cpuid; /* target cpu */ + cnodeid_t cnodeid;/* node on which the target cpu is present */ + int bit; /* intr bit reserved */ + char intr_name[MAX_NAME]; /* name of the interrupt */ +} intr_dev_targ_map_t; + +intr_dev_targ_map_t intr_dev_targ_map[MAX_DEVICES]; +uint64_t intr_dev_targ_map_size; +lock_t intr_dev_targ_map_lock; + +/* Print out the device - target cpu mapping. + * This routine is used only in the idbg command + * "intrmap" + */ +void +intr_dev_targ_map_print(cnodeid_t cnodeid) +{ + int i,j,size = 0; + int print_flag = 0,verbose = 0; + char node_name[10]; + + if (cnodeid != CNODEID_NONE) { + nodepda_t *npda; + + npda = NODEPDA(cnodeid); + for (j=0; jintr_dispatch0.info[i].ii_flags); + qprintf("\n INT_PEND1: "); + for(i = 0 ; i < N_INTPEND_BITS ; i++) + qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags); + } + verbose = 1; + } + qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n", + (verbose ? "All" : "Non-hardwired"), + (cnodeid == CNODEID_NONE) ? "s: All" : node_name); + + qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n"); + for (i = 0 ; i < intr_dev_targ_map_size ; i++) { + + print_flag = 0; + if (verbose) { + if (cnodeid != CNODEID_NONE) { + if (cnodeid == intr_dev_targ_map[i].cnodeid) + print_flag = 1; + } else { + print_flag = 1; + } + } else { + if (intr_dev_targ_map[i].dev != 0) { + if (cnodeid != CNODEID_NONE) { + if (cnodeid == + intr_dev_targ_map[i].cnodeid) + print_flag = 1; + } else { + print_flag = 1; + } + } + } + if (print_flag) { + size++; + qprintf("%d\t%d\t%d\t%d\t%s\n", + intr_dev_targ_map[i].dev, + intr_dev_targ_map[i].cpuid, + intr_dev_targ_map[i].cnodeid, + intr_dev_targ_map[i].bit, + intr_dev_targ_map[i].intr_name); + } + + } + qprintf("\nTotal : %d\n",size); +} +#endif /* DEBUG */ + +/* + * The spinlocks have already been initialized. Now initialize the interrupt + * vectors. One processor on each hub does the work. + */ +void +intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn) +{ + int i, ip=0; + intr_vecblk_t *vecblk; + subnode_pda_t *snpda; + + + snpda = SNPDA(npda,sn); + do { + if (ip == 0) { + vecblk = &snpda->intr_dispatch0; + } else { + vecblk = &snpda->intr_dispatch1; + } + + /* Initialize this vector. */ + for (i = 0; i < N_INTPEND_BITS; i++) { + vecblk->vectors[i].iv_func = intr_stray; + vecblk->vectors[i].iv_prefunc = NULL; + vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i); + + vecblk->info[i].ii_owner_dev = 0; + strcpy(vecblk->info[i].ii_name, "Unused"); + vecblk->info[i].ii_flags = 0; /* No flags */ + vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */ + + } + + spinlock_init(&vecblk->vector_lock, "ivecb"); + + vecblk->vector_count = 0; + for (i = 0; i < CPUS_PER_SUBNODE; i++) + vecblk->cpu_count[i] = 0; + + vecblk->vector_state = VECTOR_UNINITED; + + } while (++ip < 2); + +} + + +/* + * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, + * devfs_handle_t owner_dev, char *name) + * Internal work routine to reserve or unreserve an interrupt level. + * cpu is the CPU to which the interrupt will be sent. + * bit is the level bit to reserve. -1 means any level + * resflags should include II_ERRORINT if this is an + * error interrupt, II_THREADED if the interrupt handler + * will be threaded, or 0 otherwise. + * reserve should be set to II_RESERVE or II_UNRESERVE + * to get or clear a reservation. + * owner_dev is the device that "owns" this interrupt, if supplied + * name is a human-readable name for this interrupt, if supplied + * intr_reserve_level returns the bit reserved or -1 to indicate an error + */ +static int +do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, + devfs_handle_t owner_dev, char *name) +{ + intr_vecblk_t *vecblk; + hub_intmasks_t *hub_intmasks; + int s; + int rv = 0; + int ip; + synergy_da_t *sda; + int which_synergy; + cnodeid_t cnode; + + ASSERT(bit < N_INTPEND_BITS * 2); + + cnode = cpuid_to_cnodeid(cpu); + which_synergy = cpuid_to_synergy(cpu); + sda = Synergy_da_indr[(cnode * 2) + which_synergy]; + hub_intmasks = &sda->s_intmasks; + // hub_intmasks = &pdaindr[cpu].pda->p_intmasks; + + // if (pdaindr[cpu].pda == NULL) return -1; + if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) { + vecblk = hub_intmasks->dispatch0; + ip = 0; + } else { + ASSERT((bit >= N_INTPEND_BITS) || (bit == -1)); + bit -= N_INTPEND_BITS; /* Get position relative to INT_PEND1 reg. */ + vecblk = hub_intmasks->dispatch1; + ip = 1; + } + + INTR_LOCK(vecblk); + + if (bit <= -1) { + // bit = 0; + bit = 7; /* First available on SNIA */ + ASSERT(reserve == II_RESERVE); + /* Choose any available level */ + for (; bit < N_INTPEND_BITS; bit++) { + if (!(vecblk->info[bit].ii_flags & II_RESERVE)) { + rv = bit; + break; + } + } + + /* Return -1 if all interrupt levels int this register are taken. */ + if (bit == N_INTPEND_BITS) + rv = -1; + + } else { + /* Reserve a particular level if it's available. */ + if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) { + /* Can't (un)reserve a level that's already (un)reserved. */ + rv = -1; + } else { + rv = bit; + } + } + + /* Reserve the level and bump the count. */ + if (rv != -1) { + if (reserve) { + int maxlen = sizeof(vecblk->info[bit].ii_name) - 1; + int namelen; + vecblk->info[bit].ii_flags |= (II_RESERVE | resflags); + vecblk->info[bit].ii_owner_dev = owner_dev; + /* Copy in the name. */ + namelen = name ? strlen(name) : 0; + strncpy(vecblk->info[bit].ii_name, name, MIN(namelen, maxlen)); + vecblk->info[bit].ii_name[maxlen] = '\0'; + vecblk->vector_count++; + } else { + vecblk->info[bit].ii_flags = 0; /* Clear all the flags */ + vecblk->info[bit].ii_owner_dev = 0; + /* Clear the name. */ + vecblk->info[bit].ii_name[0] = '\0'; + vecblk->vector_count--; + } + } + + INTR_UNLOCK(vecblk); + +#if defined(DEBUG) + if (rv >= 0) { + int namelen = name ? strlen(name) : 0; + /* Gather this device - target cpu mapping information + * in a table which can be used later by the idbg "intrmap" + * command + */ + s = mutex_spinlock(&intr_dev_targ_map_lock); + if (intr_dev_targ_map_size < MAX_DEVICES) { + intr_dev_targ_map_t *p; + + p = &intr_dev_targ_map[intr_dev_targ_map_size]; + p->dev = owner_dev; + p->cpuid = cpu; + p->cnodeid = cputocnode(cpu); + p->bit = ip * N_INTPEND_BITS + rv; + strncpy(p->intr_name, + name, + MIN(MAX_NAME,namelen)); + intr_dev_targ_map_size++; + } + mutex_spinunlock(&intr_dev_targ_map_lock,s); + } +#endif /* DEBUG */ + + return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ; +} + + +/* + * WARNING: This routine should only be called from within ml/SN. + * Reserve an interrupt level. + */ +int +intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name) +{ + return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name)); +} + + +/* + * WARNING: This routine should only be called from within ml/SN. + * Unreserve an interrupt level. + */ +void +intr_unreserve_level(cpuid_t cpu, int bit) +{ + (void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL); +} + +/* + * Get values that vary depending on which CPU and bit we're operating on + */ +static hub_intmasks_t * +intr_get_ptrs(cpuid_t cpu, int bit, + int *new_bit, /* Bit relative to the register */ + hubreg_t **intpend_masks, /* Masks for this register */ + intr_vecblk_t **vecblk, /* Vecblock for this interrupt */ + int *ip) /* Which intpend register */ +{ + hub_intmasks_t *hub_intmasks; + synergy_da_t *sda; + int which_synergy; + cnodeid_t cnode; + + ASSERT(bit < N_INTPEND_BITS * 2); + + cnode = cpuid_to_cnodeid(cpu); + which_synergy = cpuid_to_synergy(cpu); + sda = Synergy_da_indr[(cnode * 2) + which_synergy]; + hub_intmasks = &sda->s_intmasks; + + // hub_intmasks = &pdaindr[cpu].pda->p_intmasks; + + if (bit < N_INTPEND_BITS) { + *intpend_masks = hub_intmasks->intpend0_masks; + *vecblk = hub_intmasks->dispatch0; + *ip = 0; + *new_bit = bit; + } else { + *intpend_masks = hub_intmasks->intpend1_masks; + *vecblk = hub_intmasks->dispatch1; + *ip = 1; + *new_bit = bit - N_INTPEND_BITS; + } + + return hub_intmasks; +} + + +/* + * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, + * intr_func_t intr_func, void *intr_arg); + * This is the lowest-level interface to the interrupt code. It shouldn't + * be called from outside the ml/SN directory. + * intr_connect_level hooks up an interrupt to a particular bit in + * the INT_PEND0/1 masks. Returns 0 on success. + * cpu is the CPU to which the interrupt will be sent. + * bit is the level bit to connect to + * intr_swlevel tells which software level to use + * intr_func is the interrupt handler + * intr_arg is an arbitrary argument interpreted by the handler + * intr_prefunc is a prologue function, to be called + * with interrupts disabled, to disable + * the interrupt at source. It is called + * with the same argument. Should be NULL for + * typical interrupts, which can be masked + * by the infrastructure at the level bit. + * intr_connect_level returns 0 on success or nonzero on an error + */ +/* ARGSUSED */ +int +intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, + intr_func_t intr_func, void *intr_arg, + intr_func_t intr_prefunc) +{ + intr_vecblk_t *vecblk; + hubreg_t *intpend_masks; + int s; + int rv = 0; + int ip; + + ASSERT(bit < N_INTPEND_BITS * 2); + + (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, + &vecblk, &ip); + + INTR_LOCK(vecblk); + + if ((vecblk->info[bit].ii_flags & II_INUSE) || + (!(vecblk->info[bit].ii_flags & II_RESERVE))) { + /* Can't assign to a level that's in use or isn't reserved. */ + rv = -1; + } else { + /* Stuff parameters into vector and info */ + vecblk->vectors[bit].iv_func = intr_func; + vecblk->vectors[bit].iv_prefunc = intr_prefunc; + vecblk->vectors[bit].iv_arg = intr_arg; + vecblk->info[bit].ii_flags |= II_INUSE; + } + + /* Now stuff the masks if everything's okay. */ + if (!rv) { + int lslice; + volatile hubreg_t *mask_reg; + // nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu)); + nasid_t nasid = cpuid_to_nasid(cpu); + int subnode = cpuid_to_subnode(cpu); + + /* Make sure it's not already pending when we connect it. */ + REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS); + + intpend_masks[0] |= (1ULL << (uint64_t)bit); + + lslice = cputolocalslice(cpu); + vecblk->cpu_count[lslice]++; +#if SN1 + /* + * On SN1, there are 8 interrupt mask registers per node: + * PI_0 MASK_0 A + * PI_0 MASK_1 A + * PI_0 MASK_0 B + * PI_0 MASK_1 B + * PI_1 MASK_0 A + * PI_1 MASK_1 A + * PI_1 MASK_0 B + * PI_1 MASK_1 B + */ +#endif + if (ip == 0) { + mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, + PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice); + } else { + mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, + PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice); + } + + HUB_S(mask_reg, intpend_masks[0]); + } + + INTR_UNLOCK(vecblk); + + return rv; +} + + +/* + * intr_disconnect_level(cpuid_t cpu, int bit) + * + * This is the lowest-level interface to the interrupt code. It should + * not be called from outside the ml/SN directory. + * intr_disconnect_level removes a particular bit from an interrupt in + * the INT_PEND0/1 masks. Returns 0 on success or nonzero on failure. + */ +int +intr_disconnect_level(cpuid_t cpu, int bit) +{ + intr_vecblk_t *vecblk; + hubreg_t *intpend_masks; + int s; + int rv = 0; + int ip; + + (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, + &vecblk, &ip); + + INTR_LOCK(vecblk); + + if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) != + ((II_RESERVE | II_INUSE))) { + /* Can't remove a level that's not in use or isn't reserved. */ + rv = -1; + } else { + /* Stuff parameters into vector and info */ + vecblk->vectors[bit].iv_func = (intr_func_t)NULL; + vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL; + vecblk->vectors[bit].iv_arg = 0; + vecblk->info[bit].ii_flags &= ~II_INUSE; +#ifdef BASE_ITHRTEAD + vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */ +#endif + } + + /* Now clear the masks if everything's okay. */ + if (!rv) { + int lslice; + volatile hubreg_t *mask_reg; + + intpend_masks[0] &= ~(1ULL << (uint64_t)bit); + lslice = cputolocalslice(cpu); + vecblk->cpu_count[lslice]--; + mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(cpu)), + cpuid_to_subnode(cpu), + ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A); + mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg + + (PI_INT_MASK_OFFSET * lslice)); + *mask_reg = intpend_masks[0]; + } + + INTR_UNLOCK(vecblk); + + return rv; +} + +/* + * Actually block or unblock an interrupt + */ +void +do_intr_block_bit(cpuid_t cpu, int bit, int block) +{ + intr_vecblk_t *vecblk; + int s; + int ip; + hubreg_t *intpend_masks; + volatile hubreg_t mask_value; + volatile hubreg_t *mask_reg; + + intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip); + + INTR_LOCK(vecblk); + + if (block) + /* Block */ + intpend_masks[0] &= ~(1ULL << (uint64_t)bit); + else + /* Unblock */ + intpend_masks[0] |= (1ULL << (uint64_t)bit); + + if (ip == 0) { + mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(cpu)), + cpuid_to_subnode(cpu), PI_INT_MASK0_A); + } else { + mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(cpu)), + cpuid_to_subnode(cpu), PI_INT_MASK1_A); + } + + HUB_S(mask_reg, intpend_masks[0]); + + /* + * Wait for it to take effect. (One read should suffice.) + * This is only necessary when blocking an interrupt + */ + if (block) + while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0]) + ; + + INTR_UNLOCK(vecblk); +} + + +/* + * Block a particular interrupt (cpu/bit pair). + */ +/* ARGSUSED */ +void +intr_block_bit(cpuid_t cpu, int bit) +{ + do_intr_block_bit(cpu, bit, 1); +} + + +/* + * Unblock a particular interrupt (cpu/bit pair). + */ +/* ARGSUSED */ +void +intr_unblock_bit(cpuid_t cpu, int bit) +{ + do_intr_block_bit(cpu, bit, 0); +} + + +/* verifies that the specified CPUID is on the specified SUBNODE (if any) */ +#define cpu_on_subnode(cpuid, which_subnode) \ + (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode))) + + +/* + * Choose one of the CPUs on a specified node or subnode to receive + * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu. + * + * Among all acceptable CPUs, the CPU that has the fewest total number + * of interrupts targetted towards it is chosen. Note that we never + * consider how frequent each of these interrupts might occur, so a rare + * hardware error interrupt is weighted equally with a disk interrupt. + */ +static cpuid_t +do_intr_cpu_choose(cnodeid_t cnode, int which_subnode) +{ + cpuid_t cpu, best_cpu = CPU_NONE; + int slice, min_count=1000; + + min_count = 1000; + for (slice=0; slice < CPUS_PER_NODE; slice++) { + intr_vecblk_t *vecblk0, *vecblk1; + int total_intrs_to_slice; + subnode_pda_t *snpda; + int local_cpu_num; + + cpu = cnode_slice_to_cpuid(cnode, slice); + cpu = cpu_logical_id(cpu); + if (cpu == CPU_NONE) + continue; + + /* If this cpu isn't enabled for interrupts, skip it */ + if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu)) + continue; + + /* If this isn't the right subnode, skip it */ + if (!cpu_on_subnode(cpu, which_subnode)) + continue; + + /* OK, this one's a potential CPU for interrupts */ + snpda = SUBNODEPDA(cnode,SUBNODE(slice)); + vecblk0 = &snpda->intr_dispatch0; + vecblk1 = &snpda->intr_dispatch1; + local_cpu_num = LOCALCPU(slice); + total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] + + vecblk1->cpu_count[local_cpu_num]; + + if (min_count > total_intrs_to_slice) { + min_count = total_intrs_to_slice; + best_cpu = cpu; + } + } + return best_cpu; +} + +/* + * Choose an appropriate interrupt target CPU on a specified node. + * If which_subnode is SUBNODE_ANY, then subnode is not considered. + * Otherwise, the chosen CPU must be on the specified subnode. + */ +static cpuid_t +intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode) +{ + return(do_intr_cpu_choose(cnode, which_subnode)); +} + + +#ifndef CONFIG_IA64_SGI_IO +/* + * Convert a subnode vertex into a (cnodeid, which_subnode) pair. + * Return 0 on success, non-zero on failure. + */ +static int +subnodevertex_to_subnode(devfs_handle_t vhdl, cnodeid_t *cnodeidp, int *which_subnodep) +{ + arbitrary_info_t which_subnode; + cnodeid_t cnodeid; + + /* Try to grab subnode information */ + if (hwgraph_info_get_LBL(vhdl, INFO_LBL_CPUBUS, &which_subnode) != GRAPH_SUCCESS) + return(-1); + + /* On which node? */ + cnodeid = master_node_get(vhdl); + if (cnodeid == CNODEID_NONE) + return(-1); + + *which_subnodep = (int)which_subnode; + *cnodeidp = cnodeid; + return(0); /* success */ +} + +#endif /* CONFIG_IA64_SGI_IO */ + +/* Make it easy to identify subnode vertices in the hwgraph */ +void +mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode) +{ + graph_error_t rv; + + ASSERT(0 <= which_subnode); + ASSERT(which_subnode < NUM_SUBNODES); + + rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode); + ASSERT_ALWAYS(rv == GRAPH_SUCCESS); + + rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t)); + ASSERT_ALWAYS(rv == GRAPH_SUCCESS); +} + + +#ifndef CONFIG_IA64_SGI_IO +/* + * Given a device descriptor, extract interrupt target information and + * choose an appropriate CPU. Return CPU_NONE if we can't make sense + * out of the target information. + * TBD: Should this be considered platform-independent code? + */ +static cpuid_t +intr_target_from_desc(device_desc_t dev_desc, int favor_subnode) +{ + cpuid_t cpuid = CPU_NONE; + cnodeid_t cnodeid; + int which_subnode; + devfs_handle_t intr_target_dev; + + if ((intr_target_dev = device_desc_intr_target_get(dev_desc)) != GRAPH_VERTEX_NONE) { + /* + * A valid device was specified. If it's a particular + * CPU, then use that CPU as target. + */ + cpuid = cpuvertex_to_cpuid(intr_target_dev); + if (cpuid != CPU_NONE) + goto cpuchosen; + + /* If a subnode vertex was specified, pick a CPU on that subnode. */ + if (subnodevertex_to_subnode(intr_target_dev, &cnodeid, &which_subnode) == 0) { + cpuid = intr_cpu_choose_from_node(cnodeid, which_subnode); + goto cpuchosen; + } + + /* + * Otherwise, pick a CPU on the node that owns the + * specified target. Favor "favor_subnode", if specified. + */ + cnodeid = master_node_get(intr_target_dev); + if (cnodeid != CNODEID_NONE) { + cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode); + goto cpuchosen; + } + } + +cpuchosen: + return(cpuid); +} +#endif /* CONFIG_IA64_SGI_IO */ + + +#ifndef CONFIG_IA64_SGI_IO +/* + * Check if we had already visited this candidate cnode + */ +static void * +intr_cnode_seen(cnodeid_t candidate, + void *arg1, + void *arg2) +{ + int i; + cnodeid_t *visited_cnodes = (cnodeid_t *)arg1; + int *num_visited_cnodes = (int *)arg2; + + ASSERT(visited_cnodes); + ASSERT(*num_visited_cnodes <= numnodes); + for(i = 0 ; i < *num_visited_cnodes; i++) { + if (candidate == visited_cnodes[i]) + return(NULL); + } + return(visited_cnodes); +} + +#endif /* CONFIG_IA64_SGI_IO */ + + + +/* + * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags, + * owner_dev,intr_name,*resp_bit) + * Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but + * not both. + * 1. If cpuid is specified, this routine tests if this cpu can be a valid + * interrupt target candidate. + * 2. If cnodeid is specified, this routine tests if there is a cpu on + * this node which can be a valid interrupt target candidate. + * 3. If a valid interrupt target cpu candidate is found then an attempt at + * reserving an interrupt bit on the corresponding cnode is made. + * + * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid + * interrupt target cpu then routine returns CPU_NONE (failure) + * Otherwise routine returns cpuid of interrupt target (success) + */ +static cpuid_t +intr_bit_reserve_test(cpuid_t cpuid, + int favor_subnode, + cnodeid_t cnodeid, + int req_bit, + int intr_resflags, + devfs_handle_t owner_dev, + char *intr_name, + int *resp_bit) +{ + + ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE)); + + if (cnodeid != CNODEID_NONE) { + /* Try to choose a interrupt cpu candidate */ + cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode); + } + + if (cpuid != CPU_NONE) { + /* Try to reserve an interrupt bit on the hub + * corresponding to the canidate cnode. If we + * are successful then we got a cpu which can + * act as an interrupt target for the io device. + * Otherwise we need to continue the search + * further. + */ + *resp_bit = do_intr_reserve_level(cpuid, + req_bit, + intr_resflags, + II_RESERVE, + owner_dev, + intr_name); + + if (*resp_bit >= 0) + /* The interrupt target specified was fine */ + return(cpuid); + } + return(CPU_NONE); +} +/* + * intr_heuristic(dev_t dev,device_desc_t dev_desc, + * int req_bit,int intr_resflags,dev_t owner_dev, + * char *intr_name,int *resp_bit) + * + * Choose an interrupt destination for an interrupt. + * dev is the device for which the interrupt is being set up + * dev_desc is a description of hardware and policy that could + * help determine where this interrupt should go + * req_bit is the interrupt bit requested + * (can be INTRCONNECT_ANY_BIT in which the first available + * interrupt bit is used) + * intr_resflags indicates whether we want to (un)reserve bit + * owner_dev is the owner device + * intr_name is the readable interrupt name + * resp_bit indicates whether we succeeded in getting the required + * action { (un)reservation} done + * negative value indicates failure + * + */ +/* ARGSUSED */ +cpuid_t +intr_heuristic(devfs_handle_t dev, + device_desc_t dev_desc, + int req_bit, + int intr_resflags, + devfs_handle_t owner_dev, + char *intr_name, + int *resp_bit) +{ + cpuid_t cpuid; /* possible intr targ*/ + cnodeid_t candidate; /* possible canidate */ +#ifndef BRINGUP + cnodeid_t visited_cnodes[MAX_NASIDS], /* nodes seen so far */ + center, /* node we are on */ + candidate; /* possible canidate */ + int num_visited_cnodes = 0; /* # nodes seen */ + + int radius = 1, /* start looking at the + * current node + */ + maxradius = physmem_maxradius(); + void *rv; +#endif /* BRINGUP */ + int which_subnode = SUBNODE_ANY; + +#if CONFIG_IA64_SGI_IO /* SN1 + pcibr Addressing Limitation */ + { + devfs_handle_t pconn_vhdl; + pcibr_soft_t pcibr_soft; + + /* + * This combination of SN1 and Bridge hardware has an odd "limitation". + * Due to the choice of addresses for PI0 and PI1 registers on SN1 + * and historical limitations in Bridge, Bridge is unable to + * send interrupts to both PI0 CPUs and PI1 CPUs -- we have + * to choose one set or the other. That choice is implicitly + * made when Bridge first attaches its error interrupt. After + * that point, all subsequent interrupts are restricted to the + * same PI number (though it's possible to send interrupts to + * the same PI number on a different node). + * + * Since neither SN1 nor Bridge designers are willing to admit a + * bug, we can't really call this a "workaround". It's a permanent + * solution for an SN1-specific and Bridge-specific hardware + * limitation that won't ever be lifted. + */ + if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) && + ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) { + /* + * We "know" that the error interrupt is the first + * interrupt set up by pcibr_attach. Send all interrupts + * on this bridge to the same subnode number. + */ + if (pcibr_soft->bsi_err_intr) { + which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid); + } + } + } +#endif /* CONFIG_IA64_SGI_IO */ + +#ifndef CONFIG_IA64_SGI_IO + /* + * If an interrupt target was specified for this + * interrupt allocation, try to use it. + */ + if (dev_desc) { + + /* Try to see if the interrupt target specified in the + * device descriptor is a legal candidate. + */ + cpuid = intr_bit_reserve_test(intr_target_from_desc(dev_desc, which_subnode), + which_subnode, + CNODEID_NONE, + req_bit, + intr_resflags, + owner_dev, + intr_name, + resp_bit); + + if (cpuid != CPU_NONE) { + if (cpu_on_subnode(cpuid, which_subnode)) + return(cpuid); /* got a valid interrupt target */ + + printk("Override explicit interrupt targetting: %v (0x%x)\n", + owner_dev, owner_dev); + + intr_unreserve_level(cpuid, *resp_bit); + } + + /* Fall through on to the next step in the search for + * the interrupt candidate. + */ + + } +#endif /* CONFIG_IA64_SGI_IO */ + + /* Check if we can find a valid interrupt target candidate on + * the master node for the device. + */ + cpuid = intr_bit_reserve_test(CPU_NONE, + which_subnode, + master_node_get(dev), + req_bit, + intr_resflags, + owner_dev, + intr_name, + resp_bit); + + if (cpuid != CPU_NONE) { + if (cpu_on_subnode(cpuid, which_subnode)) + return(cpuid); /* got a valid interrupt target */ + else + intr_unreserve_level(cpuid, *resp_bit); + } + + printk("Cannot target interrupts to closest node(%d): %ld (0x%lx)\n", + master_node_get(dev),(long) owner_dev, (unsigned long)owner_dev); + + /* Fall through into the default algorithm + * (exhaustive-search-for-the-nearest-possible-interrupt-target) + * for finding the interrupt target + */ + +#ifndef BRINGUP + // Use of this algorithm is deferred until the supporting + // code has been implemented. + /* + * No valid interrupt specification exists. + * Try to find a node which is closest to the current node + * which can process interrupts from a device + */ + + center = cpuid_to_cnodeid(smp_processor_id()); + while (radius <= maxradius) { + + /* Try to find a node at the given radius and which + * we haven't seen already. + */ + rv = physmem_select_neighbor_node(center,radius,&candidate, + intr_cnode_seen, + (void *)visited_cnodes, + (void *)&num_visited_cnodes); + if (!rv) { + /* We have seen all the nodes at this particular radius + * Go on to the next radius level. + */ + radius++; + continue; + } + /* We are seeing this candidate cnode for the first time + */ + visited_cnodes[num_visited_cnodes++] = candidate; + + cpuid = intr_bit_reserve_test(CPU_NONE, + which_subnode, + candidate, + req_bit, + intr_resflags, + owner_dev, + intr_name, + resp_bit); + + if (cpuid != CPU_NONE) { + if (cpu_on_subnode(cpuid, which_subnode)) + return(cpuid); /* got a valid interrupt target */ + else + intr_unreserve_level(cpuid, *resp_bit); + } + } +#else /* BRINGUP */ + { + // Do a stupid round-robin assignment of the node. + static cnodeid_t last_node = 0; + + if (last_node > numnodes) last_node = 0; + for (candidate = last_node; candidate <= numnodes; candidate++) { + cpuid = intr_bit_reserve_test(CPU_NONE, + which_subnode, + candidate, + req_bit, + intr_resflags, + owner_dev, + intr_name, + resp_bit); + + if (cpuid != CPU_NONE) { + if (cpu_on_subnode(cpuid, which_subnode)) { + last_node++; + return(cpuid); /* got a valid interrupt target */ + } + else + intr_unreserve_level(cpuid, *resp_bit); + } + last_node++; + } + } +#endif + + printk("Cannot target interrupts to any close node: %ld (0x%lx)\n", + (long)owner_dev, (unsigned long)owner_dev); + + /* In the worst case try to allocate interrupt bits on the + * master processor's node. We may get here during error interrupt + * allocation phase when the topology matrix is not yet setup + * and hence cannot do an exhaustive search. + */ + ASSERT(cpu_allows_intr(master_procid)); + cpuid = intr_bit_reserve_test(master_procid, + which_subnode, + CNODEID_NONE, + req_bit, + intr_resflags, + owner_dev, + intr_name, + resp_bit); + + if (cpuid != CPU_NONE) { + if (cpu_on_subnode(cpuid, which_subnode)) + return(cpuid); + else + intr_unreserve_level(cpuid, *resp_bit); + } + + printk("Cannot target interrupts: %ld (0x%lx)\n", + (long)owner_dev, (unsigned long)owner_dev); + + return(CPU_NONE); /* Should never get here */ +} + + + + +#ifndef BRINGUP +/* + * Should never receive an exception while running on the idle + * stack. It IS possible to handle *interrupts* while on the + * idle stack, but a non-interrupt *exception* is a problem. + */ +void +idle_err(inst_t *epc, uint cause, void *fep, void *sp) +{ + eframe_t *ep = (eframe_t *)fep; + + if ((cause & CAUSE_EXCMASK) == EXC_IBE || + (cause & CAUSE_EXCMASK) == EXC_DBE) { + (void)dobuserre((eframe_t *)ep, epc, 0); + } + + /* XXX - This will have to change to deal with various SN errors. */ + panic( "exception on IDLE stack " + "ep:0x%x epc:0x%x cause:0x%w32x sp:0x%x badvaddr:0x%x", + ep, epc, cause, sp, getbadvaddr()); + /* NOTREACHED */ +} + + +/* + * earlynofault - handle very early global faults - usually just while + * sizing memory + * Returns: 1 if should do nofault + * 0 if not + */ +/* ARGSUSED */ +int +earlynofault(eframe_t *ep, uint code) +{ + switch(code) { + case EXC_DBE: + return(1); + default: + return(0); + } +} + + + +/* ARGSUSED */ +static void +cpuintr(void *arg1, void *arg2) +{ +#if RTE + static int rte_intrdebug = 1; +#endif + /* + * Frame Scheduler + */ + LOG_TSTAMP_EVENT(RTMON_INTR, TSTAMP_EV_CPUINTR, NULL, NULL, + NULL, NULL); + + /* + * Hardware clears the IO interrupts, but we need to clear software- + * generated interrupts. + */ + LOCAL_HUB_CLR_INTR(CPU_ACTION_A + cputolocalslice(cpuid())); + +#if 0 + /* XXX - Handle error interrupts. */ + if (error_intr_reason) + error_intr(); +#endif /* 0 */ + + /* + * If we're headed for panicspin and it is due to a NMI, save the + * eframe in the NMI area + */ + if (private.p_va_panicspin && nmied) { + caddr_t nmi_save_area; + + nmi_save_area = (caddr_t) (TO_UNCAC(TO_NODE( + cputonasid(cpuid()), IP27_NMI_EFRAME_OFFSET)) + + cputoslice(cpuid()) * IP27_NMI_EFRAME_SIZE); + bcopy((caddr_t) arg2, nmi_save_area, sizeof(eframe_t)); + } + + doacvec(); +#if RTE + if (private.p_flags & PDAF_ISOLATED && !rte_intrdebug) + goto end_cpuintr; +#endif + doactions(); +#if RTE +end_cpuintr: +#endif + LOG_TSTAMP_EVENT(RTMON_INTR, TSTAMP_EV_INTREXIT, TSTAMP_EV_CPUINTR, NULL, NULL, NULL); +} + +void +install_cpuintr(cpuid_t cpu) +{ + int intr_bit = CPU_ACTION_A + cputolocalslice(cpu); + + if (intr_connect_level(cpu, intr_bit, INTPEND0_MAXMASK, + (intr_func_t) cpuintr, NULL, NULL)) + panic("install_cpuintr: Can't connect interrupt."); +} +#endif /* BRINGUP */ + +#ifdef DEBUG_INTR_TSTAMP +/* We allocate an array, but only use element number 64. This guarantees that + * the entry is in a cacheline by itself. + */ +#define DINTR_CNTIDX 32 +#define DINTR_TSTAMP1 48 +#define DINTR_TSTAMP2 64 +volatile long long dintr_tstamp_cnt[128]; +int dintr_debug_output=0; +extern void idbg_tstamp_debug(void); +#ifdef SPLDEBUG +extern void idbg_splx_log(int); +#endif +#if DEBUG_INTR_TSTAMP_DEBUG +int dintr_enter_symmon=1000; /* 1000 microseconds is 1 millisecond */ +#endif + +#ifndef BRINGUP +/* ARGSUSED */ +static void +cpulatintr(void *arg) +{ + /* + * Hardware only clears IO interrupts so we have to clear our level + * here. + */ + LOCAL_HUB_CLR_INTR(CPU_INTRLAT_A + cputolocalslice(cpuid())); + +#if DEBUG_INTR_TSTAMP_DEBUG + dintr_tstamp_cnt[DINTR_TSTAMP2] = GET_LOCAL_RTC; + if ((dintr_tstamp_cnt[DINTR_TSTAMP2] - dintr_tstamp_cnt[DINTR_TSTAMP1]) + > dintr_enter_symmon) { +#ifdef SPLDEBUG + extern int spldebug_log_off; + + spldebug_log_off = 1; +#endif /* SPLDEBUG */ + debug("ring"); +#ifdef SPLDEBUG + spldebug_log_off = 0; +#endif /* SPLDEBUG */ + } +#endif + dintr_tstamp_cnt[DINTR_CNTIDX]++; + + return; +} + +static int install_cpulat_first=0; + +void +install_cpulatintr(cpuid_t cpu) +{ + int intr_bit; + devfs_handle_t cpuv = cpuid_to_vertex(cpu); + + intr_bit = CPU_INTRLAT_A + cputolocalslice(cpu); + if (intr_bit != intr_reserve_level(cpu, intr_bit, II_THREADED, + cpuv, "intrlat")) + panic( "install_cpulatintr: Can't reserve interrupt."); + + if (intr_connect_level(cpu, intr_bit, INTPEND0_MAXMASK, + cpulatintr, NULL, NULL)) + panic( "install_cpulatintr: Can't connect interrupt."); + + if (!install_cpulat_first) { + install_cpulat_first++; + idbg_addfunc("tstamp_debug", (void (*)())idbg_tstamp_debug); +#if defined(SPLDEBUG) || defined(SPLDEBUG_CPU_EVENTS) + idbg_addfunc("splx_log", (void (*)())idbg_splx_log); +#endif /* SPLDEBUG || SPLDEBUG_CPU_EVENTS */ + } +} +#endif /* BRINGUP */ + +#endif /* DEBUG_INTR_TSTAMP */ + +#ifndef BRINGUP +/* ARGSUSED */ +static void +dbgintr(void *arg) +{ + /* + * Hardware only clears IO interrupts so we have to clear our level + * here. + */ + LOCAL_HUB_CLR_INTR(N_INTPEND_BITS + DEBUG_INTR_A + cputolocalslice(cpuid())); + + debug("zing"); + return; +} + + +void +install_dbgintr(cpuid_t cpu) +{ + int intr_bit; + devfs_handle_t cpuv = cpuid_to_vertex(cpu); + + intr_bit = N_INTPEND_BITS + DEBUG_INTR_A + cputolocalslice(cpu); + if (intr_bit != intr_reserve_level(cpu, intr_bit, 1, cpuv, "DEBUG")) + panic("install_dbgintr: Can't reserve interrupt. " + " intr_bit %d" ,intr_bit); + + if (intr_connect_level(cpu, intr_bit, INTPEND1_MAXMASK, + dbgintr, NULL, NULL)) + panic("install_dbgintr: Can't connect interrupt."); + +#ifdef DEBUG_INTR_TSTAMP + /* Set up my interrupt latency test interrupt */ + install_cpulatintr(cpu); +#endif +} + +/* ARGSUSED */ +static void +tlbintr(void *arg) +{ + extern void tlbflush_rand(void); + + /* + * Hardware only clears IO interrupts so we have to clear our level + * here. + */ + LOCAL_HUB_CLR_INTR(N_INTPEND_BITS + TLB_INTR_A + cputolocalslice(cpuid())); + + tlbflush_rand(); + return; +} + + +void +install_tlbintr(cpuid_t cpu) +{ + int intr_bit; + devfs_handle_t cpuv = cpuid_to_vertex(cpu); + + intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputolocalslice(cpu); + if (intr_bit != intr_reserve_level(cpu, intr_bit, 1, cpuv, "DEBUG")) + panic("install_tlbintr: Can't reserve interrupt. " + " intr_bit %d" ,intr_bit); + + if (intr_connect_level(cpu, intr_bit, INTPEND1_MAXMASK, + tlbintr, NULL, NULL)) + panic("install_tlbintr: Can't connect interrupt."); + +} + + +/* + * Send an interrupt to all nodes. Don't panic if we get an error. + * Returns 1 if any exceptions occurred. + */ +int +protected_broadcast(hubreg_t intrbit) +{ + nodepda_t *npdap = private.p_nodepda; + int byte, bit, sn; + int error = 0; + + extern int _wbadaddr_val(volatile void *, int, volatile int *); + + /* Send rather than clear an interrupt. */ + intrbit |= 0x100; + + for (byte = 0; byte < NASID_MASK_BYTES; byte++) { + for (bit = 0; bit < 8; bit++) { + if (npdap->nasid_mask[byte] & (1 << bit)) { + nasid_t nasid = byte * 8 + bit; + for (sn=0; snii_name, + vector->iv_func, vector->iv_arg, vector->iv_prefunc); + pf(" vertex 0x%x %s%s", + info->ii_owner_dev, + ((info->ii_flags) & II_RESERVE) ? "R" : "U", + ((info->ii_flags) & II_INUSE) ? "C" : "-"); + pf("%s%s%s%s", + ip & value ? "P" : "-", + ima & value ? "A" : "-", + imb & value ? "B" : "-", + ((info->ii_flags) & II_ERRORINT) ? "E" : "-"); + pf("\n"); +} + + +/* + * Dump information about interrupt vector assignment. + */ +void +intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...)) +{ + nodepda_t *npda; + int ip, sn, bit; + intr_vecblk_t *dispatch; + hubreg_t ipr, ima, imb; + nasid_t nasid; + + if ((cnode < 0) || (cnode >= numnodes)) { + pf("intr_dumpvec: cnodeid out of range: %d\n", cnode); + return ; + } + + nasid = COMPACT_TO_NASID_NODEID(cnode); + + if (nasid == INVALID_NASID) { + pf("intr_dumpvec: Bad cnodeid: %d\n", cnode); + return ; + } + + + npda = NODEPDA(cnode); + + for (sn = 0; sn < NUM_SUBNODES; sn++) { + for (ip = 0; ip < 2; ip++) { + dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0); + ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0); + ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A); + imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B); + + pf("Node %d INT_PEND%d:\n", cnode, ip); + + if (dispatch->ithreads_enabled) + pf(" Ithreads enabled\n"); + else + pf(" Ithreads disabled\n"); + pf(" vector_count = %d, vector_state = %d\n", + dispatch->vector_count, + dispatch->vector_state); + pf(" CPU A count %d, CPU B count %d\n", + dispatch->cpu_count[0], + dispatch->cpu_count[1]); + pf(" &vector_lock = 0x%x\n", + &(dispatch->vector_lock)); + for (bit = 0; bit < N_INTPEND_BITS; bit++) { + if ((dispatch->info[bit].ii_flags & II_RESERVE) || + (ipr & (1L << bit))) { + dump_vector(&(dispatch->info[bit]), + &(dispatch->vectors[bit]), + bit, ipr, ima, imb, pf); + } + } + pf("\n"); + } + } +} + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/ml_iograph.c linux-2.4.0-test12-lia/arch/ia64/sn/io/ml_iograph.c --- linux-2.4.0-test12/arch/ia64/sn/io/ml_iograph.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/ml_iograph.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,1583 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int maxnodes; + +/* #define PROBE_TEST */ + +/* At most 2 hubs can be connected to an xswitch */ +#define NUM_XSWITCH_VOLUNTEER 2 + +/* + * Track which hubs have volunteered to manage devices hanging off of + * a Crosstalk Switch (e.g. xbow). This structure is allocated, + * initialized, and hung off the xswitch vertex early on when the + * xswitch vertex is created. + */ +typedef struct xswitch_vol_s { + struct semaphore xswitch_volunteer_mutex; + int xswitch_volunteer_count; + devfs_handle_t xswitch_volunteer[NUM_XSWITCH_VOLUNTEER]; +} *xswitch_vol_t; + +void +xswitch_vertex_init(devfs_handle_t xswitch) +{ + xswitch_vol_t xvolinfo; + int rc; + + xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL); + init_MUTEX(&xvolinfo->xswitch_volunteer_mutex); + xvolinfo->xswitch_volunteer_count = 0; + rc = hwgraph_info_add_LBL(xswitch, + INFO_LBL_XSWITCH_VOL, + (arbitrary_info_t)xvolinfo); + ASSERT(rc == GRAPH_SUCCESS); rc = rc; +} + + +/* + * When assignment of hubs to widgets is complete, we no longer need the + * xswitch volunteer structure hanging around. Destroy it. + */ +static void +xswitch_volunteer_delete(devfs_handle_t xswitch) +{ + xswitch_vol_t xvolinfo; + int rc; + + rc = hwgraph_info_remove_LBL(xswitch, + INFO_LBL_XSWITCH_VOL, + (arbitrary_info_t *)&xvolinfo); +#ifndef CONFIG_IA64_SGI_IO + ASSERT(rc == GRAPH_SUCCESS); rc = rc; +#endif + + kfree(xvolinfo); +} +/* + * A Crosstalk master volunteers to manage xwidgets on the specified xswitch. + */ +/* ARGSUSED */ +static void +volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master) +{ + xswitch_vol_t xvolinfo = NULL; + + (void)hwgraph_info_get_LBL(xswitch, + INFO_LBL_XSWITCH_VOL, + (arbitrary_info_t *)&xvolinfo); + if (xvolinfo == NULL) { +#ifndef CONFIG_IA64_SGI_IO + if (!is_headless_node_vertex(master)) + cmn_err(CE_WARN, + "volunteer for widgets: vertex %v has no info label", + xswitch); +#endif + return; + } + +#ifndef CONFIG_IA64_SGI_IO + mutex_lock(&xvolinfo->xswitch_volunteer_mutex, PZERO); +#endif + ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER); + xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master; + xvolinfo->xswitch_volunteer_count++; +#ifndef CONFIG_IA64_SGI_IO + mutex_unlock(&xvolinfo->xswitch_volunteer_mutex); +#endif +} + +#ifndef BRINGUP +/* + * The "ideal fixed assignment" of 12 IO slots to 4 node slots. + * At index N is the node slot number of the node board that should + * ideally control the widget in IO slot N. Note that if there is + * only one node board on a given xbow, it will control all of the + * devices on that xbow regardless of these defaults. + * + * N1 controls IO slots IO1, IO3, IO5 (upper left) + * N3 controls IO slots IO2, IO4, IO6 (upper right) + * N2 controls IO slots IO7, IO9, IO11 (lower left) + * N4 controls IO slots IO8, IO10, IO12 (lower right) + * + * This makes assignments predictable and easily controllable. + * TBD: Allow administrator to override these defaults. + */ +static slotid_t ideal_assignment[] = { + -1, /* IO0 -->non-existent */ + 1, /* IO1 -->N1 */ + 3, /* IO2 -->N3 */ + 1, /* IO3 -->N1 */ + 3, /* IO4 -->N3 */ + 1, /* IO5 -->N1 */ + 3, /* IO6 -->N3 */ + 2, /* IO7 -->N2 */ + 4, /* IO8 -->N4 */ + 2, /* IO9 -->N2 */ + 4, /* IO10-->N4 */ + 2, /* IO11-->N2 */ + 4 /* IO12-->N4 */ +}; + +static int +is_ideal_assignment(slotid_t hubslot, slotid_t ioslot) +{ + return(ideal_assignment[ioslot] == hubslot); +} +#endif /* ifndef BRINGUP */ + +extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum); + +/* + * Assign all the xwidgets hanging off the specified xswitch to the + * Crosstalk masters that have volunteered for xswitch duty. + */ +/* ARGSUSED */ +static void +assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv) +{ + xswitch_info_t xswitch_info; + xswitch_vol_t xvolinfo = NULL; + xwidgetnum_t widgetnum; + int curr_volunteer, num_volunteer; + nasid_t nasid; + hubinfo_t hubinfo; +#ifndef BRINGUP + int xbownum; +#endif + + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + + xswitch_info = xswitch_info_get(xswitch); + ASSERT(xswitch_info != NULL); + + (void)hwgraph_info_get_LBL(xswitch, + INFO_LBL_XSWITCH_VOL, + (arbitrary_info_t *)&xvolinfo); + if (xvolinfo == NULL) { +#ifndef CONFIG_IA64_SGI_IO + if (!is_headless_node_vertex(hubv)) + cmn_err(CE_WARN, + "assign_widgets_to_volunteers:vertex %v has " + " no info label", + xswitch); +#endif + return; + } + + num_volunteer = xvolinfo->xswitch_volunteer_count; + ASSERT(num_volunteer > 0); + curr_volunteer = 0; + + /* Assign master hub for xswitch itself. */ + if (HUB_WIDGET_ID_MIN > 0) { + hubv = xvolinfo->xswitch_volunteer[0]; + xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv); + } + +#ifndef BRINGUP + xbownum = get_node_crossbow(nasid); +#endif /* ifndef BRINGUP */ + + /* + * TBD: Use administrative information to alter assignment of + * widgets to hubs. + */ + for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { + +#ifndef BRINGUP + int i; +#endif + /* + * Ignore disabled/empty ports. + */ + if (!xbow_port_io_enabled(nasid, widgetnum)) + continue; + + /* + * If this is the master IO board, assign it to the same + * hub that owned it in the prom. + */ + if (is_master_nasid_widget(nasid, widgetnum)) { + int i; + + for (i=0; ixswitch_volunteer[i]; + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + if (nasid == get_console_nasid()) + goto do_assignment; + } +#ifndef CONFIG_IA64_SGI_IO + cmn_err(CE_PANIC, + "Nasid == %d, console nasid == %d", + nasid, get_console_nasid()); +#endif + } + +#ifndef BRINGUP + /* + * Try to do the "ideal" assignment if IO slots to nodes. + */ + for (i=0; ixswitch_volunteer[i]; + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + if (is_ideal_assignment(SLOTNUM_GETSLOT(get_node_slotid(nasid)), + SLOTNUM_GETSLOT(get_widget_slotnum(xbownum, widgetnum)))) { + + goto do_assignment; + + } + } +#endif /* ifndef BRINGUP */ + + /* + * Do a round-robin assignment among the volunteer nodes. + */ + hubv = xvolinfo->xswitch_volunteer[curr_volunteer]; + curr_volunteer = (curr_volunteer + 1) % num_volunteer; + /* fall through */ + +do_assignment: + /* + * At this point, we want to make hubv the master of widgetnum. + */ + xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv); + } + + xswitch_volunteer_delete(xswitch); +} + +/* + * Early iograph initialization. Called by master CPU in mlreset(). + * Useful for including iograph.o in kernel.o. + */ +void +iograph_early_init(void) +{ +/* + * Need new way to get this information .. + */ + cnodeid_t cnode; + nasid_t nasid; + lboard_t *board; + + /* + * Init. the board-to-hwgraph link early, so FRU analyzer + * doesn't trip on leftover values if we panic early on. + */ + for(cnode = 0; cnode < numnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + board = (lboard_t *)KL_CONFIG_INFO(nasid); + printk("iograph_early_init: Found board 0x%p\n", board); + + /* Check out all the board info stored on a node */ + while(board) { + board->brd_graph_link = GRAPH_VERTEX_NONE; + board = KLCF_NEXT(board); + printk("iograph_early_init: Found board 0x%p\n", board); + + + } + } + + hubio_init(); +} + +#ifndef CONFIG_IA64_SGI_IO +/* There is an identical definition of this in os/scheduler/runq.c */ +#define INIT_COOKIE(cookie) cookie.must_run = 0; cookie.cpu = PDA_RUNANYWHERE +/* + * These functions absolutely doesn't belong here. It's here, though, + * until the scheduler provides a platform-independent version + * that works the way it should. The interface will definitely change, + * too. Currently used only in this file and by io/cdl.c in order to + * bind various I/O threads to a CPU on the proper node. + */ +cpu_cookie_t +setnoderun(cnodeid_t cnodeid) +{ + int i; + cpuid_t cpunum; + cpu_cookie_t cookie; + + INIT_COOKIE(cookie); + if (cnodeid == CNODEID_NONE) + return(cookie); + + /* + * Do a setmustrun to one of the CPUs on the specified + * node. + */ + if ((cpunum = CNODE_TO_CPU_BASE(cnodeid)) == CPU_NONE) { + return(cookie); + } + + cpunum += CNODE_NUM_CPUS(cnodeid) - 1; + + for (i = 0; i < CNODE_NUM_CPUS(cnodeid); i++, cpunum--) { + + if (cpu_enabled(cpunum)) { + cookie = setmustrun(cpunum); + break; + } + } + + return(cookie); +} + +void +restorenoderun(cpu_cookie_t cookie) +{ + restoremustrun(cookie); +} +static sema_t io_init_sema; + +#endif /* !CONFIG_IA64_SGI_IO */ + +struct semaphore io_init_sema; + + +/* + * Let boot processor know that we're done initializing our node's IO + * and then exit. + */ +/* ARGSUSED */ +static void +io_init_done(cnodeid_t cnodeid,cpu_cookie_t c) +{ +#ifndef CONFIG_IA64_SGI_IO + /* Let boot processor know that we're done. */ + up(&io_init_sema); + /* This is for the setnoderun done when the io_init thread + * started + */ + restorenoderun(c); + sthread_exit(); +#endif +} + +/* + * Probe to see if this hub's xtalk link is active. If so, + * return the Crosstalk Identification of the widget that we talk to. + * This is called before any of the Crosstalk infrastructure for + * this hub is set up. It's usually called on the node that we're + * probing, but not always. + * + * TBD: Prom code should actually do this work, and pass through + * hwid for our use. + */ +static void +early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid) +{ + hubreg_t llp_csr_reg; + nasid_t nasid; + hubinfo_t hubinfo; + + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + + llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); + /* + * If link is up, read the widget's part number. + * A direct connect widget must respond to widgetnum=0. + */ + if (llp_csr_reg & IIO_LLP_CSR_IS_UP) { + /* TBD: Put hub into "indirect" mode */ + /* + * We're able to read from a widget because our hub's + * WIDGET_ID was set up earlier. + */ +#ifdef BRINGUP + widgetreg_t widget_id = *(volatile widgetreg_t *) + (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); + + printk("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id, + (volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) ); + +#else /* !BRINGUP */ + widgetreg_t widget_id = XWIDGET_ID_READ(nasid, 0); +#endif /* BRINGUP */ + + hwid->part_num = XWIDGET_PART_NUM(widget_id); + hwid->rev_num = XWIDGET_REV_NUM(widget_id); + hwid->mfg_num = XWIDGET_MFG_NUM(widget_id); + + /* TBD: link reset */ + } else { + + panic("\n\n**** early_probe_for_widget: Hub Vertex 0x%p is DOWN llp_csr_reg 0x%x ****\n\n", hubv, llp_csr_reg); + + hwid->part_num = XWIDGET_PART_NUM_NONE; + hwid->rev_num = XWIDGET_REV_NUM_NONE; + hwid->mfg_num = XWIDGET_MFG_NUM_NONE; + } + +} + +/* Add inventory information to the widget vertex + * Right now (module,slot,revision) is being + * added as inventory information. + */ +static void +xwidget_inventory_add(devfs_handle_t widgetv, + lboard_t *board, + struct xwidget_hwid_s hwid) +{ + if (!board) + return; + /* Donot add inventory information for the baseio + * on a speedo with an xbox. It has already been + * taken care of in SN00_vmc. + * Speedo with xbox's baseio comes in at slot io1 (widget 9) + */ + device_inventory_add(widgetv,INV_IOBD,board->brd_type, + board->brd_module, + SLOTNUM_GETSLOT(board->brd_slot), + hwid.rev_num); +} + +/* + * io_xswitch_widget_init + * + */ + +/* defined in include/linux/ctype.h */ +/* #define toupper(c) (islower(c) ? (c) - 'a' + 'A' : (c)) */ + +void +io_xswitch_widget_init(devfs_handle_t xswitchv, + devfs_handle_t hubv, + xwidgetnum_t widgetnum, + async_attach_t aa) +{ + xswitch_info_t xswitch_info; + xwidgetnum_t hub_widgetid; + devfs_handle_t widgetv; + cnodeid_t cnode; + widgetreg_t widget_id; + nasid_t nasid, peer_nasid; + struct xwidget_hwid_s hwid; + hubinfo_t hubinfo; + /*REFERENCED*/ + int rc; + char slotname[SLOTNUM_MAXLENGTH]; + char pathname[128]; + char new_name[64]; + moduleid_t module; + slotid_t slot; + lboard_t *board = NULL; + + printk("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum); + /* + * Verify that xswitchv is indeed an attached xswitch. + */ + xswitch_info = xswitch_info_get(xswitchv); + ASSERT(xswitch_info != NULL); + + hubinfo_get(hubv, &hubinfo); + nasid = hubinfo->h_nasid; + cnode = NASID_TO_COMPACT_NODEID(nasid); + hub_widgetid = hubinfo->h_widgetid; + + + /* Who's the other guy on out crossbow (if anyone) */ + peer_nasid = NODEPDA(cnode)->xbow_peer; + if (peer_nasid == INVALID_NASID) + /* If I don't have a peer, use myself. */ + peer_nasid = nasid; + + + /* Check my xbow structure and my peer's */ + if (!xbow_port_io_enabled(nasid, widgetnum) && + !xbow_port_io_enabled(peer_nasid, widgetnum)) { + return; + } + + if (xswitch_info_link_ok(xswitch_info, widgetnum)) { + char name[4]; + /* + * If the current hub is not supposed to be the master + * for this widgetnum, then skip this widget. + */ + if (xswitch_info_master_assignment_get(xswitch_info, + widgetnum) != hubv) { + return; + } + + module = NODEPDA(cnode)->module_id; +#ifdef XBRIDGE_REGS_SIM + /* hardwire for now...could do this with something like: + * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl); + * xbow_t xbow = soft->base; + * xbowreg_t xwidget_id = xbow->xb_wid_id; + * but I don't feel like figuring out vhdl right now.. + * and I know for a fact the answer is 0x2d000049 + */ + printk("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); + printk("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049)); + if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) { +#else + if (nasid_has_xbridge(nasid)) { +#endif /* XBRIDGE_REGS_SIM */ + board = find_lboard_module_class( + (lboard_t *)KL_CONFIG_INFO(nasid), + module, + KLTYPE_IOBRICK); + + if (board) + printk("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type); + + /* + * BRINGUP + * Make sure we really want to say xbrick, pbrick, + * etc. rather than XIO, graphics, etc. + */ + +#ifdef SUPPORT_PRINTING_M_FORMAT + sprintf(pathname, EDGE_LBL_MODULE "/%M/" +#else + sprintf(pathname, EDGE_LBL_MODULE "/%x/" +#endif + "%cbrick" "/%s/%d", + NODEPDA(cnode)->module_id, +#ifdef BRINGUP + + (board->brd_type == KLTYPE_IBRICK) ? 'I' : + (board->brd_type == KLTYPE_PBRICK) ? 'P' : + (board->brd_type == KLTYPE_XBRICK) ? 'X' : '?', +#else + toupper(MODULE_GET_BTCHAR(NODEPDA(cnode)->module_id)), +#endif /* BRINGUP */ + EDGE_LBL_XTALK, widgetnum); + } + + printk("io_xswitch_widget_init: path= %s\n", pathname); + rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); + + ASSERT(rc == GRAPH_SUCCESS); + + /* This is needed to let the user programs to map the + * module,slot numbers to the corresponding widget numbers + * on the crossbow. + */ + rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); + + /* If we are looking at the global master io6 + * then add information about the version of + * the io6prom as a part of "detailed inventory" + * information. + */ + if (is_master_baseio(nasid, + NODEPDA(cnode)->module_id, +#ifdef BRINGUP + get_widget_slotnum(0,widgetnum))) { +#else + <<< BOMB! >>> Need a new way to get slot numbers on IP35/IP37 +#endif + extern void klhwg_baseio_inventory_add(devfs_handle_t, + cnodeid_t); + module = NODEPDA(cnode)->module_id; + +#ifdef XBRIDGE_REGS_SIM + printk("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n"); + if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) { +#else + if (nasid_has_xbridge(nasid)) { +#endif /* XBRIDGE_REGS_SIM */ + board = find_lboard_module( + (lboard_t *)KL_CONFIG_INFO(nasid), + module); + /* + * BRINGUP + * Change iobrick to correct i/o brick + */ +#ifdef SUPPORT_PRINTING_M_FORMAT + sprintf(pathname, EDGE_LBL_MODULE "/%M/" +#else + sprintf(pathname, EDGE_LBL_MODULE "/%x/" +#endif + "iobrick" "/%s/%d", + NODEPDA(cnode)->module_id, + EDGE_LBL_XTALK, widgetnum); + } else { +#ifdef BRINGUP + slot = get_widget_slotnum(0, widgetnum); +#else + <<< BOMB! Need a new way to get slot numbers on IP35/IP37 +#endif + board = get_board_name(nasid, module, slot, + new_name); + /* + * Create the vertex for the widget, + * using the decimal + * widgetnum as the name of the primary edge. + */ +#ifdef SUPPORT_PRINTING_M_FORMAT + sprintf(pathname, EDGE_LBL_MODULE "/%M/" +#else + sprintf(pathname, EDGE_LBL_MODULE "/%x/" +#endif + EDGE_LBL_SLOT "/%s/%s", + NODEPDA(cnode)->module_id, + slotname, new_name); + } + + rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv); + printk("io_xswitch_widget_init: (2) path= %s\n", pathname); + /* + * This is a weird ass code needed for error injection + * purposes. + */ + rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv); + + klhwg_baseio_inventory_add(widgetv,cnode); + } + sprintf(name, "%d", widgetnum); + printk("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv); + rc = hwgraph_edge_add(xswitchv, widgetv, name); + + /* + * crosstalk switch code tracks which + * widget is attached to each link. + */ + xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv); + + /* + * Peek at the widget to get its crosstalk part and + * mfgr numbers, then present it to the generic xtalk + * bus provider to have its driver attach routine + * called (or not). + */ +#ifdef XBRIDGE_REGS_SIM + widget_id = 0x2d000049; + printk("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n"); +#else + widget_id = XWIDGET_ID_READ(nasid, widgetnum); +#endif /* XBRIDGE_REGS_SIM */ + hwid.part_num = XWIDGET_PART_NUM(widget_id); + hwid.rev_num = XWIDGET_REV_NUM(widget_id); + hwid.mfg_num = XWIDGET_MFG_NUM(widget_id); + /* Store some inventory information about + * the xwidget in the hardware graph. + */ + xwidget_inventory_add(widgetv,board,hwid); + + (void)xwidget_register(&hwid, widgetv, widgetnum, + hubv, hub_widgetid, + aa); + +#ifdef SN0_USE_BTE + bte_bpush_war(cnode, (void *)board); +#endif + } + +} + + +static void +io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode) +{ + xwidgetnum_t widgetnum; + async_attach_t aa; + + aa = async_attach_new(); + + printk("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode); + + for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; + widgetnum++) { +#ifdef BRINGUP + if (widgetnum != 0xe) + io_xswitch_widget_init(xswitchv, + cnodeid_to_vertex(cnode), + widgetnum, aa); + +#else + io_xswitch_widget_init(xswitchv, + cnodeid_to_vertex(cnode), + widgetnum, aa); +#endif /* BRINGUP */ + } + /* + * Wait for parallel attach threads, if any, to complete. + */ + async_attach_waitall(aa); + async_attach_free(aa); +} + +/* + * For each PCI bridge connected to the xswitch, add a link from the + * board's klconfig info to the bridge's hwgraph vertex. This lets + * the FRU analyzer find the bridge without traversing the hardware + * graph and risking hangs. + */ +static void +io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid) +{ + xwidgetnum_t widgetnum; + char pathname[128]; + devfs_handle_t vhdl; + nasid_t nasid, peer_nasid; + lboard_t *board; + + + + /* And its connected hub's nasids */ + nasid = COMPACT_TO_NASID_NODEID(cnodeid); + peer_nasid = NODEPDA(cnodeid)->xbow_peer; + + /* + * Look for paths matching "/pci" under xswitchv. + * For every widget, init. its lboard's hwgraph link. If the + * board has a PCI bridge, point the link to it. + */ + for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; + widgetnum++) { + sprintf(pathname, "%d", widgetnum); + if (hwgraph_traverse(xswitchv, pathname, &vhdl) != + GRAPH_SUCCESS) + continue; + +#if defined (CONFIG_SGI_IP35) || defined (CONFIG_IA64_SGI_SN1) || defined (CONFIG_IA64_GENERIC) + board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), + NODEPDA(cnodeid)->module_id); +#else + { + slotid_t slot; + slot = get_widget_slotnum(xbow_num, widgetnum); + board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), + NODEPDA(cnodeid)->module_id, slot); + } +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + if (board == NULL && peer_nasid != INVALID_NASID) { + /* + * Try to find the board on our peer + */ +#if defined (CONFIG_SGI_IP35) || defined (CONFIG_IA64_SGI_SN1) || defined (CONFIG_IA64_GENERIC) + board = find_lboard_module( + (lboard_t *)KL_CONFIG_INFO(peer_nasid), + NODEPDA(cnodeid)->module_id); + +#else + board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(peer_nasid), + NODEPDA(cnodeid)->module_id, slot); + +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + } + if (board == NULL) { +#ifndef CONFIG_IA64_SGI_IO + cmn_err(CE_WARN, + "Could not find PROM info for vertex %v, " + "FRU analyzer may fail", + vhdl); +#endif + return; + } + + sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); + if (hwgraph_traverse(xswitchv, pathname, &vhdl) == + GRAPH_SUCCESS) + board->brd_graph_link = vhdl; + else + board->brd_graph_link = GRAPH_VERTEX_NONE; + } +} + +/* + * Initialize all I/O on the specified node. + */ +static void +io_init_node(cnodeid_t cnodeid) +{ + /*REFERENCED*/ + devfs_handle_t hubv, switchv, widgetv; + struct xwidget_hwid_s hwid; + hubinfo_t hubinfo; + int is_xswitch; + nodepda_t *npdap; +#ifndef CONFIG_IA64_SGI_IO + sema_t *peer_sema = 0; +#else + struct semaphore *peer_sema = 0; +#endif + uint32_t widget_partnum; + nodepda_router_info_t *npda_rip; + cpu_cookie_t c = 0; + +#ifndef CONFIG_IA64_SGI_IO + /* Try to execute on the node that we're initializing. */ + c = setnoderun(cnodeid); +#endif + npdap = NODEPDA(cnodeid); + + /* + * Get the "top" vertex for this node's hardware + * graph; it will carry the per-hub hub-specific + * data, and act as the crosstalk provider master. + * It's canonical path is probably something of the + * form /hw/module/%M/slot/%d/node + */ + hubv = cnodeid_to_vertex(cnodeid); + printk("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap); + + ASSERT(hubv != GRAPH_VERTEX_NONE); + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC + hubdev_docallouts(hubv); +#endif + + /* + * Set up the dependent routers if we have any. + */ + npda_rip = npdap->npda_rip_first; + + while(npda_rip) { + /* If the router info has not been initialized + * then we need to do the router initialization + */ + if (!npda_rip->router_infop) { + router_init(cnodeid,0,npda_rip); + } + npda_rip = npda_rip->router_next; + } + + /* + * Read mfg info on this hub + */ +#ifndef CONFIG_IA64_SGI_IO + printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n"); + HUB_VERTEX_MFG_INFO(hubv); +#endif /* CONFIG_IA64_SGI_IO */ + + /* + * If nothing connected to this hub's xtalk port, we're done. + */ + early_probe_for_widget(hubv, &hwid); + if (hwid.part_num == XWIDGET_PART_NUM_NONE) { +#ifdef PROBE_TEST + if ((cnodeid == 1) || (cnodeid == 2)) { + int index; + + for (index = 0; index < 600; index++) + printk("Interfering with device probing!!!\n"); + } +#endif + /* io_init_done takes cpu cookie as 2nd argument + * to do a restorenoderun for the setnoderun done + * at the start of this thread + */ + + printk("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv); + io_init_done(cnodeid,c); + /* NOTREACHED */ + } + + /* + * attach our hub_provider information to hubv, + * so we can use it as a crosstalk provider "master" + * vertex. + */ + xtalk_provider_register(hubv, &hub_provider); + xtalk_provider_startup(hubv); + + /* + * Create a vertex to represent the crosstalk bus + * attached to this hub, and a vertex to be used + * as the connect point for whatever is out there + * on the other side of our crosstalk connection. + * + * Crosstalk Switch drivers "climb up" from their + * connection point to try and take over the switch + * point. + * + * Of course, the edges and verticies may already + * exist, in which case our net effect is just to + * associate the "xtalk_" driver with the connection + * point for the device. + */ + + (void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv); + + printk("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv); + + ASSERT(switchv != GRAPH_VERTEX_NONE); + + (void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO); + + printk("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n"); + + /* + * We need to find the widget id and update the basew_id field + * accordingly. In particular, SN00 has direct connected bridge, + * and hence widget id is Not 0. + */ + + widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT; + + if (widget_partnum == BRIDGE_WIDGET_PART_NUM || + widget_partnum == XBRIDGE_WIDGET_PART_NUM){ + npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); + + printk("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum); + + } else if (widget_partnum == XBOW_WIDGET_PART_NUM || + widget_partnum == XXBOW_WIDGET_PART_NUM) { + /* + * Xbow control register does not have the widget ID field. + * So, hard code the widget ID to be zero. + */ + printk("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum); + npdap->basew_id = 0; + +#if defined(BRINGUP) + } else if (widget_partnum == XG_WIDGET_PART_NUM) { + /* + * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock??? + * So, hard code the widget ID to be zero? + */ + npdap->basew_id = 0; + npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); +#endif + } else { + npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID); + + panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, hubv); + + /*NOTREACHED*/ + } + { + char widname[10]; + sprintf(widname, "%x", npdap->basew_id); + (void)hwgraph_path_add(switchv, widname, &widgetv); + printk("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv); + ASSERT(widgetv != GRAPH_VERTEX_NONE); + } + + nodepda->basew_xc = widgetv; + + is_xswitch = xwidget_hwid_is_xswitch(&hwid); + + /* + * Try to become the master of the widget. If this is an xswitch + * with multiple hubs connected, only one will succeed. Mastership + * of an xswitch is used only when touching registers on that xswitch. + * The slave xwidgets connected to the xswitch can be owned by various + * masters. + */ + if (device_master_set(widgetv, hubv) == 0) { + + /* Only one hub (thread) per Crosstalk device or switch makes + * it to here. + */ + + /* + * Initialize whatever xwidget is hanging off our hub. + * Whatever it is, it's accessible through widgetnum 0. + */ + hubinfo_get(hubv, &hubinfo); + + (void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL); + + if (!is_xswitch) { + /* io_init_done takes cpu cookie as 2nd argument + * to do a restorenoderun for the setnoderun done + * at the start of this thread + */ + io_init_done(cnodeid,c); + /* NOTREACHED */ + } + + /* + * Special handling for Crosstalk Switches (e.g. xbow). + * We need to do things in roughly the following order: + * 1) Initialize xswitch hardware (done above) + * 2) Determine which hubs are available to be widget masters + * 3) Discover which links are active from the xswitch + * 4) Assign xwidgets hanging off the xswitch to hubs + * 5) Initialize all xwidgets on the xswitch + */ + + volunteer_for_widgets(switchv, hubv); + + /* If there's someone else on this crossbow, recognize him */ + if (npdap->xbow_peer != INVALID_NASID) { + nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer)); + peer_sema = &peer_npdap->xbow_sema; + volunteer_for_widgets(switchv, peer_npdap->node_vertex); + } + + assign_widgets_to_volunteers(switchv, hubv); + + /* Signal that we're done */ + if (peer_sema) { + up(peer_sema); + } + + } + else { + /* Wait 'til master is done assigning widgets. */ + down(&npdap->xbow_sema); + } + +#ifdef PROBE_TEST + if ((cnodeid == 1) || (cnodeid == 2)) { + int index; + + for (index = 0; index < 500; index++) + printk("Interfering with device probing!!!\n"); + } +#endif + /* Now both nodes can safely inititialize widgets */ + io_init_xswitch_widgets(switchv, cnodeid); + io_link_xswitch_widgets(switchv, cnodeid); + + /* io_init_done takes cpu cookie as 2nd argument + * to do a restorenoderun for the setnoderun done + * at the start of this thread + */ + io_init_done(cnodeid,c); + + printk("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid); +} + + +#define IOINIT_STKSZ (16 * 1024) + +#ifndef CONFIG_IA64_SGI_IO +#include +#endif +#define __DEVSTR1 "/../.master/" +#define __DEVSTR2 "/target/" +#define __DEVSTR3 "/lun/0/disk/partition/" +#define __DEVSTR4 "/../ef" + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +/* + * Currently, we need to allow for 5 IBrick slots with 1 FC each + * plus an internal 1394. + * + * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR. + */ +#define NUM_BASE_IO_SCSI_CTLR 6 +#endif +/* + * This tells ioconfig where it can start numbering scsi controllers. + * Below this base number, platform-specific handles the numbering. + * XXX Irix legacy..controller numbering should be part of devfsd's job + */ +int num_base_io_scsi_ctlr = 2; /* used by syssgi */ +devfs_handle_t base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR]; +static devfs_handle_t baseio_enet_vhdl,baseio_console_vhdl; + +/* + * Put the logical controller number information in the + * scsi controller vertices for each scsi controller that + * is in a "fixed position". + */ +static void +scsi_ctlr_nums_add(devfs_handle_t pci_vhdl) +{ + { + int i; + + num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR; + + /* Initialize base_io_scsi_ctlr_vhdl array */ + for (i=0; i +#else +#include +#endif +extern devfs_handle_t ioc3_console_vhdl_get(void); +devfs_handle_t sys_critical_graph_root = GRAPH_VERTEX_NONE; + +/* Define the system critical vertices and connect them through + * a canonical parent-child relationships for easy traversal + * during io error handling. + */ +static void +sys_critical_graph_init(void) +{ + devfs_handle_t bridge_vhdl,master_node_vhdl; + devfs_handle_t xbow_vhdl = GRAPH_VERTEX_NONE; + extern devfs_handle_t hwgraph_root; + devfs_handle_t pci_slot_conn; + int slot; + devfs_handle_t baseio_console_conn; + + printk("sys_critical_graph_init: FIXME.\n"); + baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl); + + if (baseio_console_conn == NULL) { + return; + } + + /* Get the vertex handle for the baseio bridge */ + bridge_vhdl = device_master_get(baseio_console_conn); + + /* Get the master node of the baseio card */ + master_node_vhdl = cnodeid_to_vertex( + master_node_get(baseio_console_vhdl)); + + /* Add the "root->node" part of the system critical graph */ + + sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl); + + /* Check if we have a crossbow */ + if (hwgraph_traverse(master_node_vhdl, + EDGE_LBL_XTALK"/0", + &xbow_vhdl) == GRAPH_SUCCESS) { + /* We have a crossbow.Add "node->xbow" part of the system + * critical graph. + */ + sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl); + + /* Add "xbow->baseio bridge" of the system critical graph */ + sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl); + + hwgraph_vertex_unref(xbow_vhdl); + } else + /* We donot have a crossbow. Add "node->baseio_bridge" + * part of the system critical graph. + */ + sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl); + + /* Add all the populated PCI slot vertices to the system critical + * graph with the bridge vertex as the parent. + */ + for (slot = 0 ; slot < 8; slot++) { + char slot_edge[10]; + + sprintf(slot_edge,"%d",slot); + if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn) + != GRAPH_SUCCESS) + continue; + sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn); + hwgraph_vertex_unref(pci_slot_conn); + } + + hwgraph_vertex_unref(bridge_vhdl); + + /* Add the "ioc3 pci connection point -> console ioc3" part + * of the system critical graph + */ + + if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) == + GRAPH_SUCCESS) { + sys_critical_graph_vertex_add(pci_slot_conn, + baseio_console_vhdl); + hwgraph_vertex_unref(pci_slot_conn); + } + + /* Add the "ethernet pci connection point -> base ethernet" part of + * the system critical graph + */ + if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) == + GRAPH_SUCCESS) { + sys_critical_graph_vertex_add(pci_slot_conn, + baseio_enet_vhdl); + hwgraph_vertex_unref(pci_slot_conn); + } + + /* Add the "scsi controller pci connection point -> base scsi + * controller" part of the system critical graph + */ + if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0], + "../..",&pci_slot_conn) == GRAPH_SUCCESS) { + sys_critical_graph_vertex_add(pci_slot_conn, + base_io_scsi_ctlr_vhdl[0]); + hwgraph_vertex_unref(pci_slot_conn); + } + if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1], + "../..",&pci_slot_conn) == GRAPH_SUCCESS) { + sys_critical_graph_vertex_add(pci_slot_conn, + base_io_scsi_ctlr_vhdl[1]); + hwgraph_vertex_unref(pci_slot_conn); + } + hwgraph_vertex_unref(baseio_console_conn); + +} + +static void +baseio_ctlr_num_set(void) +{ + char name[MAXDEVNAME]; + devfs_handle_t console_vhdl, pci_vhdl, enet_vhdl; + + + printk("baseio_ctlr_num_set; FIXME\n"); + console_vhdl = ioc3_console_vhdl_get(); + if (console_vhdl == GRAPH_VERTEX_NONE) + return; + /* Useful for setting up the system critical graph */ + baseio_console_vhdl = console_vhdl; + + vertex_to_name(console_vhdl,name,MAXDEVNAME); + + strcat(name,__DEVSTR1); + pci_vhdl = hwgraph_path_to_vertex(name); + scsi_ctlr_nums_add(pci_vhdl); + /* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex + */ + hwgraph_vertex_unref(pci_vhdl); + + vertex_to_name(console_vhdl, name, MAXDEVNAME); + strcat(name, __DEVSTR4); + enet_vhdl = hwgraph_path_to_vertex(name); + + /* Useful for setting up the system critical graph */ + baseio_enet_vhdl = enet_vhdl; + + device_controller_num_set(enet_vhdl, 0); + /* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex + */ + hwgraph_vertex_unref(enet_vhdl); +} +/* #endif */ + +void +sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list) +{ + /* REFERENCED */ + int rtn_val; + + /* + ** sn00 population: errb orrb + ** 0- ql 3+? + ** 1- ql 2 + ** 2- ioc3 ethernet 2+? + ** 3- ioc3 secondary 1 + ** 4- 0 + ** 5- PCI slot + ** 6- PCI slot + ** 7- PCI slot + */ + + /* The following code implements this heuristic for getting + * maximum usage out of the rrbs + * + * constraints: + * 8 bit ql1 needs 1+1 + * ql0 or ql5,6,7 wants 1+2 + * ethernet wants 2 or more + * + * rules for even rrbs: + * if nothing in slot 6 + * 4 rrbs to 0 and 2 (0xc8889999) + * else + * 3 2 3 to slots 0 2 6 (0xc8899bbb) + * + * rules for odd rrbs + * if nothing in slot 5 or 7 (0xc8889999) + * 4 rrbs to 1 and 3 + * else if 1 thing in 5 or 7 (0xc8899aaa) or (0xc8899bbb) + * 3 2 3 to slots 1 3 5|7 + * else + * 2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this + * (0xc89aaabb) may short what it wants therefore the + * rule should be to plug pci slots in order) + */ + + + if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) { + /* something in slot 6 */ + rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0); + } + else { + rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0); + } +#ifndef CONFIG_IA64_SGI_IO + if (rtn_val) + cmn_err(CE_WARN, "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); +#endif + + if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && + (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) { + /* soemthing in slot 5 and 7 */ + rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0); + } + else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) { + /* soemthing in slot 5 but not 7 */ + rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0); + } + else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) { + /* soemthing in slot 7 but not 5 */ + rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0); + } + else { + /* nothing in slot 5 or 7 */ + rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0); + } +#ifndef CONFIG_IA64_SGI_IO + if (rtn_val) + cmn_err(CE_WARN, "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed"); +#endif +} + + +/* + * Initialize all I/O devices. Starting closest to nodes, probe and + * initialize outward. + */ +void +init_all_devices(void) +{ + /* Governor on init threads..bump up when safe + * (beware many devfs races) + */ +#ifndef CONFIG_IA64_SGI_IO + int io_init_node_threads = 2; +#endif + cnodeid_t cnodeid, active; + + init_MUTEX(&io_init_sema); + + + active = 0; + for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) { +#ifndef CONFIG_IA64_SGI_IO + char thread_name[16]; + extern int io_init_pri; + + /* + * Spawn a service thread for each node to initialize all + * I/O on that node. Each thread attempts to bind itself + * to the node whose I/O it's initializing. + */ + sprintf(thread_name, "IO_init[%d]", cnodeid); + + (void)sthread_create(thread_name, 0, IOINIT_STKSZ, 0, + io_init_pri, KT_PS, (st_func_t *)io_init_node, + (void *)(long)cnodeid, 0, 0, 0); +#else + printk("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid); + io_init_node(cnodeid); + + printk("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid); + +#endif /* !CONFIG_IA64_SGI_IO */ + + + /* Limit how many nodes go at once, to not overload hwgraph */ + /* TBD: Should timeout */ +#ifdef AA_DEBUG + printk("started thread for cnode %d\n", cnodeid); +#endif +#ifdef LINUX_KERNEL_THREADS + active++; + if (io_init_node_threads && + active >= io_init_node_threads) { + down(&io_init_sema); + active--; + } +#endif /* LINUX_KERNEL_THREADS */ + } + +#ifdef LINUX_KERNEL_THREADS + /* Wait until all IO_init threads are done */ + + while (active > 0) { +#ifdef AA_DEBUG + printk("waiting, %d still active\n", active); +#endif + sema(&io_init_sema); + active--; + } + +#endif /* LINUX_KERNEL_THREADS */ + + for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) + /* + * Update information generated by IO init. + */ + update_node_information(cnodeid); + + baseio_ctlr_num_set(); + /* Setup the system critical graph (which is a subgraph of the + * main hwgraph). This information is useful during io error + * handling. + */ + sys_critical_graph_init(); + +#if HWG_PRINT + hwgraph_print(); +#endif + +} + +#define toint(x) ((int)(x) - (int)('0')) + +void +devnamefromarcs(char *devnm) +{ + int val; + char tmpnm[MAXDEVNAME]; + char *tmp1, *tmp2; + + val = strncmp(devnm, "dks", 3); + if (val != 0) + return; + tmp1 = devnm + 3; + if (!isdigit(*tmp1)) + return; + + val = 0; + while (isdigit(*tmp1)) { + val = 10*val+toint(*tmp1); + tmp1++; + } + + if(*tmp1 != 'd') + return; + else + tmp1++; + + if ((val < 0) || (val >= NUM_BASE_IO_SCSI_CTLR)) { + int i; + int viable_found = 0; + + printk("Only controller numbers 0..%d are supported for\n", NUM_BASE_IO_SCSI_CTLR-1); + printk("prom \"root\" variables of the form dksXdXsX.\n"); + printk("To use another disk you must use the full hardware graph path\n\n"); + printk("Possible controller numbers for use in 'dksXdXsX' on this system: "); + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define LDEBUG 1 + +#define DPRINTF if (LDEBUG) printk +#define printf printk + +module_t *modules[MODULE_MAX]; +int nummodules; + +#define SN00_SERIAL_FUDGE 0x3b1af409d513c2 +#define SN0_SERIAL_FUDGE 0x6e + +void +encode_int_serial(uint64_t src,uint64_t *dest) +{ + uint64_t val; + int i; + + val = src + SN00_SERIAL_FUDGE; + + + for (i = 0; i < sizeof(long long); i++) { + ((char*)dest)[i] = + ((char*)&val)[sizeof(long long)/2 + + ((i%2) ? ((i/2 * -1) - 1) : (i/2))]; + } +} + + +void +decode_int_serial(uint64_t src, uint64_t *dest) +{ + uint64_t val; + int i; + + for (i = 0; i < sizeof(long long); i++) { + ((char*)&val)[sizeof(long long)/2 + + ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = + ((char*)&src)[i]; + } + + *dest = val - SN00_SERIAL_FUDGE; +} + + +void +encode_str_serial(const char *src, char *dest) +{ + int i; + + for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) { + + dest[i] = src[MAX_SERIAL_NUM_SIZE/2 + + ((i%2) ? ((i/2 * -1) - 1) : (i/2))] + + SN0_SERIAL_FUDGE; + } +} + +void +decode_str_serial(const char *src, char *dest) +{ + int i; + + for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) { + dest[MAX_SERIAL_NUM_SIZE/2 + + ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] - + SN0_SERIAL_FUDGE; + } +} + + +module_t *module_lookup(moduleid_t id) +{ + int i; + + DPRINTF("module_lookup: id=%d\n", id); + + for (i = 0; i < nummodules; i++) + if (modules[i]->id == id) { + DPRINTF("module_lookup: found m=0x%p\n", modules[i]); + return modules[i]; + } + + return NULL; +} + +/* + * module_add_node + * + * The first time a new module number is seen, a module structure is + * inserted into the module list in order sorted by module number + * and the structure is initialized. + * + * The node number is added to the list of nodes in the module. + */ + +module_t *module_add_node(moduleid_t id, cnodeid_t n) +{ + module_t *m; + int i; + + DPRINTF("module_add_node: id=%x node=%d\n", id, n); + + if ((m = module_lookup(id)) == 0) { +#ifndef CONFIG_IA64_SGI_IO + m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n); +#else + m = kmalloc(sizeof (module_t), GFP_KERNEL); + memset(m, 0 , sizeof(module_t)); + printk("Module nodecnt = %d\n", m->nodecnt); +#endif + ASSERT_ALWAYS(m); + + DPRINTF("module_add_node: m=0x%p\n", m); + + m->id = id; + spin_lock_init(&m->lock); + + init_MUTEX_LOCKED(&m->thdcnt); + +printk("Set elsc to 0x%p on node %d\n", &m->elsc, get_nasid()); + +set_elsc(&m->elsc); + elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n)); + spin_lock_init(&m->elsclock); + + /* Insert in sorted order by module number */ + + for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--) + modules[i] = modules[i - 1]; + + modules[i] = m; + nummodules++; + } + + m->nodes[m->nodecnt++] = n; + +printk("module_add_node: module %x now has %d nodes\n", id, m->nodecnt); + DPRINTF("module_add_node: module %x now has %d nodes\n", id, m->nodecnt); + + return m; +} + +int module_probe_snum(module_t *m, nasid_t nasid) +{ + lboard_t *board; + klmod_serial_num_t *comp; + + board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), + KLTYPE_MIDPLANE8); + + if (! board || KL_CONFIG_DUPLICATE_BOARD(board)) + return 0; + + comp = GET_SNUM_COMP(board); + + if (comp) { +#if LDEBUG + int i; + + printf("********found module with id %x and string", m->id); + + for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) + printf(" %x ", comp->snum.snum_str[i]); + + printf("\n"); /* Fudged string is not ASCII */ +#endif + + if (comp->snum.snum_str[0] != '\0') { + bcopy(comp->snum.snum_str, + m->snum.snum_str, + MAX_SERIAL_NUM_SIZE); + m->snum_valid = 1; + } + } + + if (m->snum_valid) + return 1; + else { +#ifndef CONFIG_IA64_SGI_IO + cmn_err(CE_WARN | CE_MAINTENANCE, + "Invalid serial number for module %d, " + "possible missing or invalid NIC.", m->id); +#else + printk("Invalid serial number for module %d, " + "possible missing or invalid NIC.", m->id); +#endif + return 0; + } +} + +void +io_module_init(void) +{ + cnodeid_t node; + lboard_t *board; + nasid_t nasid; + int nserial; + module_t *m; + + DPRINTF("*******module_init\n"); + + nserial = 0; + + for (node = 0; node < numnodes; node++) { + nasid = COMPACT_TO_NASID_NODEID(node); + + board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), + KLTYPE_IP27); + ASSERT(board); + + m = module_add_node(board->brd_module, node); + + if (! m->snum_valid && module_probe_snum(m, nasid)) + nserial++; + } + + DPRINTF("********found total of %d serial numbers in the system\n", + nserial); + + if (nserial == 0) + cmn_err(CE_WARN, "No serial number found."); +} + +#ifdef BRINGUP +elsc_t *Elsc[100]; + +void +set_elsc(elsc_t *p) +{ + Elsc[get_nasid()] = p; +} +#endif + +elsc_t *get_elsc(void) +{ +#ifdef BRINGUP +return(Elsc[get_nasid()]); +#else + if ( NODEPDA(get_nasid())->module == (module_t *)0 ) { + printf("get_elsc() for nasd %d fails\n", get_nasid()); +// return((elsc_t *)0); + } + return &NODEPDA(get_nasid())->module->elsc; + +// return &NODEPDA(NASID_TO_COMPACT_NODEID(0))->module->elsc; +#endif +} + +int +get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info) +{ + int i; + + if (cmod < 0 || cmod >= nummodules) + return EINVAL; + + if (! modules[cmod]->snum_valid) + return ENXIO; + + mod_info->mod_num = modules[cmod]->id; + { + char temp[MAX_SERIAL_NUM_SIZE]; + + decode_str_serial(modules[cmod]->snum.snum_str, temp); + + /* if this is an invalid serial number return an error */ + if (temp[0] != 'K') + return ENXIO; + + mod_info->serial_num = 0; + + for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) { + mod_info->serial_num <<= 4; + mod_info->serial_num |= (temp[i] & 0xf); + + mod_info->serial_str[i] = temp[i]; + } + + mod_info->serial_str[i] = '\0'; + } + + return 0; +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/pci.c linux-2.4.0-test12-lia/arch/ia64/sn/io/pci.c --- linux-2.4.0-test12/arch/ia64/sn/io/pci.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/pci.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,306 @@ +/* + * + * 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. + * + * SNI64 specific PCI support for SNI IO. + * + * Copyright (C) 1997, 1998, 2000 Colin Ngam + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG_CONFIG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + + + +#ifdef CONFIG_PCI + +extern devfs_handle_t pci_bus_to_vertex(unsigned char); +extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn); + +/* + * snia64_read_config_byte - Read a byte from the config area of the device. + */ +static int snia64_read_config_byte (struct pci_dev *dev, + int where, unsigned char *val) +{ + unsigned long res = 0; + unsigned size = 1; + devfs_handle_t device_vertex; + + if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + res = pciio_config_get(device_vertex, (unsigned) where, size); + *val = (unsigned char) res; + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_read_config_word - Read 2 bytes from the config area of the device. + */ +static int snia64_read_config_word (struct pci_dev *dev, + int where, unsigned short *val) +{ + unsigned long res = 0; + unsigned size = 2; /* 2 bytes */ + devfs_handle_t device_vertex; + + if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + res = pciio_config_get(device_vertex, (unsigned) where, size); + *val = (unsigned short) res; + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_read_config_dword - Read 4 bytes from the config area of the device. + */ +static int snia64_read_config_dword (struct pci_dev *dev, + int where, unsigned int *val) +{ + unsigned long res = 0; + unsigned size = 4; /* 4 bytes */ + devfs_handle_t device_vertex; + + if (where & 3) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + res = pciio_config_get(device_vertex, (unsigned) where, size); + *val = (unsigned int) res; + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_write_config_byte - Writes 1 byte to the config area of the device. + */ +static int snia64_write_config_byte (struct pci_dev *dev, + int where, unsigned char val) +{ + devfs_handle_t device_vertex; + + if ( dev == (struct pci_dev *)0 ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + /* + * if it's an IOC3 then we bail out, we special + * case them with pci_fixup_ioc3 + */ + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3 ) + return PCIBIOS_SUCCESSFUL; + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_write_config_word - Writes 2 bytes to the config area of the device. + */ +static int snia64_write_config_word (struct pci_dev *dev, + int where, unsigned short val) +{ + devfs_handle_t device_vertex = NULL; + + if (where & 1) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + if ( dev == (struct pci_dev *)0 ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + /* + * if it's an IOC3 then we bail out, we special + * case them with pci_fixup_ioc3 + */ + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3) + return PCIBIOS_SUCCESSFUL; + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * snia64_write_config_dword - Writes 4 bytes to the config area of the device. + */ +static int snia64_write_config_dword (struct pci_dev *dev, + int where, unsigned int val) +{ + devfs_handle_t device_vertex; + + if (where & 3) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + if ( dev == (struct pci_dev *)0 ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + /* + * if it's an IOC3 then we bail out, we special + * case them with pci_fixup_ioc3 + */ + if (dev->vendor == PCI_VENDOR_ID_SGI && + dev->device == PCI_DEVICE_ID_SGI_IOC3) + return PCIBIOS_SUCCESSFUL; + + device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn); + if (!device_vertex) { + DBG("%s : nonexistent device: bus= 0x%x slot= 0x%x func= 0x%x\n", + __FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + return(-1); + } + pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops snia64_pci_ops = { + snia64_read_config_byte, + snia64_read_config_word, + snia64_read_config_dword, + snia64_write_config_byte, + snia64_write_config_word, + snia64_write_config_dword +}; + +/* + * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code. + */ +void __init +sn1_pci_find_bios(void) +{ + extern struct pci_ops pci_conf; + /* + * Go initialize our IO Infrastructure .. + */ + extern void sgi_master_io_infr_init(void); + + sgi_master_io_infr_init(); + +#ifdef BRINGUP + if ( IS_RUNNING_ON_SIMULATOR() ) + return; +#endif + /* sn1_io_infrastructure_init(); */ + pci_conf = snia64_pci_ops; +} + +void +pci_fixup_ioc3(struct pci_dev *d) +{ + int i; + int slot; + unsigned long res = 0; + unsigned int val, size; + int ret; + u_short command; + + devfs_handle_t device_vertex; + devfs_handle_t bridge_vhdl = pci_bus_to_vertex(d->bus->number); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t devreg; + + /* IOC3 only decodes 0x20 bytes of the config space, reading + * beyond that is relatively benign but writing beyond that + * (especially the base address registers) will shut down the + * pci bus...so avoid doing so. + * NOTE: this means we can't program the intr_pin into the device, + * currently we hack this with special code in + * sgi_pci_intr_support() + */ + printk("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name); + + /* I happen to know from the spec that the ioc3 needs only 0xfffff + * The standard pci trick of writing ~0 to the baddr and seeing + * what comes back doesn't work with the ioc3 + */ + size = 0xfffff; + d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size; + + /* + * Zero out the resource structure .. because we did not go through + * the normal PCI Infrastructure Init, garbbage are left in these + * fileds. + */ + for (i = 1; i <= PCI_ROM_RESOURCE; i++) { + d->resource[i].start = 0UL; + d->resource[i].end = 0UL; + d->resource[i].flags = 0UL; + } + + /* + * Hardcode Device 4 register(IOC3 is in Slot 4) to set the + * DEV_DIRECT bit. This will not work if IOC3 is not on Slot + * 4. + */ + *(volatile u32 *)0xc0000a000f000220 |= 0x90000; + + d->subsystem_vendor = 0; + d->subsystem_device = 0; + +} + +#endif /* CONFIG_PCI */ diff -urN linux-2.4.0-test12/arch/ia64/sn/io/pci_bus_cvlink.c linux-2.4.0-test12-lia/arch/ia64/sn/io/pci_bus_cvlink.c --- linux-2.4.0-test12/arch/ia64/sn/io/pci_bus_cvlink.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/pci_bus_cvlink.c Wed Dec 13 18:59:33 2000 @@ -0,0 +1,595 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +// #include +#include +#include +extern int bridge_rev_b_data_check_disable; +#include + +#define MAX_PCI_XWIDGET 256 +devfs_handle_t busnum_to_xwidget[MAX_PCI_XWIDGET]; +nasid_t busnum_to_nid[MAX_PCI_XWIDGET]; +unsigned char num_bridges; +static int done_probing = 0; + +static int pci_bus_map_create(devfs_handle_t xtalk); +devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn); + +/* + * pci_bus_cvlink_init() - To be called once during initialization before + * SGI IO Infrastructure init is called. + */ +void +pci_bus_cvlink_init(void) +{ + + memset(busnum_to_xwidget, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET); + memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET); + num_bridges = 0; +} + +/* + * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated + * pci bus vertex from the SGI IO Infrastructure. + */ +devfs_handle_t +pci_bus_to_vertex(unsigned char busnum) +{ + + devfs_handle_t xwidget; + devfs_handle_t pci_bus = NULL; + + + /* + * First get the xwidget vertex. + */ + xwidget = busnum_to_xwidget[busnum]; + if (!xwidget) + return (NULL); + + /* + * Use devfs to get the pci vertex from xwidget. + */ + if (hwgraph_traverse(xwidget, EDGE_LBL_PCI, &pci_bus) != GRAPH_SUCCESS) { + if (!pci_bus) { + printk("pci_bus_to_vertex: Cannot find pci bus for given bus number %d\n", busnum); + return (NULL); + } + } + + return(pci_bus); +} + +/* + * devfn_to_vertex() - returns the vertex of the device given the bus, slot, + * and function numbers. + */ +devfs_handle_t +devfn_to_vertex(unsigned char busnum, unsigned int devfn) +{ + + int slot = 0; + int func = 0; + char name[16]; + devfs_handle_t pci_bus = NULL; + devfs_handle_t device_vertex = NULL; + + /* + * Go get the pci bus vertex. + */ + pci_bus = pci_bus_to_vertex(busnum); + if (!pci_bus) { + /* + * During probing, the Linux pci code invents non existant + * bus numbers and pci_dev structures and tries to access + * them to determine existance. Don't crib during probing. + */ + if (done_probing) + printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum); + return(NULL); + } + + + /* + * Go get the slot&function vertex. + * Should call pciio_slot_func_to_name() when ready. + */ + slot = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + if (func == 0) + sprintf(name, "%d", slot); + else + sprintf(name, "%d%c", slot, 'a'+func); + + if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) { + if (!device_vertex) { + printk("devfn_to_vertex: Unable to get slot&func %s from pci vertex 0x%p\n", name, pci_bus); + return(NULL); + } + } + + return(device_vertex); +} + +/* + * Most drivers currently do not properly tell the arch specific pci dma + * interfaces whether they can handle A64. Here is where we privately + * keep track of this. + */ +static void __init +set_sn1_pci64(struct pci_dev *dev) +{ + unsigned short vendor = dev->vendor; + unsigned short device = dev->device; + + if (vendor == PCI_VENDOR_ID_QLOGIC) { + if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) || + (device == PCI_DEVICE_ID_QLOGIC_ISP2200)) { + SET_PCIA64(dev); + return; + } + } + + if (vendor == PCI_VENDOR_ID_SGI) { + if (device == PCI_DEVICE_ID_SGI_IOC3) { + SET_PCIA64(dev); + return; + } + } + +} + +/* + * sn1_pci_fixup() - This routine is called when platform_pci_fixup() is + * invoked at the end of pcibios_init() to link the Linux pci + * infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c + * + * Other platform specific fixup can also be done here. + */ +void +sn1_pci_fixup(int arg) +{ + struct list_head *ln; + struct pci_bus *pci_bus = NULL; + struct pci_dev *device_dev = NULL; + struct sn1_widget_sysdata *widget_sysdata; + struct sn1_device_sysdata *device_sysdata; + extern void sn1_pci_find_bios(void); + + +unsigned long res; + + if (arg == 0) { + sn1_pci_find_bios(); + return; + } + +#if 0 +{ + devfs_handle_t bridge_vhdl = pci_bus_to_vertex(0); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl); + bridge_t *bridge = pcibr_soft->bs_base; +printk("Before Changing PIO Map Address:\n"); + printk("pci_fixup_ioc3: Before devreg fixup\n"); + printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg); + printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg); + printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg); + printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg); + printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg); + printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg); + printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg); + printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg); +} +#endif + done_probing = 1; + + if ( IS_RUNNING_ON_SIMULATOR() ) { + printk("sn1_pci_fixup not supported on simulator.\n"); + return; + } + +#ifdef REAL_HARDWARE + + /* + * Initialize the pci bus vertex in the pci_bus struct. + */ + for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) { + pci_bus = pci_bus_b(ln); + widget_sysdata = kmalloc(sizeof(struct sn1_widget_sysdata), + GFP_KERNEL); + widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number); + pci_bus->sysdata = (void *)widget_sysdata; + } + + /* + * set the root start and end so that drivers calling check_region() + * won't see a conflict + */ + ioport_resource.start |= IO_SWIZ_BASE; + ioport_resource.end |= (HSPEC_SWIZ_BASE-1); + /* + * Initialize the device vertex in the pci_dev struct. + */ + pci_for_each_dev(device_dev) { + unsigned int irq; + int idx; + u16 cmd; + devfs_handle_t vhdl; + unsigned long size; + + if (device_dev->vendor == PCI_VENDOR_ID_SGI && + device_dev->device == PCI_DEVICE_ID_SGI_IOC3) { + extern void pci_fixup_ioc3(struct pci_dev *d); + pci_fixup_ioc3(device_dev); + } + + /* Set the device vertex */ + + device_sysdata = kmalloc(sizeof(struct sn1_device_sysdata), + GFP_KERNEL); + device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn); + device_sysdata->isa64 = 0; + device_dev->sysdata = (void *) device_sysdata; + set_sn1_pci64(device_dev); + pci_read_config_word(device_dev, PCI_COMMAND, &cmd); + + /* + * Set the resources address correctly. The assumption here + * is that the addresses in the resource structure has been + * read from the card and it was set in the card by our + * Infrastructure .. + */ + vhdl = device_sysdata->vhdl; + for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { + size = 0; + size = device_dev->resource[idx].end - + device_dev->resource[idx].start; + if (size) { +res = 0; +res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4); +printk("Before pciio_pio_addr Base address %d = 0x%lx\n", idx, res); + + printk(" Changing device %d:%d resource start address from 0x%lx", + PCI_SLOT(device_dev->devfn),PCI_FUNC(device_dev->devfn), + device_dev->resource[idx].start); + device_dev->resource[idx].start = + (unsigned long)pciio_pio_addr(vhdl, 0, + PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM); + } + else + continue; + + device_dev->resource[idx].end = + device_dev->resource[idx].start + size; + + /* + * Adjust the addresses to go to the SWIZZLE .. + */ + device_dev->resource[idx].start = + device_dev->resource[idx].start & 0xfffff7ffffffffff; + device_dev->resource[idx].end = + device_dev->resource[idx].end & 0xfffff7ffffffffff; + printk(" to 0x%lx\n", device_dev->resource[idx].start); +res = 0; +res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4); +printk("After pciio_pio_addr Base address %d = 0x%lx\n", idx, res); + + if (device_dev->resource[idx].flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + else if (device_dev->resource[idx].flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + /* + * Now handle the ROM resource .. + */ + size = device_dev->resource[PCI_ROM_RESOURCE].end - + device_dev->resource[PCI_ROM_RESOURCE].start; + printk(" Changing device %d:%d ROM resource start address from 0x%lx", + PCI_SLOT(device_dev->devfn),PCI_FUNC(device_dev->devfn), + device_dev->resource[PCI_ROM_RESOURCE].start); + device_dev->resource[PCI_ROM_RESOURCE].start = + (unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, + size, 0, PCIIO_BYTE_STREAM); + device_dev->resource[PCI_ROM_RESOURCE].end = + device_dev->resource[PCI_ROM_RESOURCE].start + size; + + /* + * go through synergy swizzled space + */ + device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL; + device_dev->resource[PCI_ROM_RESOURCE].end &= 0xfffff7ffffffffffUL; + + /* + * Update the Command Word on the Card. + */ + cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */ + /* bit gets dropped .. no harm */ + pci_write_config_word(device_dev, PCI_COMMAND, cmd); + + printk(" to 0x%lx\n", device_dev->resource[PCI_ROM_RESOURCE].start); + + /* + * Set the irq correctly. + * Bits 7:3 = slot + * Bits 2:0 = function + * + * In the IRQ we will have: + * Bits 24:16 = bus number + * Bits 15:8 = slot|func number + */ + irq = 0; + irq = (irq | (device_dev->devfn << 8)); + irq = (irq | ( (device_dev->bus->number & 0xff) << 16) ); + device_dev->irq = irq; +printk("sn1_pci_fixup: slot= %d fn= %d vendor= 0x%x device= 0x%x irq= 0x%x\n", +PCI_SLOT(device_dev->devfn),PCI_FUNC(device_dev->devfn),device_dev->vendor, +device_dev->device, device_dev->irq); + + } +#endif /* REAL_HARDWARE */ +#if 0 + +{ + devfs_handle_t bridge_vhdl = pci_bus_to_vertex(0); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl); + bridge_t *bridge = pcibr_soft->bs_base; + +printk("After Changing PIO Map Address:\n"); + printk("pci_fixup_ioc3: Before devreg fixup\n"); + printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg); + printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg); + printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg); + printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg); + printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg); + printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg); + printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg); + printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg); +} +#endif + +} + +/* + * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job. + */ +static int +pci_bus_map_create(devfs_handle_t xtalk) +{ + + devfs_handle_t master_node_vertex = NULL; + devfs_handle_t xwidget = NULL; + devfs_handle_t pci_bus = NULL; + hubinfo_t hubinfo = NULL; + xwidgetnum_t widgetnum; + char pathname[128]; + graph_error_t rv; + + /* + * Loop throught this vertex and get the Xwidgets .. + */ + for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) { + sprintf(pathname, "%d", widgetnum); + xwidget = NULL; + + rv = hwgraph_traverse(xtalk, pathname, &xwidget); + if ( (rv != GRAPH_SUCCESS) ) { + if (!xwidget) + continue; + } + + sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum); + pci_bus = NULL; + if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS) + if (!pci_bus) + continue; + + /* + * Assign the correct bus number and also the nasid of this + * pci Xwidget. + * + * Should not be any race here ... + */ + num_bridges++; + busnum_to_xwidget[num_bridges - 1] = xwidget; + + /* + * Get the master node and from there get the NASID. + */ + master_node_vertex = device_master_get(xwidget); + if (!master_node_vertex) { + printk(" **** pci_bus_map_create: Unable to get .master for vertex 0x%p **** \n", xwidget); + } + + hubinfo_get(master_node_vertex, &hubinfo); + if (!hubinfo) { + printk(" **** pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p ****\n", master_node_vertex); + return(1); + } else { + busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid; + } + + printk("pci_bus_map_create: Found Hub nasid %d PCI Xwidget 0x%p widgetnum= %d\n", hubinfo->h_nasid, xwidget, widgetnum); + } + + return(0); +} + +/* + * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure + * initialization has completed to set up the mappings between Xbridge + * and logical pci bus numbers. We also set up the NASID for each of these + * xbridges. + * + * Must be called before pci_init() is invoked. + */ +int +pci_bus_to_hcl_cvlink(void) +{ + + devfs_handle_t devfs_hdl = NULL; + devfs_handle_t module_comp = NULL; + devfs_handle_t node = NULL; + devfs_handle_t xtalk = NULL; + graph_vertex_place_t placeptr = EDGE_PLACE_WANT_REAL_EDGES; + int rv = 0; + char name[256]; + + /* + * Iterate throught each xtalk links in the system .. + * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 + * + * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15 + * + * What if it is not pci? + */ + devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module"); + + /* + * Loop throught this directory "/devfs/hw/module/" and get each + * of it's entry. + */ + while (1) { + + /* Get vertex of component /dev/hw/ */ + memset((char *)name, '0', 256); + module_comp = NULL; + rv = hwgraph_edge_get_next(devfs_hdl, (char *)name, &module_comp, (uint *)&placeptr); + if ((rv == 0) && (module_comp)) { + /* Found a valid entry */ + node = NULL; + rv = hwgraph_edge_get(module_comp, "node", &node); + + } else { + printk("pci_bus_to_hcl_cvlink: No more Module Component.\n"); + return(0); + } + + if ( (rv != 0) || (!node) ){ + printk("pci_bus_to_hcl_cvlink: Module Component does not have node vertex.\n"); + continue; + } else { + xtalk = NULL; + rv = hwgraph_edge_get(node, "xtalk", &xtalk); + if ( (rv != 0) || (xtalk == NULL) ){ + printk("pci_bus_to_hcl_cvlink: Node has no xtalk vertex.\n"); + continue; + } + } + + printk("pci_bus_to_hcl_cvlink: Found Module %s node vertex = 0x%p xtalk vertex = 0x%p\n", name, node, xtalk); + /* + * Call routine to get the existing PCI Xwidget and create + * the convenience link from "/devfs/hw/pci_bus/.." + */ + pci_bus_map_create(xtalk); + } + + return(0); +} + +/* + * sgi_pci_intr_support - + */ +int +sgi_pci_intr_support (unsigned int requested_irq, device_desc_t *dev_desc, + devfs_handle_t *bus_vertex, pciio_intr_line_t *lines, + devfs_handle_t *device_vertex) + +{ + + unsigned int bus; + unsigned int devfn; + struct pci_dev *pci_dev; + unsigned char intr_pin = 0; + struct sn1_widget_sysdata *widget_sysdata; + struct sn1_device_sysdata *device_sysdata; + + printk("sgi_pci_intr_support: Called with requested_irq 0x%x\n", requested_irq); + + if (!dev_desc || !bus_vertex || !device_vertex) { + printk("sgi_pci_intr_support: Invalid parameter dev_desc 0x%p, bus_vertex 0x%p, device_vertex 0x%p\n", dev_desc, bus_vertex, device_vertex); + return(-1); + } + + devfn = (requested_irq >> 8) & 0xff; + bus = (requested_irq >> 16) & 0xffff; + pci_dev = pci_find_slot(bus, devfn); + widget_sysdata = (struct sn1_widget_sysdata *)pci_dev->bus->sysdata; + *bus_vertex = widget_sysdata->vhdl; + device_sysdata = (struct sn1_device_sysdata *)pci_dev->sysdata; + *device_vertex = device_sysdata->vhdl; +#if 0 + { + int pos; + char dname[256]; + pos = devfs_generate_path(*device_vertex, dname, 256); + printk("%s : path= %s pos %d\n", __FUNCTION__, &dname[pos], pos); + } +#endif /* BRINGUP */ + + + /* + * Get the Interrupt PIN. + */ + pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intr_pin); + *lines = (pciio_intr_line_t)intr_pin; + +#ifdef BRINGUP + /* + * ioc3 can't decode the PCI_INTERRUPT_PIN field of its config + * space so we have to set it here + */ + if (pci_dev->vendor == PCI_VENDOR_ID_SGI && + pci_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) { + *lines = 1; + printk("%s : IOC3 HACK: lines= %d\n", __FUNCTION__, *lines); + } +#endif /* BRINGUP */ + + /* Not supported currently */ + *dev_desc = NULL; + + printk("sgi_pci_intr_support: Device Descriptor 0x%p, Bus Vertex 0x%p, Interrupt Pins 0x%x, Device Vertex 0x%p\n", *dev_desc, *bus_vertex, *lines, *device_vertex); + + return(0); + +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/pci_dma.c linux-2.4.0-test12-lia/arch/ia64/sn/io/pci_dma.c --- linux-2.4.0-test12/arch/ia64/sn/io/pci_dma.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/pci_dma.c Wed Dec 13 18:59:33 2000 @@ -0,0 +1,333 @@ +/* + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Leo Dagum + */ + +#include +#include +#include +#include +#include +#include + +#ifndef LANGUAGE_C +#define LANGUAGE_C 99 +#endif +#ifndef _LANGUAGE_C +#define _LANGUAGE_C 99 +#endif +#ifndef CONFIG_IA64_SGI_IO +#define CONFIG_IA64_SGI_IO 99 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * this is REALLY ugly, blame it on gcc's lame inlining that we + * have to put procedures in header files + */ +#if LANGUAGE_C == 99 +#undef LANGUAGE_C +#endif +#if _LANGUAGE_C == 99 +#undef _LANGUAGE_C +#endif +#if CONFIG_IA64_SGI_IO == 99 +#undef CONFIG_IA64_SGI_IO +#endif + +/* + * sn1 platform specific pci_alloc_consistent() + * + * this interface is meant for "command" streams, i.e. called only + * once for initializing a device, so we don't want prefetching or + * write gathering turned on, hence the PCIIO_DMA_CMD flag + */ +void * +sn1_pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + devfs_handle_t vhdl; + struct sn1_device_sysdata *device_sysdata; + paddr_t temp_ptr; + + *dma_handle = (dma_addr_t) NULL; + + /* + * get vertex for the device + */ + device_sysdata = (struct sn1_device_sysdata *) hwdev->sysdata; + vhdl = device_sysdata->vhdl; + + if ( ret = (void *)__get_free_pages(gfp, get_order(size)) ) { + memset(ret, 0, size); + } else { + return(NULL); + } + + temp_ptr = (paddr_t) __pa(ret); + if (IS_PCIA64(hwdev)) { + + /* + * This device supports 64bits DMA addresses. + */ + *dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size, + PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD + | PCIIO_DMA_A64 ); + return (ret); + } + + /* + * Devices that supports 32 Bits upto 63 Bits DMA Address gets + * 32 Bits DMA addresses. + * + * First try to get 32 Bit Direct Map Support. + */ + if (IS_PCI32G(hwdev)) { + *dma_handle = pciio_dmatrans_addr(vhdl, NULL, temp_ptr, size, + PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD); + if (dma_handle) { + return (ret); + } else { + /* + * We need to map this request by using ATEs. + */ + printk("sn1_pci_alloc_consistent: 32Bits DMA Page Map support not available yet!"); + BUG(); + } + } + + if (IS_PCI32L(hwdev)) { + /* + * SNIA64 cannot support DMA Addresses smaller than 32 bits. + */ + return (NULL); + } + + return NULL; +} + +void +sn1_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long) vaddr, get_order(size)); +} + +/* + * On sn1 we use the alt_address entry of the scatterlist to store + * the physical address corresponding to the given virtual address + */ +int +sn1_pci_map_sg (struct pci_dev *hwdev, + struct scatterlist *sg, int nents, int direction) +{ + + int i; + devfs_handle_t vhdl; + dma_addr_t dma_addr; + paddr_t temp_ptr; + struct sn1_device_sysdata *device_sysdata; + + + if (direction == PCI_DMA_NONE) + BUG(); + + /* + * Handle 64 bit cards. + */ + device_sysdata = (struct sn1_device_sysdata *) hwdev->sysdata; + vhdl = device_sysdata->vhdl; + for (i = 0; i < nents; i++, sg++) { + sg->orig_address = sg->address; + dma_addr = 0; + temp_ptr = (paddr_t) __pa(sg->address); + + /* + * Handle the most common case 64Bit cards. + */ + if (IS_PCIA64(hwdev)) { + dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL, + temp_ptr, sg->length, + PCIBR_BARRIER | PCIIO_BYTE_STREAM | + PCIIO_DMA_CMD | PCIIO_DMA_A64 ); + sg->address = (char *)dma_addr; +/* printk("pci_map_sg: 64Bits hwdev %p DMA Address 0x%p alt_address 0x%p orig_address 0x%p length 0x%x\n", hwdev, sg->address, sg->alt_address, sg->orig_address, sg->length); */ + continue; + } + + /* + * Handle 32Bits and greater cards. + */ + if (IS_PCI32G(hwdev)) { + dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL, + temp_ptr, sg->length, + PCIBR_BARRIER | PCIIO_BYTE_STREAM | + PCIIO_DMA_CMD); + if (dma_addr) { + sg->address = (char *)dma_addr; +/* printk("pci_map_single: 32Bit direct pciio_dmatrans_addr pcidev %p returns dma_addr 0x%lx\n", hwdev, dma_addr); */ + continue; + } else { + /* + * We need to map this request by using ATEs. + */ + printk("pci_map_single: 32Bits DMA Page Map support not available yet!"); + BUG(); + + } + } + } + + return nents; + +} + +/* + * Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +void +sn1_pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + int i; + + if (direction == PCI_DMA_NONE) + BUG(); + for (i = 0; i < nelems; i++, sg++) + if (sg->orig_address != sg->address) { + /* phys_to_virt((dma_addr_t)sg->address | ~0x80000000); */ + sg->address = sg->orig_address; + sg->orig_address = 0; + } +} + +/* + * We map this to the one step pciio_dmamap_trans interface rather than + * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have + * no way of saving the dmamap handle from the alloc to later free + * (which is pretty much unacceptable). + * + * TODO: simplify our interface; + * get rid of dev_desc and vhdl (seems redundant given a pci_dev); + * figure out how to save dmamap handle so can use two step. + */ +dma_addr_t sn1_pci_map_single (struct pci_dev *hwdev, + void *ptr, size_t size, int direction) +{ + devfs_handle_t vhdl; + dma_addr_t dma_addr; + paddr_t temp_ptr; + struct sn1_device_sysdata *device_sysdata; + + + if (direction == PCI_DMA_NONE) + BUG(); + + if (IS_PCI32L(hwdev)) { + /* + * SNIA64 cannot support DMA Addresses smaller than 32 bits. + */ + return ((dma_addr_t) NULL); + } + + /* + * find vertex for the device + */ + device_sysdata = (struct sn1_device_sysdata *)hwdev->sysdata; + vhdl = device_sysdata->vhdl; +/* printk("pci_map_single: Called vhdl = 0x%p ptr = 0x%p size = %d\n", vhdl, ptr, size); */ + /* + * Call our dmamap interface + */ + dma_addr = 0; + temp_ptr = (paddr_t) __pa(ptr); + + if (IS_PCIA64(hwdev)) { + /* + * This device supports 64bits DMA addresses. + */ + dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL, + temp_ptr, size, + PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD + | PCIIO_DMA_A64 ); +/* printk("pci_map_single: 64Bit pciio_dmatrans_addr pcidev %p returns dma_addr 0x%lx\n", hwdev, dma_addr); */ + return (dma_addr); + } + + /* + * Devices that supports 32 Bits upto 63 Bits DMA Address gets + * 32 Bits DMA addresses. + * + * First try to get 32 Bit Direct Map Support. + */ + if (IS_PCI32G(hwdev)) { + dma_addr = (dma_addr_t) pciio_dmatrans_addr(vhdl, NULL, + temp_ptr, size, + PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD); + if (dma_addr) { +/* printk("pci_map_single: 32Bit direct pciio_dmatrans_addr pcidev %p returns dma_addr 0x%lx\n", hwdev, dma_addr); */ + return (dma_addr); + } else { + /* + * We need to map this request by using ATEs. + */ + printk("pci_map_single: 32Bits DMA Page Map support not available yet!"); + BUG(); + } + } + + if (IS_PCI32L(hwdev)) { + /* + * SNIA64 cannot support DMA Addresses smaller than 32 bits. + */ + return ((dma_addr_t) NULL); + } + + return ((dma_addr_t) NULL); + +} + +void +sn1_pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} + +void +sn1_pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} + +void +sn1_pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + /* Nothing to do */ +} + diff -urN linux-2.4.0-test12/arch/ia64/sn/io/pcibr.c linux-2.4.0-test12-lia/arch/ia64/sn/io/pcibr.c --- linux-2.4.0-test12/arch/ia64/sn/io/pcibr.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/pcibr.c Wed Nov 15 19:11:35 2000 @@ -0,0 +1,9574 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifdef BRINGUP +int NeedXbridgeSwap = 0; +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#include +#endif + +#if defined(BRINGUP) +#if 0 +#define DEBUG 1 /* To avoid lots of bad printk() formats leave off */ +#endif +#define PCI_DEBUG 1 +#define ATTACH_DEBUG 1 +#define PCIBR_SOFT_LIST 1 +#endif + +#ifndef LOCAL +#define LOCAL static +#endif + +#define PCIBR_LLP_CONTROL_WAR +#if defined (PCIBR_LLP_CONTROL_WAR) +int pcibr_llp_control_war_cnt; +#endif /* PCIBR_LLP_CONTROL_WAR */ + +#define NEWAf(ptr,n,f) (ptr = kmem_zalloc((n)*sizeof (*(ptr)), (f&PCIIO_NOSLEEP)?KM_NOSLEEP:KM_SLEEP)) +#define NEWA(ptr,n) (ptr = kmem_zalloc((n)*sizeof (*(ptr)), KM_SLEEP)) +#define DELA(ptr,n) (kfree(ptr)) + +#define NEWf(ptr,f) NEWAf(ptr,1,f) +#define NEW(ptr) NEWA(ptr,1) +#define DEL(ptr) DELA(ptr,1) + +int pcibr_devflag = D_MP; + +#define F(s,n) { 1l<<(s),-(s), n } + +struct reg_desc bridge_int_status_desc[] = +{ + F(31, "MULTI_ERR"), + F(30, "PMU_ESIZE_EFAULT"), + F(29, "UNEXPECTED_RESP"), + F(28, "BAD_XRESP_PACKET"), + F(27, "BAD_XREQ_PACKET"), + F(26, "RESP_XTALK_ERROR"), + F(25, "REQ_XTALK_ERROR"), + F(24, "INVALID_ADDRESS"), + F(23, "UNSUPPORTED_XOP"), + F(22, "XREQ_FIFO_OFLOW"), + F(21, "LLP_REC_SNERROR"), + F(20, "LLP_REC_CBERROR"), + F(19, "LLP_RCTY"), + F(18, "LLP_TX_RETRY"), + F(17, "LLP_TCTY"), + F(16, "SSRAM_PERR"), + F(15, "PCI_ABORT"), + F(14, "PCI_PARITY"), + F(13, "PCI_SERR"), + F(12, "PCI_PERR"), + F(11, "PCI_MASTER_TOUT"), + F(10, "PCI_RETRY_CNT"), + F(9, "XREAD_REQ_TOUT"), + F(8, "GIO_BENABLE_ERR"), + F(7, "INT7"), + F(6, "INT6"), + F(5, "INT5"), + F(4, "INT4"), + F(3, "INT3"), + F(2, "INT2"), + F(1, "INT1"), + F(0, "INT0"), + {0} +}; + +struct reg_values space_v[] = +{ + {PCIIO_SPACE_NONE, "none"}, + {PCIIO_SPACE_ROM, "ROM"}, + {PCIIO_SPACE_IO, "I/O"}, + {PCIIO_SPACE_MEM, "MEM"}, + {PCIIO_SPACE_MEM32, "MEM(32)"}, + {PCIIO_SPACE_MEM64, "MEM(64)"}, + {PCIIO_SPACE_CFG, "CFG"}, + {PCIIO_SPACE_WIN(0), "WIN(0)"}, + {PCIIO_SPACE_WIN(1), "WIN(1)"}, + {PCIIO_SPACE_WIN(2), "WIN(2)"}, + {PCIIO_SPACE_WIN(3), "WIN(3)"}, + {PCIIO_SPACE_WIN(4), "WIN(4)"}, + {PCIIO_SPACE_WIN(5), "WIN(5)"}, + {PCIIO_SPACE_BAD, "BAD"}, + {0} +}; + +struct reg_desc space_desc[] = +{ + {0xFF, 0, "space", 0, space_v}, + {0} +}; + +#if DEBUG +#define device_desc device_bits +LOCAL struct reg_desc device_bits[] = +{ + {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"}, + {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"}, + {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"}, + {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"}, + {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"}, + {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"}, + {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"}, + {BRIDGE_DEV_RT, 0, "RT"}, + {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"}, + {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"}, + {BRIDGE_DEV_PREF, 0, "PREF"}, + {BRIDGE_DEV_PRECISE, 0, "PRECISE"}, + {BRIDGE_DEV_COH, 0, "COH"}, + {BRIDGE_DEV_BARRIER, 0, "BARRIER"}, + {BRIDGE_DEV_GBR, 0, "GBR"}, + {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"}, + {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"}, + {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"}, + {0} +}; +#endif /* DEBUG */ + +#ifdef SUPPORT_PRINTING_R_FORMAT +LOCAL struct reg_values xio_cmd_pactyp[] = +{ + {0x0, "RdReq"}, + {0x1, "RdResp"}, + {0x2, "WrReqWithResp"}, + {0x3, "WrResp"}, + {0x4, "WrReqNoResp"}, + {0x5, "Reserved(5)"}, + {0x6, "FetchAndOp"}, + {0x7, "Reserved(7)"}, + {0x8, "StoreAndOp"}, + {0x9, "Reserved(9)"}, + {0xa, "Reserved(a)"}, + {0xb, "Reserved(b)"}, + {0xc, "Reserved(c)"}, + {0xd, "Reserved(d)"}, + {0xe, "SpecialReq"}, + {0xf, "SpecialResp"}, + {0} +}; + +LOCAL struct reg_desc xio_cmd_bits[] = +{ + {WIDGET_DIDN, -28, "DIDN", "%x"}, + {WIDGET_SIDN, -24, "SIDN", "%x"}, + {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp}, + {WIDGET_TNUM, -15, "TNUM", "%x"}, + {WIDGET_COHERENT, 0, "COHERENT"}, + {WIDGET_DS, 0, "DS"}, + {WIDGET_GBR, 0, "GBR"}, + {WIDGET_VBPM, 0, "VBPM"}, + {WIDGET_ERROR, 0, "ERROR"}, + {WIDGET_BARRIER, 0, "BARRIER"}, + {0} +}; +#endif /* SUPPORT_PRINTING_R_FORMAT */ + +#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG +LOCAL struct reg_desc ate_bits[] = +{ + {0xFFFF000000000000ull, -48, "RMF", "%x"}, + {~(IOPGSIZE - 1) & /* may trim off some low bits */ + 0x0000FFFFFFFFF000ull, 0, "XIO", "%x"}, + {0x0000000000000F00ull, -8, "port", "%x"}, + {0x0000000000000010ull, 0, "Barrier"}, + {0x0000000000000008ull, 0, "Prefetch"}, + {0x0000000000000004ull, 0, "Precise"}, + {0x0000000000000002ull, 0, "Coherent"}, + {0x0000000000000001ull, 0, "Valid"}, + {0} +}; +#endif + +#if PCIBR_ATE_DEBUG +LOCAL struct reg_values ssram_sizes[] = +{ + {BRIDGE_CTRL_SSRAM_512K, "512k"}, + {BRIDGE_CTRL_SSRAM_128K, "128k"}, + {BRIDGE_CTRL_SSRAM_64K, "64k"}, + {BRIDGE_CTRL_SSRAM_1K, "1k"}, + {0} +}; + +LOCAL struct reg_desc control_bits[] = +{ + {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"}, + {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"}, + {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"}, + {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"}, + {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"}, + {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"}, + {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"}, + {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"}, + {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"}, + {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"}, + {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes}, + {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"}, + {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"}, + {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"}, + {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"}, + {BRIDGE_CTRL_SYS_END, 0, "SYS_END"}, + {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"}, + {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"}, + {0} +}; +#endif + +/* kbrick widgetnum-to-bus layout */ +int p_busnum[MAX_PORT_NUM] = { /* widget# */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0 - 0x7 */ + 2, /* 0x8 */ + 1, /* 0x9 */ + 0, 0, /* 0xa - 0xb */ + 5, /* 0xc */ + 6, /* 0xd */ + 4, /* 0xe */ + 3, /* 0xf */ +}; + +/* + * Additional PIO spaces per slot are + * recorded in this structure. + */ +struct pciio_piospace_s { + pciio_piospace_t next; /* another space for this device */ + char free; /* 1 if free, 0 if in use */ + pciio_space_t space; /* Which space is in use */ + iopaddr_t start; /* Starting address of the PIO space */ + size_t count; /* size of PIO space */ +}; + +/* Use io spin locks. This ensures that all the PIO writes from a particular + * CPU to a particular IO device are synched before the start of the next + * set of PIO operations to the same device. + */ +#define pcibr_lock(pcibr_soft) io_splock(pcibr_soft->bs_lock) +#define pcibr_unlock(pcibr_soft, s) io_spunlock(pcibr_soft->bs_lock,s) + +#if PCIBR_SOFT_LIST +typedef struct pcibr_list_s *pcibr_list_p; +struct pcibr_list_s { + pcibr_list_p bl_next; + pcibr_soft_t bl_soft; + devfs_handle_t bl_vhdl; +}; +pcibr_list_p pcibr_list = 0; +#endif + +typedef volatile unsigned *cfg_p; +typedef volatile bridgereg_t *reg_p; + +#define INFO_LBL_PCIBR_ASIC_REV "_pcibr_asic_rev" + +#define PCIBR_D64_BASE_UNSET (0xFFFFFFFFFFFFFFFF) +#define PCIBR_D32_BASE_UNSET (0xFFFFFFFF) + +#define PCIBR_VALID_SLOT(s) (s < 8) + +#ifdef SN_XXX +extern int hub_device_flags_set(devfs_handle_t widget_dev, + hub_widget_flags_t flags); +#endif + +extern devfs_handle_t hwgraph_root; +extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl); +extern int cap_able(uint64_t x); +extern uint64_t rmalloc(struct map *mp, size_t size); +extern void rmfree(struct map *mp, size_t size, uint64_t a); +extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen); +extern long atoi(register char *p); +extern void *swap_ptr(void **loc, void *new); +extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen); +extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl); +extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr); +extern struct map *rmallocmap(uint64_t mapsiz); +extern void rmfreemap(struct map *mp); +extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr); +extern void cmn_err_tag(int seqnumber, register int level, char *fmt, ...); + + + +/* ===================================================================== + * Function Table of Contents + * + * The order of functions in this file has stopped + * making much sense. We might want to take a look + * at it some time and bring back some sanity, or + * perhaps bust this file into smaller chunks. + */ + +LOCAL void do_pcibr_rrb_clear(bridge_t *, int); +LOCAL void do_pcibr_rrb_flush(bridge_t *, int); +LOCAL int do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t); +LOCAL int do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t); +LOCAL int do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int); +LOCAL int do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int); + +LOCAL void do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int); + +int pcibr_wrb_flush(devfs_handle_t); +int pcibr_rrb_alloc(devfs_handle_t, int *, int *); +int pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *); +int pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int); +void pcibr_rrb_flush(devfs_handle_t); + +LOCAL int pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t); +void pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t); + +LOCAL void pcibr_clearwidint(bridge_t *); +LOCAL void pcibr_setwidint(xtalk_intr_t); +LOCAL int pcibr_probe_slot(bridge_t *, cfg_p, unsigned *); + +void pcibr_init(void); +int pcibr_attach(devfs_handle_t); +int pcibr_detach(devfs_handle_t); +int pcibr_open(devfs_handle_t *, int, int, cred_t *); +int pcibr_close(devfs_handle_t, int, int, cred_t *); +int pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); +int pcibr_unmap(devfs_handle_t, vhandl_t *); +int pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); + +void pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t); + +#ifndef BRINGUP +LOCAL int pcibr_init_ext_ate_ram(bridge_t *); +#endif +LOCAL int pcibr_ate_alloc(pcibr_soft_t, int); +LOCAL void pcibr_ate_free(pcibr_soft_t, int, int); + +LOCAL pcibr_info_t pcibr_info_get(devfs_handle_t); +LOCAL pcibr_info_t pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); +LOCAL void pcibr_device_info_free(devfs_handle_t, pciio_slot_t); +LOCAL int pcibr_device_attach(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_device_detach(devfs_handle_t,pciio_slot_t); +LOCAL iopaddr_t pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned); + +pcibr_piomap_t pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); +void pcibr_piomap_free(pcibr_piomap_t); +caddr_t pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t); +void pcibr_piomap_done(pcibr_piomap_t); +caddr_t pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); +iopaddr_t pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); +void pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); + +LOCAL iopaddr_t pcibr_flags_to_d64(unsigned, pcibr_soft_t); +LOCAL bridge_ate_t pcibr_flags_to_ate(unsigned); + +pcibr_dmamap_t pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +void pcibr_dmamap_free(pcibr_dmamap_t); +LOCAL bridge_ate_p pcibr_ate_addr(pcibr_soft_t, int); +LOCAL iopaddr_t pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t); +iopaddr_t pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t); +alenlist_t pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned); +void pcibr_dmamap_done(pcibr_dmamap_t); +cnodeid_t pcibr_get_dmatrans_node(devfs_handle_t); +iopaddr_t pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); +alenlist_t pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +void pcibr_dmamap_drain(pcibr_dmamap_t); +void pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); +void pcibr_dmalist_drain(devfs_handle_t, alenlist_t); +iopaddr_t pcibr_dmamap_pciaddr_get(pcibr_dmamap_t); + +static unsigned pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines); +pcibr_intr_t pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +void pcibr_intr_free(pcibr_intr_t); +LOCAL void pcibr_setpciint(xtalk_intr_t); +int pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t, void *); +void pcibr_intr_disconnect(pcibr_intr_t); + +devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t); +void pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); +void pcibr_intr_list_func(intr_arg_t); + +LOCAL void print_bridge_errcmd(uint32_t, char *); + +void pcibr_error_dump(pcibr_soft_t); +uint32_t pcibr_errintr_group(uint32_t); +LOCAL void pcibr_pioerr_check(pcibr_soft_t); +LOCAL void pcibr_error_intr_handler(intr_arg_t); + +LOCAL int pcibr_addr_toslot(pcibr_soft_t, iopaddr_t, pciio_space_t *, iopaddr_t *, pciio_function_t *); +LOCAL void pcibr_error_cleanup(pcibr_soft_t, int); +void pcibr_device_disable(pcibr_soft_t, int); +LOCAL int pcibr_pioerror(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *); +int pcibr_dmard_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *); +int pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *); +LOCAL int pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *); +int pcibr_error_devenable(devfs_handle_t, int); + +void pcibr_provider_startup(devfs_handle_t); +void pcibr_provider_shutdown(devfs_handle_t); + +int pcibr_reset(devfs_handle_t); +pciio_endian_t pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); +int pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t); +pciio_priority_t pcibr_priority_set(devfs_handle_t, pciio_priority_t); +int pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t); + +LOCAL cfg_p pcibr_config_addr(devfs_handle_t, unsigned); +uint64_t pcibr_config_get(devfs_handle_t, unsigned, unsigned); +LOCAL uint64_t do_pcibr_config_get(cfg_p, unsigned, unsigned); +void pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t); +LOCAL void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); + +LOCAL pcibr_hints_t pcibr_hints_get(devfs_handle_t, int); +void pcibr_hints_fix_rrbs(devfs_handle_t); +void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); +void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); +void pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t); +void pcibr_hints_handsoff(devfs_handle_t); +void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t); + +LOCAL int pcibr_slot_reset(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_info_init(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_info_free(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_device_init(devfs_handle_t, pciio_slot_t); +LOCAL int pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_call_device_attach(devfs_handle_t,pciio_slot_t); +LOCAL int pcibr_slot_call_device_detach(devfs_handle_t,pciio_slot_t); + +int pcibr_slot_powerup(devfs_handle_t,pciio_slot_t); +int pcibr_slot_shutdown(devfs_handle_t,pciio_slot_t); +int pcibr_slot_inquiry(devfs_handle_t,pciio_slot_t); + +/* ===================================================================== + * RRB management + */ + +#define LSBIT(word) ((word) &~ ((word)-1)) + +#define PCIBR_RRB_SLOT_VIRTUAL 8 + +LOCAL void +do_pcibr_rrb_clear(bridge_t *bridge, int rrb) +{ + bridgereg_t status; + + /* bridge_lock must be held; + * this RRB must be disabled. + */ + + /* wait until RRB has no outstanduing XIO packets. */ + while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) { + ; /* XXX- beats on bridge. bad idea? */ + } + + /* if the RRB has data, drain it. */ + if (status & BRIDGE_RRB_VALID(rrb)) { + bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb); + + /* wait until RRB is no longer valid. */ + while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) { + ; /* XXX- beats on bridge. bad idea? */ + } + } +} + +LOCAL void +do_pcibr_rrb_flush(bridge_t *bridge, int rrbn) +{ + reg_p rrbp = &bridge->b_rrb_map[rrbn & 1].reg; + bridgereg_t rrbv; + int shft = 4 * (rrbn >> 1); + unsigned ebit = BRIDGE_RRB_EN << shft; + + rrbv = *rrbp; + if (rrbv & ebit) + *rrbp = rrbv & ~ebit; + + do_pcibr_rrb_clear(bridge, rrbn); + + if (rrbv & ebit) + *rrbp = rrbv; +} + +/* + * pcibr_rrb_count_valid: count how many RRBs are + * marked valid for the specified PCI slot on this + * bridge. + * + * NOTE: The "slot" parameter for all pcibr_rrb + * management routines must include the "virtual" + * bit; when manageing both the normal and the + * virtual channel, separate calls to these + * routines must be made. To denote the virtual + * channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot + * number. + * + * IMPL NOTE: The obvious algorithm is to iterate + * through the RRB fields, incrementing a count if + * the RRB is valid and matches the slot. However, + * it is much simpler to use an algorithm derived + * from the "partitioned add" idea. First, XOR in a + * pattern such that the fields that match this + * slot come up "all ones" and all other fields + * have zeros in the mismatching bits. Then AND + * together the bits in the field, so we end up + * with one bit turned on for each field that + * matched. Now we need to count these bits. This + * can be done either with a series of shift/add + * instructions or by using "tmp % 15"; I expect + * that the cascaded shift/add will be faster. + */ + +LOCAL int +do_pcibr_rrb_count_valid(bridge_t *bridge, + pciio_slot_t slot) +{ + bridgereg_t tmp; + + tmp = bridge->b_rrb_map[slot & 1].reg; + tmp ^= 0x11111111 * (7 - slot / 2); + tmp &= (0xCCCCCCCC & tmp) >> 2; + tmp &= (0x22222222 & tmp) >> 1; + tmp += tmp >> 4; + tmp += tmp >> 8; + tmp += tmp >> 16; + return tmp & 15; +} + +/* + * do_pcibr_rrb_count_avail: count how many RRBs are + * available to be allocated for the specified slot. + * + * IMPL NOTE: similar to the above, except we are + * just counting how many fields have the valid bit + * turned off. + */ +LOCAL int +do_pcibr_rrb_count_avail(bridge_t *bridge, + pciio_slot_t slot) +{ + bridgereg_t tmp; + + tmp = bridge->b_rrb_map[slot & 1].reg; + tmp = (0x88888888 & ~tmp) >> 3; + tmp += tmp >> 4; + tmp += tmp >> 8; + tmp += tmp >> 16; + return tmp & 15; +} + +/* + * do_pcibr_rrb_alloc: allocate some additional RRBs + * for the specified slot. Returns -1 if there were + * insufficient free RRBs to satisfy the request, + * or 0 if the request was fulfilled. + * + * Note that if a request can be partially filled, + * it will be, even if we return failure. + * + * IMPL NOTE: again we avoid iterating across all + * the RRBs; instead, we form up a word containing + * one bit for each free RRB, then peel the bits + * off from the low end. + */ +LOCAL int +do_pcibr_rrb_alloc(bridge_t *bridge, + pciio_slot_t slot, + int more) +{ + int rv = 0; + bridgereg_t reg, tmp, bit; + + reg = bridge->b_rrb_map[slot & 1].reg; + tmp = (0x88888888 & ~reg) >> 3; + while (more-- > 0) { + bit = LSBIT(tmp); + if (!bit) { + rv = -1; + break; + } + tmp &= ~bit; + reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2))); + } + bridge->b_rrb_map[slot & 1].reg = reg; + return rv; +} + +/* + * do_pcibr_rrb_free: release some of the RRBs that + * have been allocated for the specified + * slot. Returns zero for success, or negative if + * it was unable to free that many RRBs. + * + * IMPL NOTE: We form up a bit for each RRB + * allocated to the slot, aligned with the VALID + * bitfield this time; then we peel bits off one at + * a time, releasing the corresponding RRB. + */ +LOCAL int +do_pcibr_rrb_free(bridge_t *bridge, + pciio_slot_t slot, + int less) +{ + int rv = 0; + bridgereg_t reg, tmp, clr, bit; + int i; + + clr = 0; + reg = bridge->b_rrb_map[slot & 1].reg; + + /* This needs to be done otherwise the rrb's on the virtual channel + * for this slot won't be freed !! + */ + tmp = reg & 0xbbbbbbbb; + + tmp ^= (0x11111111 * (7 - slot / 2)); + tmp &= (0x33333333 & tmp) << 2; + tmp &= (0x44444444 & tmp) << 1; + while (less-- > 0) { + bit = LSBIT(tmp); + if (!bit) { + rv = -1; + break; + } + tmp &= ~bit; + reg &= ~bit; + clr |= bit; + } + bridge->b_rrb_map[slot & 1].reg = reg; + + for (i = 0; i < 8; i++) + if (clr & (8 << (4 * i))) + do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1)); + + return rv; +} + +LOCAL void +do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft, + int slot, + int more_rrbs) +{ + bridge_t *bridge = pcibr_soft->bs_base; + int got; + + for (got = 0; got < more_rrbs; ++got) { + if (pcibr_soft->bs_rrb_res[slot & 7] > 0) + pcibr_soft->bs_rrb_res[slot & 7]--; + else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0) + pcibr_soft->bs_rrb_avail[slot & 1]--; + else + break; + if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0) + break; +#if PCIBR_RRB_DEBUG + printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n", + slot & 7, slot & 8 ? "v" : ""); +#endif + pcibr_soft->bs_rrb_valid[slot]++; + } +#if PCIBR_RRB_DEBUG + printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name, + pcibr_soft->bs_rrb_avail[0], + pcibr_soft->bs_rrb_avail[1]); + for (slot = 0; slot < 8; ++slot) + printk("\t%d+%d+%d", + 0xFFF & pcibr_soft->bs_rrb_valid[slot], + 0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], + pcibr_soft->bs_rrb_res[slot]); + printk("\n"); +#endif +} + +/* + * Device driver interface to flush the write buffers for a specified + * device hanging off the bridge. + */ +int +pcibr_wrb_flush(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridge_t *bridge = pcibr_soft->bs_base; + volatile bridgereg_t *wrb_flush; + + wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg); + while (*wrb_flush); + + return(0); +} +/* + * Device driver interface to request RRBs for a specified device + * hanging off a Bridge. The driver requests the total number of + * RRBs it would like for the normal channel (vchan0) and for the + * "virtual channel" (vchan1). The actual number allocated to each + * channel is returned. + * + * If we cannot allocate at least one RRB to a channel that needs + * at least one, return -1 (failure). Otherwise, satisfy the request + * as best we can and return 0. + */ +int +pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, + int *count_vchan0, + int *count_vchan1) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridge_t *bridge = pcibr_soft->bs_base; + int desired_vchan0; + int desired_vchan1; + int orig_vchan0; + int orig_vchan1; + int delta_vchan0; + int delta_vchan1; + int final_vchan0; + int final_vchan1; + int avail_rrbs; + unsigned s; + int error; + + /* + * TBD: temper request with admin info about RRB allocation, + * and according to demand from other devices on this Bridge. + * + * One way of doing this would be to allocate two RRBs + * for each device on the bus, before any drivers start + * asking for extras. This has the weakness that one + * driver might not give back an "extra" RRB until after + * another driver has already failed to get one that + * it wanted. + */ + + s = pcibr_lock(pcibr_soft); + + /* How many RRBs do we own? */ + orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot]; + orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL]; + + /* How many RRBs do we want? */ + desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0; + desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1; + + /* How many RRBs are free? */ + avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1] + + pcibr_soft->bs_rrb_res[pciio_slot]; + + /* Figure desired deltas */ + delta_vchan0 = desired_vchan0 - orig_vchan0; + delta_vchan1 = desired_vchan1 - orig_vchan1; + + /* Trim back deltas to something + * that we can actually meet, by + * decreasing the ending allocation + * for whichever channel wants + * more RRBs. If both want the same + * number, cut the second channel. + * NOTE: do not change the allocation for + * a channel that was passed as NULL. + */ + while ((delta_vchan0 + delta_vchan1) > avail_rrbs) { + if (count_vchan0 && + (!count_vchan1 || + ((orig_vchan0 + delta_vchan0) > + (orig_vchan1 + delta_vchan1)))) + delta_vchan0--; + else + delta_vchan1--; + } + + /* Figure final RRB allocations + */ + final_vchan0 = orig_vchan0 + delta_vchan0; + final_vchan1 = orig_vchan1 + delta_vchan1; + + /* If either channel wants RRBs but our actions + * would leave it with none, declare an error, + * but DO NOT change any RRB allocations. + */ + if ((desired_vchan0 && !final_vchan0) || + (desired_vchan1 && !final_vchan1)) { + + error = -1; + + } else { + + /* Commit the allocations: free, then alloc. + */ + if (delta_vchan0 < 0) + (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0); + if (delta_vchan1 < 0) + (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1); + + if (delta_vchan0 > 0) + (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0); + if (delta_vchan1 > 0) + (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1); + + /* Return final values to caller. + */ + if (count_vchan0) + *count_vchan0 = final_vchan0; + if (count_vchan1) + *count_vchan1 = final_vchan1; + + /* prevent automatic changes to this slot's RRBs + */ + pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot; + + /* Track the actual allocations, release + * any further reservations, and update the + * number of available RRBs. + */ + + pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0; + pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1; + pcibr_soft->bs_rrb_avail[pciio_slot & 1] = + pcibr_soft->bs_rrb_avail[pciio_slot & 1] + + pcibr_soft->bs_rrb_res[pciio_slot] + - delta_vchan0 + - delta_vchan1; + pcibr_soft->bs_rrb_res[pciio_slot] = 0; + +#if PCIBR_RRB_DEBUG + printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n", + pciio_slot, final_vchan0, final_vchan1, + pcibr_soft->bs_rrb_avail[0], + pcibr_soft->bs_rrb_avail[1]); + for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot) + printk("\t%d+%d+%d", + 0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot], + 0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL], + pcibr_soft->bs_rrb_res[pciio_slot]); + printk("\n"); +#endif + + error = 0; + } + + pcibr_unlock(pcibr_soft, s); + return error; +} + +/* + * Device driver interface to check the current state + * of the RRB allocations. + * + * pconn_vhdl is your PCI connection point (specifies which + * PCI bus and which slot). + * + * count_vchan0 points to where to return the number of RRBs + * assigned to the primary DMA channel, used by all DMA + * that does not explicitly ask for the alternate virtual + * channel. + * + * count_vchan1 points to where to return the number of RRBs + * assigned to the secondary DMA channel, used when + * PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified. + * + * count_reserved points to where to return the number of RRBs + * that have been automatically reserved for your device at + * startup, but which have not been assigned to a + * channel. RRBs must be assigned to a channel to be used; + * this can be done either with an explicit pcibr_rrb_alloc + * call, or automatically by the infrastructure when a DMA + * translation is constructed. Any call to pcibr_rrb_alloc + * will release any unassigned reserved RRBs back to the + * free pool. + * + * count_pool points to where to return the number of RRBs + * that are currently unassigned and unreserved. This + * number can (and will) change as other drivers make calls + * to pcibr_rrb_alloc, or automatically allocate RRBs for + * DMA beyond their initial reservation. + * + * NULL may be passed for any of the return value pointers + * the caller is not interested in. + * + * The return value is "0" if all went well, or "-1" if + * there is a problem. Additionally, if the wrong vertex + * is passed in, one of the subsidiary support functions + * could panic with a "bad pciio fingerprint." + */ + +int +pcibr_rrb_check(devfs_handle_t pconn_vhdl, + int *count_vchan0, + int *count_vchan1, + int *count_reserved, + int *count_pool) +{ + pciio_info_t pciio_info; + pciio_slot_t pciio_slot; + pcibr_soft_t pcibr_soft; + unsigned s; + int error = -1; + + if ((pciio_info = pciio_info_get(pconn_vhdl)) && + (pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) && + ((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) { + + s = pcibr_lock(pcibr_soft); + + if (count_vchan0) + *count_vchan0 = + pcibr_soft->bs_rrb_valid[pciio_slot]; + + if (count_vchan1) + *count_vchan1 = + pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL]; + + if (count_reserved) + *count_reserved = + pcibr_soft->bs_rrb_res[pciio_slot]; + + if (count_pool) + *count_pool = + pcibr_soft->bs_rrb_avail[pciio_slot & 1]; + + error = 0; + + pcibr_unlock(pcibr_soft, s); + } + return error; +} + +/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities + * requested for each of the devies. The evn_odd argument indicates whether + * allcoation for the odd or even rrbs is requested and next group of four pairse + * are the amount to assign to each device (they should sum to <= 8) and + * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no) + * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7 + * if even_odd is even we alloc even rrbs else we allocate odd rrbs + * returns 0 if no errors else returns -1 + */ + +int +pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd, + int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2, + int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4) +{ + devfs_handle_t pcibr_vhdl; +#ifdef colin + pcibr_soft_t pcibr_soft; +#else + pcibr_soft_t pcibr_soft = NULL; +#endif + bridge_t *bridge = NULL; + + uint32_t rrb_setting = 0; + int rrb_shift = 7; + uint32_t cur_rrb; + int dev_rrbs[4]; + int virt[4]; + int i, j; + unsigned s; + + if (GRAPH_SUCCESS == + hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) { + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (pcibr_soft) + bridge = pcibr_soft->bs_base; + hwgraph_vertex_unref(pcibr_vhdl); + } + if (bridge == NULL) + bridge = (bridge_t *) xtalk_piotrans_addr + (vhdl, NULL, 0, sizeof(bridge_t), 0); + + even_odd &= 1; + + dev_rrbs[0] = dev_1_rrbs; + dev_rrbs[1] = dev_2_rrbs; + dev_rrbs[2] = dev_3_rrbs; + dev_rrbs[3] = dev_4_rrbs; + + virt[0] = virt1; + virt[1] = virt2; + virt[2] = virt3; + virt[3] = virt4; + + if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) { + return -1; + } + if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) { + return -1; + } + /* walk through rrbs */ + for (i = 0; i < 4; i++) { + if (virt[i]) { + cur_rrb = i | 0xc; + cur_rrb = cur_rrb << (rrb_shift * 4); + rrb_shift--; + rrb_setting = rrb_setting | cur_rrb; + dev_rrbs[i] = dev_rrbs[i] - 1; + } + for (j = 0; j < dev_rrbs[i]; j++) { + cur_rrb = i | 0x8; + cur_rrb = cur_rrb << (rrb_shift * 4); + rrb_shift--; + rrb_setting = rrb_setting | cur_rrb; + } + } + + if (pcibr_soft) + s = pcibr_lock(pcibr_soft); + + bridge->b_rrb_map[even_odd].reg = rrb_setting; + + if (pcibr_soft) { + + pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd; + + /* since we've "FIXED" the allocations + * for these slots, we probably can dispense + * with tracking avail/res/valid data, but + * keeping it up to date helps debugging. + */ + + pcibr_soft->bs_rrb_avail[even_odd] = + 8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs); + + pcibr_soft->bs_rrb_res[even_odd + 0] = 0; + pcibr_soft->bs_rrb_res[even_odd + 2] = 0; + pcibr_soft->bs_rrb_res[even_odd + 4] = 0; + pcibr_soft->bs_rrb_res[even_odd + 6] = 0; + + pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1; + pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2; + pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3; + pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4; + + pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1; + pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2; + pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3; + pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4; + + pcibr_unlock(pcibr_soft, s); + } + return 0; +} + +/* + * pcibr_rrb_flush: chase down all the RRBs assigned + * to the specified connection point, and flush + * them. + */ +void +pcibr_rrb_flush(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + bridge_t *bridge = pcibr_soft->bs_base; + unsigned s; + reg_p rrbp; + unsigned rrbm; + int i; + int rrbn; + unsigned sval; + unsigned mask; + + sval = BRIDGE_RRB_EN | (pciio_slot >> 1); + mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV; + rrbn = pciio_slot & 1; + rrbp = &bridge->b_rrb_map[rrbn].reg; + + s = pcibr_lock(pcibr_soft); + rrbm = *rrbp; + for (i = 0; i < 8; ++i) { + if ((rrbm & mask) == sval) + do_pcibr_rrb_flush(bridge, rrbn); + rrbm >>= 4; + rrbn += 2; + } + pcibr_unlock(pcibr_soft, s); +} + +/* ===================================================================== + * Device(x) register management + */ + +/* pcibr_try_set_device: attempt to modify Device(x) + * for the specified slot on the specified bridge + * as requested in flags, limited to the specified + * bits. Returns which BRIDGE bits were in conflict, + * or ZERO if everything went OK. + * + * Caller MUST hold pcibr_lock when calling this function. + */ +LOCAL int +pcibr_try_set_device(pcibr_soft_t pcibr_soft, + pciio_slot_t slot, + unsigned flags, + bridgereg_t mask) +{ + bridge_t *bridge; + pcibr_soft_slot_t slotp; + bridgereg_t old; + bridgereg_t new; + bridgereg_t chg; + bridgereg_t bad; + bridgereg_t badpmu; + bridgereg_t badd32; + bridgereg_t badd64; + bridgereg_t fix; + unsigned s; + bridgereg_t xmask; + + xmask = mask; + if (pcibr_soft->bs_xbridge) { + if (mask == BRIDGE_DEV_PMU_BITS) + xmask = XBRIDGE_DEV_PMU_BITS; + if (mask == BRIDGE_DEV_D64_BITS) + xmask = XBRIDGE_DEV_D64_BITS; + } + + slotp = &pcibr_soft->bs_slot[slot]; + + s = pcibr_lock(pcibr_soft); + + bridge = pcibr_soft->bs_base; + + old = slotp->bss_device; + + /* figure out what the desired + * Device(x) bits are based on + * the flags specified. + */ + + new = old; + + /* Currently, we inherit anything that + * the new caller has not specified in + * one way or another, unless we take + * action here to not inherit. + * + * This is needed for the "swap" stuff, + * since it could have been set via + * pcibr_endian_set -- altho note that + * any explicit PCIBR_BYTE_STREAM or + * PCIBR_WORD_VALUES will freely override + * the effect of that call (and vice + * versa, no protection either way). + * + * I want to get rid of pcibr_endian_set + * in favor of tracking DMA endianness + * using the flags specified when DMA + * channels are created. + */ + +#define BRIDGE_DEV_WRGA_BITS (BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN) +#define BRIDGE_DEV_SWAP_BITS (BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR) + + /* Do not use Barrier, Write Gather, + * or Prefetch unless asked. + * Leave everything else as it + * was from the last time. + */ + new = new + & ~BRIDGE_DEV_BARRIER + & ~BRIDGE_DEV_WRGA_BITS + & ~BRIDGE_DEV_PREF + ; + + /* Generic macro flags + */ + if (flags & PCIIO_DMA_DATA) { +#ifdef colin + new = new + & ~BRIDGE_DEV_BARRIER /* barrier off */ + | BRIDGE_DEV_PREF; /* prefetch on */ +#else + new = (new + & ~BRIDGE_DEV_BARRIER) /* barrier off */ + | BRIDGE_DEV_PREF; /* prefetch on */ +#endif + + } + if (flags & PCIIO_DMA_CMD) { +#ifdef colin + new = new + & ~BRIDGE_DEV_PREF /* prefetch off */ + & ~BRIDGE_DEV_WRGA_BITS /* write gather off */ + | BRIDGE_DEV_BARRIER; /* barrier on */ +#else + new = ((new + & ~BRIDGE_DEV_PREF) /* prefetch off */ + & ~BRIDGE_DEV_WRGA_BITS) /* write gather off */ + | BRIDGE_DEV_BARRIER; /* barrier on */ +#endif + } + /* Generic detail flags + */ + if (flags & PCIIO_WRITE_GATHER) + new |= BRIDGE_DEV_WRGA_BITS; + if (flags & PCIIO_NOWRITE_GATHER) + new &= ~BRIDGE_DEV_WRGA_BITS; + + if (flags & PCIIO_PREFETCH) + new |= BRIDGE_DEV_PREF; + if (flags & PCIIO_NOPREFETCH) + new &= ~BRIDGE_DEV_PREF; + + if (flags & PCIBR_WRITE_GATHER) + new |= BRIDGE_DEV_WRGA_BITS; + if (flags & PCIBR_NOWRITE_GATHER) + new &= ~BRIDGE_DEV_WRGA_BITS; + + if (flags & PCIIO_BYTE_STREAM) + new |= (pcibr_soft->bs_xbridge) ? + BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS; + if (flags & PCIIO_WORD_VALUES) + new &= (pcibr_soft->bs_xbridge) ? + ~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS; + + /* Provider-specific flags + */ + if (flags & PCIBR_PREFETCH) + new |= BRIDGE_DEV_PREF; + if (flags & PCIBR_NOPREFETCH) + new &= ~BRIDGE_DEV_PREF; + + if (flags & PCIBR_PRECISE) + new |= BRIDGE_DEV_PRECISE; + if (flags & PCIBR_NOPRECISE) + new &= ~BRIDGE_DEV_PRECISE; + + if (flags & PCIBR_BARRIER) + new |= BRIDGE_DEV_BARRIER; + if (flags & PCIBR_NOBARRIER) + new &= ~BRIDGE_DEV_BARRIER; + + if (flags & PCIBR_64BIT) + new |= BRIDGE_DEV_DEV_SIZE; + if (flags & PCIBR_NO64BIT) + new &= ~BRIDGE_DEV_DEV_SIZE; + + chg = old ^ new; /* what are we changing, */ + chg &= xmask; /* of the interesting bits */ + + if (chg) { + + badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0; + if (pcibr_soft->bs_xbridge) { + badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0; + badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0; + } else { + badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0; + badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0; + } + bad = badpmu | badd32 | badd64; + + if (bad) { + + /* some conflicts can be resolved by + * forcing the bit on. this may cause + * some performance degredation in + * the stream(s) that want the bit off, + * but the alternative is not allowing + * the new stream at all. + */ +#ifdef colin + if (fix = bad & (BRIDGE_DEV_PRECISE | + BRIDGE_DEV_BARRIER)) { +#else + if ( (fix = bad & (BRIDGE_DEV_PRECISE | + BRIDGE_DEV_BARRIER)) ){ +#endif + bad &= ~fix; + /* don't change these bits if + * they are already set in "old" + */ + chg &= ~(fix & old); + } + /* some conflicts can be resolved by + * forcing the bit off. this may cause + * some performance degredation in + * the stream(s) that want the bit on, + * but the alternative is not allowing + * the new stream at all. + */ +#ifdef colin + if (fix = bad & (BRIDGE_DEV_WRGA_BITS | + BRIDGE_DEV_PREF)) { +#else + if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS | + BRIDGE_DEV_PREF)) ){ +#endif + bad &= ~fix; + /* don't change these bits if + * we wanted to turn them on. + */ + chg &= ~(fix & new); + } + /* conflicts in other bits mean + * we can not establish this DMA + * channel while the other(s) are + * still present. + */ + if (bad) { + pcibr_unlock(pcibr_soft, s); +#if (DEBUG && PCIBR_DEV_DEBUG) + printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits); +#endif + return bad; + } + } + } + if (mask == BRIDGE_DEV_PMU_BITS) + slotp->bss_pmu_uctr++; + if (mask == BRIDGE_DEV_D32_BITS) + slotp->bss_d32_uctr++; + if (mask == BRIDGE_DEV_D64_BITS) + slotp->bss_d64_uctr++; + + /* the value we want to write is the + * original value, with the bits for + * our selected changes flipped, and + * with any disabled features turned off. + */ + new = old ^ chg; /* only change what we want to change */ + + if (slotp->bss_device == new) { + pcibr_unlock(pcibr_soft, s); + return 0; + } + bridge->b_device[slot].reg = new; + slotp->bss_device = new; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + pcibr_unlock(pcibr_soft, s); +#if DEBUG && PCIBR_DEV_DEBUG + printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg); +#endif + + return 0; +} + +void +pcibr_release_device(pcibr_soft_t pcibr_soft, + pciio_slot_t slot, + bridgereg_t mask) +{ + pcibr_soft_slot_t slotp; + unsigned s; + + slotp = &pcibr_soft->bs_slot[slot]; + + s = pcibr_lock(pcibr_soft); + + if (mask == BRIDGE_DEV_PMU_BITS) + slotp->bss_pmu_uctr--; + if (mask == BRIDGE_DEV_D32_BITS) + slotp->bss_d32_uctr--; + if (mask == BRIDGE_DEV_D64_BITS) + slotp->bss_d64_uctr--; + + pcibr_unlock(pcibr_soft, s); +} + +/* + * flush write gather buffer for slot + */ +LOCAL void +pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft, + pciio_slot_t slot) +{ + bridge_t *bridge; + unsigned s; + volatile uint32_t wrf; + s = pcibr_lock(pcibr_soft); + bridge = pcibr_soft->bs_base; + wrf = bridge->b_wr_req_buf[slot].reg; + pcibr_unlock(pcibr_soft, s); +} + +/* ===================================================================== + * Bridge (pcibr) "Device Driver" entry points + */ + +/* + * pcibr_probe_slot: read a config space word + * while trapping any errors; reutrn zero if + * all went OK, or nonzero if there was an error. + * The value read, if any, is passed back + * through the valp parameter. + */ +LOCAL int +pcibr_probe_slot(bridge_t *bridge, + cfg_p cfg, + unsigned *valp) +{ + int rv; + bridgereg_t old_enable, new_enable; + + old_enable = bridge->b_int_enable; + new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; + + bridge->b_int_enable = new_enable; + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#if defined(BRINGUP) + /* + * The xbridge doesn't clear b_err_int_view unless + * multi-err is cleared... + */ + if (is_xbridge(bridge)) + if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) { + bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; + } +#endif /* BRINGUP */ +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + + if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) { + bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR; + (void) bridge->b_wid_tflush; /* flushbus */ + } + rv = badaddr_val((void *) cfg, 4, valp); + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#if defined(BRINGUP) + /* + * The xbridge doesn't set master timeout in b_int_status + * here. Fortunately it's in error_interrupt_view. + */ + if (is_xbridge(bridge)) + if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) { + bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR; + rv = 1; /* unoccupied slot */ + } +#endif /* BRINGUP */ +#endif /* CONFIG_SGI_IP35 */ + + bridge->b_int_enable = old_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + + return rv; +} + +/* + * pcibr_init: called once during system startup or + * when a loadable driver is loaded. + * + * The driver_register function should normally + * be in _reg, not _init. But the pcibr driver is + * required by devinit before the _reg routines + * are called, so this is an exception. + */ +void +pcibr_init(void) +{ +#if DEBUG && ATTACH_DEBUG + printk("pcibr_init\n"); +#endif + + xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM, + XBRIDGE_WIDGET_MFGR_NUM, + "pcibr_", + 0); + xwidget_driver_register(BRIDGE_WIDGET_PART_NUM, + BRIDGE_WIDGET_MFGR_NUM, + "pcibr_", + 0); +} + +/* + * open/close mmap/munmap interface would be used by processes + * that plan to map the PCI bridge, and muck around with the + * registers. This is dangerous to do, and will be allowed + * to a select brand of programs. Typically these are + * diagnostics programs, or some user level commands we may + * write to do some weird things. + * To start with expect them to have root priveleges. + * We will ask for more later. + */ +/* ARGSUSED */ +int +pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) +{ +#ifndef CONFIG_IA64_SGI_IO + if (!_CAP_CRABLE((uint64_t)credp, (uint64_t)CAP_DEVICE_MGT)) + return EPERM; +#endif + return 0; +} + +/*ARGSUSED */ +int +pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) +{ + return 0; +} + +/*ARGSUSED */ +int +pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) +{ + int error; + devfs_handle_t vhdl = dev_to_vhdl(dev); + devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get(vhdl); + pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge_t *bridge = pcibr_soft->bs_base; + + hwgraph_vertex_unref(pcibr_vhdl); + + ASSERT(pcibr_soft); + len = ctob(btoc(len)); /* Make len page aligned */ + error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len); + + /* + * If the offset being mapped corresponds to the flash prom + * base, and if the mapping succeeds, and if the user + * has requested the protections to be WRITE, enable the + * flash prom to be written. + * + * XXX- deprecate this in favor of using the + * real flash driver ... + */ + if (!error && + ((off == BRIDGE_EXTERNAL_FLASH) || + (len > BRIDGE_EXTERNAL_FLASH))) { + int s; + + /* + * ensure that we write and read without any interruption. + * The read following the write is required for the Bridge war + */ + s = splhi(); + bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN; + bridge->b_wid_control; /* inval addr bug war */ + splx(s); + } + return error; +} + +/*ARGSUSED */ +int +pcibr_unmap(devfs_handle_t dev, vhandl_t *vt) +{ + devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev); + pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge_t *bridge = pcibr_soft->bs_base; + + hwgraph_vertex_unref(pcibr_vhdl); + + /* + * If flashprom write was enabled, disable it, as + * this is the last unmap. + */ + if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) { + int s; + + /* + * ensure that we write and read without any interruption. + * The read following the write is required for the Bridge war + */ + s = splhi(); + bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN; + bridge->b_wid_control; /* inval addr bug war */ + splx(s); + } + return 0; +} + +/* This is special case code used by grio. There are plans to make + * this a bit more general in the future, but till then this should + * be sufficient. + */ +pciio_slot_t +pcibr_device_slot_get(devfs_handle_t dev_vhdl) +{ + char devname[MAXDEVNAME]; + devfs_handle_t tdev; + pciio_info_t pciio_info; + pciio_slot_t slot = PCIIO_SLOT_NONE; + + vertex_to_name(dev_vhdl, devname, MAXDEVNAME); + + /* run back along the canonical path + * until we find a PCI connection point. + */ + tdev = hwgraph_connectpt_get(dev_vhdl); + while (tdev != GRAPH_VERTEX_NONE) { + pciio_info = pciio_info_chk(tdev); + if (pciio_info) { + slot = pciio_info_slot_get(pciio_info); + break; + } + hwgraph_vertex_unref(tdev); + tdev = hwgraph_connectpt_get(tdev); + } + hwgraph_vertex_unref(tdev); + + return slot; +} +/*========================================================================== + * BRIDGE PCI SLOT RELATED IOCTLs + */ +/* + * pcibr_slot_powerup + * Software initialize the pci slot. + */ +int +pcibr_slot_powerup(devfs_handle_t pcibr_vhdl,pciio_slot_t slot) +{ + /* Check for the valid slot */ + if (!PCIBR_VALID_SLOT(slot)) + return(EINVAL); + + if (pcibr_device_attach(pcibr_vhdl,slot)) + return(EINVAL); + + return(0); +} +/* + * pcibr_slot_shutdown + * Software shutdown the pci slot + */ +int +pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl,pciio_slot_t slot) +{ + /* Check for valid slot */ + if (!PCIBR_VALID_SLOT(slot)) + return(EINVAL); + + if (pcibr_device_detach(pcibr_vhdl,slot)) + return(EINVAL); + + return(0); +} + +char *pci_space_name[] = {"NONE", + "ROM", + "IO", + "", + "MEM", + "MEM32", + "MEM64", + "CFG", + "WIN0", + "WIN1", + "WIN2", + "WIN3", + "WIN4", + "WIN5", + "", + "BAD"}; + +void +pcibr_slot_func_info_print(pcibr_info_h pcibr_infoh, int func, int verbose) +{ + pcibr_info_t pcibr_info = pcibr_infoh[func]; + char name[MAXDEVNAME]; + int win; + + if (!pcibr_info) + return; + +#ifdef SUPPORT_PRINTING_V_FORMAT + sprintf(name, "%v", pcibr_info->f_vertex); +#endif + if (!verbose) { + printk("\tSlot Name : %s\n",name); + } else { + printk("\tPER-SLOT FUNCTION INFO\n"); +#ifdef SUPPORT_PRINTING_V_FORMAT + sprintf(name, "%v", pcibr_info->f_vertex); +#endif + printk("\tSlot Name : %s\n",name); + printk("\tPCI Bus : %d ",pcibr_info->f_bus); + printk("Slot : %d ", pcibr_info->f_slot); + printk("Function : %d\n", pcibr_info->f_func); +#ifdef SUPPORT_PRINTING_V_FORMAT + sprintf(name, "%v", pcibr_info->f_master); +#endif + printk("\tBus provider : %s\n",name); + printk("\tProvider Fns : 0x%p ", pcibr_info->f_pops); + printk("Error Handler : 0x%p Arg 0x%p\n", + pcibr_info->f_efunc,pcibr_info->f_einfo); + } + printk("\tVendorId : 0x%x " , pcibr_info->f_vendor); + printk("DeviceId : 0x%x\n", pcibr_info->f_device); + + printk("\n\tBase Register Info\n"); + printk("\t\tReg#\tBase\t\tSize\t\tSpace\n"); + for(win = 0 ; win < 6 ; win++) + printk("\t\t%d\t0x%lx\t%s0x%lx\t%s%s\n", + win, + pcibr_info->f_window[win].w_base, + pcibr_info->f_window[win].w_base >= 0x100000 ? "": "\t", + pcibr_info->f_window[win].w_size, + pcibr_info->f_window[win].w_size >= 0x100000 ? "": "\t", + pci_space_name[pcibr_info->f_window[win].w_space]); + + printk("\t\t7\t0x%x\t%s0x%x\t%sROM\n", + pcibr_info->f_rbase, + pcibr_info->f_rbase > 0x100000 ? "" : "\t", + pcibr_info->f_rsize, + pcibr_info->f_rsize > 0x100000 ? "" : "\t"); + + printk("\n\tInterrupt Bit Map\n"); + printk("\t\tPCI Int#\tBridge Pin#\n"); + for (win = 0 ; win < 4; win++) + printk("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]); + printk("\n"); +} + + +void +pcibr_slot_info_print(pcibr_soft_t pcibr_soft, + pciio_slot_t slot, + int verbose) +{ + pcibr_soft_slot_t pss; + char slot_conn_name[MAXDEVNAME]; + int func; + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t b_resp; + reg_p b_respp; + int dev; + bridgereg_t b_int_device; + bridgereg_t b_int_host; + bridgereg_t b_int_enable; + int pin = 0; + int int_bits = 0; + + pss = &pcibr_soft->bs_slot[slot]; + + printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot); + + if (verbose) { + printk("\tHost Present ? %s ", pss->has_host ? "yes" : "no"); + printk("\tHost Slot : %d\n",pss->host_slot); +#ifdef SUPPORT_PRINTING_V_FORMAT + sprintf(slot_conn_name, "%v", pss->slot_conn); +#endif + printk("\tSlot Conn : %s\n",slot_conn_name); + printk("\t#Functions : %d\n",pss->bss_ninfo); + } + for (func = 0; func < pss->bss_ninfo; func++) + pcibr_slot_func_info_print(pss->bss_infos,func, verbose); + printk("\tDevio[Space:%s,Base:0x%lx,Shadow:0x%x]\n", + pci_space_name[pss->bss_devio.bssd_space], + pss->bss_devio.bssd_base, + pss->bss_device); + + if (verbose) { + printk("\tUsage counts : pmu %d d32 %d d64 %d\n", + pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr); + + printk("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x" + "d32_base 0x%x d32_flags 0x%x\n", + (unsigned int)pss->bss_d64_base, pss->bss_d64_flags, + (unsigned int)pss->bss_d32_base, pss->bss_d32_flags); + + printk("\tExt ATEs active ? %s", + pss->bss_ext_ates_active ? "yes" : "no"); + printk(" Command register : 0x%p ", pss->bss_cmd_pointer); + printk(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow); + } + + printk("\tSoft RRB Info[Valid %d+%d, Reserved %d]\n", + pcibr_soft->bs_rrb_valid[slot], + pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], + pcibr_soft->bs_rrb_res[slot]); + + + if (slot & 1) + b_respp = &bridge->b_odd_resp; + else + b_respp = &bridge->b_even_resp; + + b_resp = *b_respp; + + printk("\n\tBridge RRB Info\n"); + printk("\t\tRRB#\tVirtual\n"); + for (dev = 0; dev < 8; dev++) { + if ((b_resp & BRIDGE_RRB_EN) && + (b_resp & BRIDGE_RRB_PDEV) == (slot >> 1)) + printk( "\t\t%d\t%s\n", + dev, + (b_resp & BRIDGE_RRB_VDEV) ? "yes" : "no"); + b_resp >>= 4; + + } + b_int_device = bridge->b_int_device; + b_int_enable = bridge->b_int_enable; + + printk("\n\tBridge Interrupt Info\n" + "\t\tInt_device 0x%x\n\t\tInt_enable 0x%x " + "\n\t\tEnabled pin#s for this slot: ", + b_int_device, + b_int_enable); + + while (b_int_device) { + if (((b_int_device & 7) == slot) && + (b_int_enable & (1 << pin))) { + int_bits |= (1 << pin); + printk("%d ", pin); + } + pin++; + b_int_device >>= 3; + } + + if (!int_bits) + printk("NONE "); + + b_int_host = bridge->b_int_addr[slot].addr; + + printk("\n\t\tInt_host_addr 0x%x\n", + b_int_host); + +} + +int verbose = 0; +/* + * pcibr_slot_inquiry + * Print information about the pci slot maintained by the infrastructure. + * Current information displayed + * Slot hwgraph name + * Vendor/Device info + * Base register info + * Interrupt mapping from device pins to the bridge pins + * Devio register + * Software RRB info + * RRB register info + * In verbose mode following additional info is displayed + * Host/Gues info + * PCI Bus #,slot #, function # + * Slot provider hwgraph name + * Provider Functions + * Error handler + * DMA mapping usage counters + * DMA direct translation info + * External SSRAM workaround info + */ +int +pcibr_slot_inquiry(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); + + /* Make sure that we are dealing with a bridge device vertex */ + if (!pcibr_soft) + return(EINVAL); + + /* Make sure that we have a valid pci slot number or PCIIO_SLOT_NONE */ + if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) + return(EINVAL); + + /* Print information for the requested pci slot */ + if (slot != PCIIO_SLOT_NONE) { + pcibr_slot_info_print(pcibr_soft,slot,verbose); + return(0); + } + /* Print information for all the slots */ + for (slot = 0; slot < 8; slot++) + pcibr_slot_info_print(pcibr_soft, slot,verbose); + return(0); +} + +/*ARGSUSED */ +int +pcibr_ioctl(devfs_handle_t dev, + int cmd, + void *arg, + int flag, + struct cred *cr, + int *rvalp) +{ + devfs_handle_t pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev); +#ifdef colin + pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); +#endif + int error = 0; + + hwgraph_vertex_unref(pcibr_vhdl); + + switch (cmd) { +#ifdef colin + case GIOCSETBW: + { + grio_ioctl_info_t info; + pciio_slot_t slot = 0; + + if (!cap_able((uint64_t)CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { + error = EFAULT; + break; + } +#ifdef GRIO_DEBUG + printk("pcibr:: prev_vhdl: %d reqbw: %lld\n", + info.prev_vhdl, info.reqbw); +#endif /* GRIO_DEBUG */ + + if ((slot = pcibr_device_slot_get(info.prev_vhdl)) == + PCIIO_SLOT_NONE) { + error = EIO; + break; + } + if (info.reqbw) + pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH); + break; + } + + case GIOCRELEASEBW: + { + grio_ioctl_info_t info; + pciio_slot_t slot = 0; + + if (!cap_able(CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { + error = EFAULT; + break; + } +#ifdef GRIO_DEBUG + printk("pcibr:: prev_vhdl: %d reqbw: %lld\n", + info.prev_vhdl, info.reqbw); +#endif /* GRIO_DEBUG */ + + if ((slot = pcibr_device_slot_get(info.prev_vhdl)) == + PCIIO_SLOT_NONE) { + error = EIO; + break; + } + if (info.reqbw) + pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW); + break; + } +#endif /* colin */ + + case PCIBR_SLOT_POWERUP: + { + pciio_slot_t slot; + + if (!cap_able(CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + + slot = (pciio_slot_t)(uint64_t)arg; + error = pcibr_slot_powerup(pcibr_vhdl,slot); + break; + } + case PCIBR_SLOT_SHUTDOWN: + { + pciio_slot_t slot; + + if (!cap_able(CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + + slot = (pciio_slot_t)(uint64_t)arg; + error = pcibr_slot_shutdown(pcibr_vhdl,slot); + break; + } + case PCIBR_SLOT_INQUIRY: + { + pciio_slot_t slot; + + if (!cap_able(CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + + slot = (pciio_slot_t)(uint64_t)arg; + error = pcibr_slot_inquiry(pcibr_vhdl,slot); + break; + } + default: + break; + + } + + return error; +} + +void +pcibr_freeblock_sub(iopaddr_t *free_basep, + iopaddr_t *free_lastp, + iopaddr_t base, + size_t size) +{ + iopaddr_t free_base = *free_basep; + iopaddr_t free_last = *free_lastp; + iopaddr_t last = base + size - 1; + + if ((last < free_base) || (base > free_last)); /* free block outside arena */ + + else if ((base <= free_base) && (last >= free_last)) + /* free block contains entire arena */ + *free_basep = *free_lastp = 0; + + else if (base <= free_base) + /* free block is head of arena */ + *free_basep = last + 1; + + else if (last >= free_last) + /* free block is tail of arena */ + *free_lastp = base - 1; + + /* + * We are left with two regions: the free area + * in the arena "below" the block, and the free + * area in the arena "above" the block. Keep + * the one that is bigger. + */ + + else if ((base - free_base) > (free_last - last)) + *free_lastp = base - 1; /* keep lower chunk */ + else + *free_basep = last + 1; /* keep upper chunk */ +} + +#ifdef IRIX +/* Convert from ssram_bits in control register to number of SSRAM entries */ +#define ATE_NUM_ENTRIES(n) _ate_info[n] + +/* Possible choices for number of ATE entries in Bridge's SSRAM */ +LOCAL int _ate_info[] = +{ + 0, /* 0 entries */ + 8 * 1024, /* 8K entries */ + 16 * 1024, /* 16K entries */ + 64 * 1024 /* 64K entries */ +}; + +#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int)) +#define ATE_PROBE_VALUE 0x0123456789abcdefULL +#endif /* IRIX */ + +/* + * Determine the size of this bridge's external mapping SSRAM, and set + * the control register appropriately to reflect this size, and initialize + * the external SSRAM. + */ +#ifndef BRINGUP +LOCAL int +pcibr_init_ext_ate_ram(bridge_t *bridge) +{ + int largest_working_size = 0; + int num_entries, entry; + int i, j; + bridgereg_t old_enable, new_enable; + int s; + + if (is_xbridge(bridge)) + return 0; + + /* Probe SSRAM to determine its size. */ + old_enable = bridge->b_int_enable; + new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT; + bridge->b_int_enable = new_enable; + + for (i = 1; i < ATE_NUM_SIZES; i++) { + /* Try writing a value */ + bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE; + + /* Guard against wrap */ + for (j = 1; j < i; j++) + bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0; + + /* See if value was written */ + if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE) + largest_working_size = i; + } + bridge->b_int_enable = old_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + + /* + * ensure that we write and read without any interruption. + * The read following the write is required for the Bridge war + */ + + s = splhi(); +#ifdef colin + bridge->b_wid_control = (bridge->b_wid_control + & ~BRIDGE_CTRL_SSRAM_SIZE_MASK) + | BRIDGE_CTRL_SSRAM_SIZE(largest_working_size); +#endif + bridge->b_wid_control; /* inval addr bug war */ + splx(s); + + num_entries = ATE_NUM_ENTRIES(largest_working_size); + +#if PCIBR_ATE_DEBUG + if (num_entries) + printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries); + else + printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge); +#endif + + /* Initialize external mapping entries */ + for (entry = 0; entry < num_entries; entry++) + bridge->b_ext_ate_ram[entry] = 0; + + return (num_entries); +} +#endif /* !BRINGUP */ + +/* + * Allocate "count" contiguous Bridge Address Translation Entries + * on the specified bridge to be used for PCI to XTALK mappings. + * Indices in rm map range from 1..num_entries. Indicies returned + * to caller range from 0..num_entries-1. + * + * Return the start index on success, -1 on failure. + */ +LOCAL int +pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count) +{ + int index = 0; + + index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count); + + if (!index && pcibr_soft->bs_ext_ate_map) + index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count); + + /* 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; +} + +LOCAL 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); +} + +LOCAL pcibr_info_t +pcibr_info_get(devfs_handle_t vhdl) +{ + return (pcibr_info_t) pciio_info_get(vhdl); +} + +pcibr_info_t +pcibr_device_info_new( + pcibr_soft_t pcibr_soft, + pciio_slot_t slot, + pciio_function_t rfunc, + pciio_vendor_id_t vendor, + pciio_device_id_t device) +{ + pcibr_info_t pcibr_info; + pciio_function_t func; + int ibit; + + func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc; + + NEW(pcibr_info); + pciio_device_info_new(&pcibr_info->f_c, + pcibr_soft->bs_vhdl, + slot, rfunc, + vendor, device); + + if (slot != PCIIO_SLOT_NONE) { + + /* + * Currently favored mapping from PCI + * slot number and INTA/B/C/D to Bridge + * PCI Interrupt Bit Number: + * + * SLOT A B C D + * 0 0 4 0 4 + * 1 1 5 1 5 + * 2 2 6 2 6 + * 3 3 7 3 7 + * 4 4 0 4 0 + * 5 5 1 5 1 + * 6 6 2 6 2 + * 7 7 3 7 3 + * + * XXX- allow pcibr_hints to override default + * XXX- allow ADMIN to override pcibr_hints + */ + for (ibit = 0; ibit < 4; ++ibit) + pcibr_info->f_ibit[ibit] = + (slot + 4 * ibit) & 7; + + /* + * Record the info in the sparse func info space. + */ +printk("pcibr_device_info_new: slot= %d func= %d bss_ninfo= %d pcibr_info= 0x%p\n", slot, func, pcibr_soft->bs_slot[slot].bss_ninfo, pcibr_info); + + if (func < pcibr_soft->bs_slot[slot].bss_ninfo) + pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info; + } + return pcibr_info; +} + +void +pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); + pcibr_info_t pcibr_info; + pciio_function_t func; + pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[slot]; + int nfunc = slotp->bss_ninfo; + + + for (func = 0; func < nfunc; func++) { + pcibr_info = slotp->bss_infos[func]; + + if (!pcibr_info) + continue; + + slotp->bss_infos[func] = 0; + pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c); + pciio_device_info_free(&pcibr_info->f_c); + DEL(pcibr_info); + } + + /* Clear the DEVIO(x) for this slot */ + slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE; + slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET; + slotp->bss_device = 0; + + + /* Reset the mapping usage counters */ + slotp->bss_pmu_uctr = 0; + slotp->bss_d32_uctr = 0; + slotp->bss_d64_uctr = 0; + + /* Clear the Direct translation info */ + slotp->bss_d64_base = PCIBR_D64_BASE_UNSET; + slotp->bss_d64_flags = 0; + slotp->bss_d32_base = PCIBR_D32_BASE_UNSET; + slotp->bss_d32_flags = 0; + + /* Clear out shadow info necessary for the external SSRAM workaround */ + slotp->bss_ext_ates_active = 0; + slotp->bss_cmd_pointer = 0; + slotp->bss_cmd_shadow = 0; + +} + +/* + * PCI_ADDR_SPACE_LIMITS_LOAD + * Gets the current values of + * pci io base, + * pci io last, + * pci low memory base, + * pci low memory last, + * pci high memory base, + * pci high memory last + */ +#define PCI_ADDR_SPACE_LIMITS_LOAD() \ + pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base; \ + pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last; \ + pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base; \ + pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last; \ + pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base; \ + pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last; +/* + * PCI_ADDR_SPACE_LIMITS_STORE + * Sets the current values of + * pci io base, + * pci io last, + * pci low memory base, + * pci low memory last, + * pci high memory base, + * pci high memory last + */ +#define PCI_ADDR_SPACE_LIMITS_STORE() \ + pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb; \ + pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl; \ + pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb; \ + pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl; \ + pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb; \ + pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl; + +#define PCI_ADDR_SPACE_LIMITS_PRINT() \ + printf("+++++++++++++++++++++++\n" \ + "IO base 0x%x last 0x%x\n" \ + "SWIN base 0x%x last 0x%x\n" \ + "MEM base 0x%x last 0x%x\n" \ + "+++++++++++++++++++++++\n", \ + pcibr_soft->bs_spinfo.pci_io_base, \ + pcibr_soft->bs_spinfo.pci_io_last, \ + pcibr_soft->bs_spinfo.pci_swin_base, \ + pcibr_soft->bs_spinfo.pci_swin_last, \ + pcibr_soft->bs_spinfo.pci_mem_base, \ + pcibr_soft->bs_spinfo.pci_mem_last); + +/* + * pcibr_slot_reset + * Reset the pci device in the particular slot . + */ +int +pcibr_slot_reset(devfs_handle_t pcibr_vhdl,pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge_t *bridge; + bridgereg_t ctrlreg,tmp; + volatile bridgereg_t *wrb_flush; + + if (!PCIBR_VALID_SLOT(slot)) + return(1); + + if (!pcibr_soft) + return(1); + + /* Enable the DMA operations from this device of the xtalk widget + * (PCI host bridge in this case). + */ + xtalk_widgetdev_enable(pcibr_soft->bs_conn, slot); + /* Set the reset slot bit in the bridge's wid control register + * to reset the pci slot + */ + bridge = pcibr_soft->bs_base; + /* Read the bridge widget control and clear out the reset pin + * bit for the corresponding slot. + */ + tmp = ctrlreg = bridge->b_wid_control; + tmp &= ~BRIDGE_CTRL_RST_PIN(slot); + bridge->b_wid_control = tmp; + tmp = bridge->b_wid_control; + /* Restore the old control register back. + * NOTE : pci card gets reset when the reset pin bit + * changes from 0 (set above) to 1 (going to be set now). + */ + bridge->b_wid_control = ctrlreg; + + /* Flush the write buffers if any !! */ + wrb_flush = &(bridge->b_wr_req_buf[slot].reg); + while (*wrb_flush); + + return(0); +} +/* + * pcibr_slot_info_init + * Probe for this slot and see if it is populated. + * If it is populated initialize the generic pci infrastructural + * information associated with this particular pci device. + */ +int +pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + bridge_t *bridge; + cfg_p cfgw; + unsigned idword; + unsigned pfail; + unsigned idwords[8]; + pciio_vendor_id_t vendor; + pciio_device_id_t device; + unsigned htype; + cfg_p wptr; + int win; + pciio_space_t space; + iopaddr_t pci_io_fb, pci_io_fl; + iopaddr_t pci_lo_fb, pci_lo_fl; + iopaddr_t pci_hi_fb, pci_hi_fl; + int nfunc; + pciio_function_t rfunc; + int func; + devfs_handle_t conn_vhdl; + pcibr_soft_slot_t slotp; + + /* Get the basic software information required to proceed */ + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft) + return(1); + + bridge = pcibr_soft->bs_base; + if (!PCIBR_VALID_SLOT(slot)) + return(1); + + slotp = &pcibr_soft->bs_slot[slot]; + + /* Load the current values of allocated pci address spaces */ + PCI_ADDR_SPACE_LIMITS_LOAD(); + + /* If we have a host slot (eg:- IOC3 has 2 pci slots and the initialization + * is done by the host slot then we are done. + */ + if (pcibr_soft->bs_slot[slot].has_host) + return(0); + + /* Try to read the device-id/vendor-id from the config space */ + cfgw = bridge->b_type0_cfg_dev[slot].l; + +#ifdef BRINGUP + if (slot < 3 || slot == 7) + return (0); + else +#endif /* BRINGUP */ + if (pcibr_probe_slot(bridge, cfgw, &idword)) + return(0); + + vendor = 0xFFFF & idword; + /* If the vendor id is not valid then the slot is not populated + * and we are done. + */ + if (vendor == 0xFFFF) + return(0); /* next slot */ + + device = 0xFFFF & (idword >> 16); + htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); + + nfunc = 1; + rfunc = PCIIO_FUNC_NONE; + pfail = 0; + + /* NOTE: if a card claims to be multifunction + * but only responds to config space 0, treat + * it as a unifunction card. + */ + + if (htype & 0x80) { /* MULTIFUNCTION */ + for (func = 1; func < 8; ++func) { + cfgw = bridge->b_type0_cfg_dev[slot].f[func].l; + if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) { + pfail |= 1 << func; + continue; + } + vendor = 0xFFFF & idwords[func]; + if (vendor == 0xFFFF) { + pfail |= 1 << func; + continue; + } + nfunc = func + 1; + rfunc = 0; + } + cfgw = bridge->b_type0_cfg_dev[slot].l; + } + NEWA(pcibr_infoh, nfunc); + + pcibr_soft->bs_slot[slot].bss_ninfo = nfunc; + pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh; + + for (func = 0; func < nfunc; ++func) { + unsigned cmd_reg; + + if (func) { + if (pfail & (1 << func)) + continue; + + idword = idwords[func]; + cfgw = bridge->b_type0_cfg_dev[slot].f[func].l; + + device = 0xFFFF & (idword >> 16); + htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1); + rfunc = func; + } + htype &= 0x7f; + if (htype != 0x00) { + PRINT_WARNING("%s pcibr: pci slot %d func %d has strange header type 0x%x\n", + pcibr_soft->bs_name, slot, func, htype); + continue; + } +#if DEBUG && ATTACH_DEBUG + PRINT_NOTICE( + "%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x", + pcibr_soft->bs_name, slot, func, vendor, device); +#endif + + pcibr_info = pcibr_device_info_new + (pcibr_soft, slot, rfunc, vendor, device); + conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c); + if (func == 0) + slotp->slot_conn = conn_vhdl; + + cmd_reg = cfgw[PCI_CFG_COMMAND / 4]; + + wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; + + + for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) { + iopaddr_t base, mask, code; + size_t size; + + /* + * GET THE BASE & SIZE OF THIS WINDOW: + * + * The low two or four bits of the BASE register + * determines which address space we are in; the + * rest is a base address. BASE registers + * determine windows that are power-of-two sized + * and naturally aligned, so we can get the size + * of a window by writing all-ones to the + * register, reading it back, and seeing which + * bits are used for decode; the least + * significant nonzero bit is also the size of + * the window. + * + * WARNING: someone may already have allocated + * some PCI space to this window, and in fact + * PIO may be in process at this very moment + * from another processor (or even from this + * one, if we get interrupted)! So, if the BASE + * already has a nonzero address, be generous + * and use the LSBit of that address as the + * size; this could overstate the window size. + * Usually, when one card is set up, all are set + * up; so, since we don't bitch about + * overlapping windows, we are ok. + * + * UNFORTUNATELY, some cards do not clear their + * BASE registers on reset. I have two heuristics + * that can detect such cards: first, if the + * decode enable is turned off for the space + * that the window uses, we can disregard the + * initial value. second, if the address is + * outside the range that we use, we can disregard + * it as well. + * + * This is looking very PCI generic. Except for + * knowing how many slots and where their config + * spaces are, this window loop and the next one + * could probably be shared with other PCI host + * adapters. It would be interesting to see if + * this could be pushed up into pciio, when we + * start supporting more PCI providers. + */ +#ifdef LITTLE_ENDIAN + base = wptr[((win*4)^4)/4]; +#else + base = wptr[win]; +#endif /* LITTLE_ENDIAN */ + + if (base & 1) { + /* BASE is in I/O space. */ + space = PCIIO_SPACE_IO; + mask = -4; + code = base & 3; + base = base & mask; + if (base == 0) { + ; /* not assigned */ + } else if (!(cmd_reg & PCI_CMD_IO_SPACE)) { + base = 0; /* decode not enabled */ + } + } else { + /* BASE is in MEM space. */ + space = PCIIO_SPACE_MEM; + mask = -16; + code = base & 15; + base = base & mask; + if (base == 0) { + ; /* not assigned */ + } else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) { + base = 0; /* decode not enabled */ + } else if (base & 0xC0000000) { + base = 0; /* outside permissable range */ + } else if ((code == PCI_BA_MEM_64BIT) && +#ifdef LITTLE_ENDIAN + (wptr[(((win + 1)*4)^4)/4] != 0)) { +#else + (wptr[win + 1] != 0)) { +#endif /* LITTLE_ENDIAN */ + base = 0; /* outside permissable range */ + } + } + + if (base != 0) { /* estimate size */ + size = base & -base; + } else { /* calculate size */ +#ifdef LITTLE_ENDIAN + wptr[((win*4)^4)/4] = ~0; /* turn on all bits */ + size = wptr[((win*4)^4)/4]; /* get stored bits */ +#else + wptr[win] = ~0; /* turn on all bits */ + size = wptr[win]; /* get stored bits */ +#endif /* LITTLE_ENDIAN */ + size &= mask; /* keep addr */ + size &= -size; /* keep lsbit */ + if (size == 0) + continue; + } + + pcibr_info->f_window[win].w_space = space; + pcibr_info->f_window[win].w_base = base; + pcibr_info->f_window[win].w_size = size; + + /* + * If this window already has PCI space + * allocated for it, "subtract" that space from + * our running freeblocks. Don't worry about + * overlaps in existing allocated windows; we + * may be overstating their sizes anyway. + */ + + if (base && size) { + if (space == PCIIO_SPACE_IO) { + pcibr_freeblock_sub(&pci_io_fb, + &pci_io_fl, + base, size); + } else { + pcibr_freeblock_sub(&pci_lo_fb, + &pci_lo_fl, + base, size); + pcibr_freeblock_sub(&pci_hi_fb, + &pci_hi_fl, + base, size); + } + } +#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM) + /* + * IOC3 BASE_ADDR* BUG WORKAROUND + * + + * If we write to BASE1 on the IOC3, the + * data in BASE0 is replaced. The + * original workaround was to remember + * the value of BASE0 and restore it + * when we ran off the end of the BASE + * registers; however, a later + * workaround was added (I think it was + * rev 1.44) to avoid setting up + * anything but BASE0, with the comment + * that writing all ones to BASE1 set + * the enable-parity-error test feature + * in IOC3's SCR bit 14. + * + * So, unless we defer doing any PCI + * space allocation until drivers + * attach, and set up a way for drivers + * (the IOC3 in paricular) to tell us + * generically to keep our hands off + * BASE registers, we gotta "know" about + * the IOC3 here. + * + * Too bad the PCI folks didn't reserve the + * all-zero value for 'no BASE here' (it is a + * valid code for an uninitialized BASE in + * 32-bit PCI memory space). + */ + + if ((vendor == IOC3_VENDOR_ID_NUM) && + (device == IOC3_DEVICE_ID_NUM)) + break; +#endif + if (code == PCI_BA_MEM_64BIT) { + win++; /* skip upper half */ +#ifdef LITTLE_ENDIAN + wptr[((win*4)^4)/4] = 0; /* which must be zero */ +#else + wptr[win] = 0; /* which must be zero */ +#endif /* LITTLE_ENDIAN */ + } + } /* next win */ + } /* next func */ + + /* Store back the values for allocated pci address spaces */ + PCI_ADDR_SPACE_LIMITS_STORE(); + return(0); +} + +/* + * pcibr_slot_info_free + * Remove all the pci infrastructural information associated + * with a particular pci device. + */ +int +pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + int nfunc; +#if defined(PCI_HOTSWAP_DEBUG) + cfg_p cfgw; + bridge_t *bridge; + int win; + cfg_p wptr; +#endif /* PCI_HOTSWAP_DEBUG */ + + + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + +#if defined(PCI_HOTSWAP_DEBUG) + /* Clean out all the base registers */ + bridge = pcibr_soft->bs_base; + cfgw = bridge->b_type0_cfg_dev[slot].l; + wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; + + for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) +#ifdef LITTLE_ENDIAN + wptr[((win*4)^4)/4] = 0; +#else + wptr[win] = 0; +#endif /* LITTLE_ENDIAN */ +#endif /* PCI_HOTSWAP_DEBUG */ + + nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; + + pcibr_device_info_free(pcibr_vhdl, slot); + + pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; + DELA(pcibr_infoh,nfunc); + pcibr_soft->bs_slot[slot].bss_ninfo = 0; + + return(0); + + +} +int as_debug = 0; +/* + * pcibr_slot_addr_space_init + * Reserve chunks of pci address space as required by + * the base registers in the card. + */ +int +pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + bridge_t *bridge; + iopaddr_t pci_io_fb, pci_io_fl; + iopaddr_t pci_lo_fb, pci_lo_fl; + iopaddr_t pci_hi_fb, pci_hi_fl; + size_t align; + iopaddr_t mask; + int nfunc; + int func; + int win; + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + + bridge = pcibr_soft->bs_base; + + /* Get the current values for the allocated pci address spaces */ + PCI_ADDR_SPACE_LIMITS_LOAD(); + + if (as_debug) +#ifdef colin + PCI_ADDR_SPACE_LIMITS_PRINT(); +#endif + /* allocate address space, + * for windows that have not been + * previously assigned. + */ + + if (pcibr_soft->bs_slot[slot].has_host) + return(0); + + nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; + if (nfunc < 1) + return(0); + + pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; + if (!pcibr_infoh) + return(0); + + /* + * Try to make the DevIO windows not + * overlap by pushing the "io" and "hi" + * allocation areas up to the next one + * or two megabyte bound. This also + * keeps them from being zero. + * + * DO NOT do this with "pci_lo" since + * the entire "lo" area is only a + * megabyte, total ... + */ + align = (slot < 2) ? 0x200000 : 0x100000; + mask = -align; + pci_io_fb = (pci_io_fb + align - 1) & mask; + pci_hi_fb = (pci_hi_fb + align - 1) & mask; + + for (func = 0; func < nfunc; ++func) { + cfg_p cfgw; + cfg_p wptr; + pciio_space_t space; + iopaddr_t base; + size_t size; + cfg_p pci_cfg_cmd_reg_p; + unsigned pci_cfg_cmd_reg; + unsigned pci_cfg_cmd_reg_add = 0; + + pcibr_info = pcibr_infoh[func]; + + if (!pcibr_info) + continue; + + if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) + continue; + + cfgw = bridge->b_type0_cfg_dev[slot].f[func].l; + wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4; + + for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) { + + space = pcibr_info->f_window[win].w_space; + base = pcibr_info->f_window[win].w_base; + size = pcibr_info->f_window[win].w_size; + + if (size < 1) + continue; + + if (base >= size) { +#if DEBUG && PCI_DEBUG + printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n", + slot, func, win, space, base, base + size - 1); +#endif + continue; /* already allocated */ + } + align = size; /* ie. 0x00001000 */ + if (align < _PAGESZ) + align = _PAGESZ; /* ie. 0x00004000 */ + mask = -align; /* ie. 0xFFFFC000 */ + + switch (space) { + case PCIIO_SPACE_IO: + base = (pci_io_fb + align - 1) & mask; + if ((base + size) > pci_io_fl) { + base = 0; + break; + } + pci_io_fb = base + size; + break; + + case PCIIO_SPACE_MEM: +#ifdef LITTLE_ENDIAN + if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) == +#else + if ((wptr[win] & PCI_BA_MEM_LOCATION) == +#endif /* LITTLE_ENDIAN */ + PCI_BA_MEM_1MEG) { + /* allocate from 20-bit PCI space */ + base = (pci_lo_fb + align - 1) & mask; + if ((base + size) > pci_lo_fl) { + base = 0; + break; + } + pci_lo_fb = base + size; + } else { + /* allocate from 32-bit or 64-bit PCI space */ + base = (pci_hi_fb + align - 1) & mask; + if ((base + size) > pci_hi_fl) { + base = 0; + break; + } + pci_hi_fb = base + size; + } + break; + + default: + base = 0; +#if DEBUG && PCI_DEBUG + printk("pcibr: slot %d window %d had bad space code %d\n", + slot, win, space); +#endif + } + pcibr_info->f_window[win].w_base = base; +#ifdef LITTLE_ENDIAN + wptr[((win*4)^4)/4] = base; + printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base); +#else + wptr[win] = base; +#endif /* LITTLE_ENDIAN */ + +#if DEBUG && PCI_DEBUG + if (base >= size) + printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n", + slot, func, win, space, base, base + size - 1); + else + printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n", + slot, func, win, size, space); +#endif + } /* next base */ + + /* + * Allocate space for the EXPANSION ROM + * NOTE: DO NOT DO THIS ON AN IOC3, + * as it blows the system away. + */ + base = size = 0; + if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) || + (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) { + + wptr = cfgw + PCI_EXPANSION_ROM / 4; +#ifdef LITTLE_ENDIAN + wptr[1] = 0xFFFFF000; + mask = wptr[1]; +#else + *wptr = 0xFFFFF000; + mask = *wptr; +#endif /* LITTLE_ENDIAN */ + if (mask & 0xFFFFF000) { + size = mask & -mask; + align = size; + if (align < _PAGESZ) + align = _PAGESZ; + mask = -align; + base = (pci_hi_fb + align - 1) & mask; + if ((base + size) > pci_hi_fl) + base = size = 0; + else { + pci_hi_fb = base + size; +#ifdef LITTLE_ENDIAN + wptr[1] = base; +#else + *wptr = base; +#endif /* LITTLE_ENDIAN */ +#if DEBUG && PCI_DEBUG + printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n", + pcibr_soft->bs_name, slot, + base, base + size - 1); +#endif + } + } + } + pcibr_info->f_rbase = base; + pcibr_info->f_rsize = size; + + /* + * if necessary, update the board's + * command register to enable decoding + * in the windows we added. + * + * There are some bits we always want to + * be sure are set. + */ + pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE; + pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE; + pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER; + + pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4; + pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p; +#if PCI_FBBE /* XXX- check here to see if dev can do fast-back-to-back */ + if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP)) + fast_back_to_back_enable = 0; +#endif + pci_cfg_cmd_reg &= 0xFFFF; + if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg) + *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add; + + } /* next func */ + + /* Now that we have allocated new chunks of pci address spaces to this + * card we need to update the bookkeeping values which indicate + * the current pci address space allocations. + */ + PCI_ADDR_SPACE_LIMITS_STORE(); + return(0); +} +/* + * pcibr_slot_device_init + * Setup the device register in the bridge for this pci slot. + */ +int +pcibr_slot_device_init(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + bridgereg_t devreg; + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + + bridge = pcibr_soft->bs_base; + + /* + * Adjustments to Device(x) + * and init of bss_device shadow + */ + devreg = bridge->b_device[slot].reg; + devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS; + devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN; +#ifdef LITTLE_ENDIAN + devreg |= BRIDGE_DEV_DEV_SWAP; +#endif + pcibr_soft->bs_slot[slot].bss_device = devreg; + bridge->b_device[slot].reg = devreg; + +#if DEBUG && PCI_DEBUG + printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg); +#endif + +#if DEBUG && PCI_DEBUG + printk("pcibr: PCI space allocation done.\n"); +#endif + + return(0); +} + +/* + * pcibr_slot_guest_info_init + * Setup the host/guest relations for a pci slot. + */ +int +pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + pcibr_soft_slot_t slotp; + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + + slotp = &pcibr_soft->bs_slot[slot]; + + /* create info and verticies for guest slots; + * for compatibilitiy macros, create info + * for even unpopulated slots (but do not + * build verticies for them). + */ + if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) { + NEWA(pcibr_infoh, 1); + pcibr_soft->bs_slot[slot].bss_ninfo = 1; + pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh; + + pcibr_info = pcibr_device_info_new + (pcibr_soft, slot, PCIIO_FUNC_NONE, + PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE); + + if (pcibr_soft->bs_slot[slot].has_host) { + slotp->slot_conn = pciio_device_info_register + (pcibr_vhdl, &pcibr_info->f_c); + } + } + + /* generate host/guest relations + */ + if (pcibr_soft->bs_slot[slot].has_host) { + int host = pcibr_soft->bs_slot[slot].host_slot; + pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host]; + + hwgraph_edge_add(slotp->slot_conn, + host_slotp->slot_conn, + EDGE_LBL_HOST); + + /* XXX- only gives us one guest edge per + * host. If/when we have a host with more than + * one guest, we will need to figure out how + * the host finds all its guests, and sorts + * out which one is which. + */ + hwgraph_edge_add(host_slotp->slot_conn, + slotp->slot_conn, + EDGE_LBL_GUEST); + } + + return(0); +} +/* + * pcibr_slot_initial_rrb_alloc + * Allocate a default number of rrbs for this slot on + * the two channels. This is dictated by the rrb allocation + * strategy routine defined per platform. + */ + +int +pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) + +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + bridge_t *bridge; + int c0, c1; + int r; + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + + bridge = pcibr_soft->bs_base; + + + /* How may RRBs are on this slot? + */ + c0 = do_pcibr_rrb_count_valid(bridge, slot); + c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL); +#if PCIBR_RRB_DEBUG + printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1); +#endif + + /* Do we really need any? + */ + pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; + pcibr_info = pcibr_infoh[0]; + if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && + !pcibr_soft->bs_slot[slot].has_host) { + if (c0 > 0) + do_pcibr_rrb_free(bridge, slot, c0); + if (c1 > 0) + do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1); + pcibr_soft->bs_rrb_valid[slot] = 0x1000; + pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000; + return(0); + } + + pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1; + pcibr_soft->bs_rrb_valid[slot] = c0; + pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1; + + pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0); + pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1); + + r = 3 - (c0 + c1); + + if (r > 0) { + pcibr_soft->bs_rrb_res[slot] = r; + pcibr_soft->bs_rrb_avail[slot & 1] -= r; + } + +#if PCIBR_RRB_DEBUG + printk("\t%d+%d+%d", + 0xFFF & pcibr_soft->bs_rrb_valid[slot], + 0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], + pcibr_soft->bs_rrb_res[slot]); + printk("\n"); +#endif + return(0); +} + +/* + * pcibr_slot_call_device_attach + * This calls the associated driver attach routine for the pci + * card in this slot. + */ +int +pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + async_attach_t aa = NULL; + int func; + devfs_handle_t xconn_vhdl,conn_vhdl; + int nfunc; + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + + + if (pcibr_soft->bs_slot[slot].has_host) + return(0); + + xconn_vhdl = pcibr_soft->bs_conn; + aa = async_attach_get_info(xconn_vhdl); + + nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; + pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; + + printk("\npcibr_slot_call_device_attach: link 0x%p pci bus 0x%p slot %d\n", xconn_vhdl, pcibr_vhdl, slot); + + for (func = 0; func < nfunc; ++func) { + + pcibr_info = pcibr_infoh[func]; + + if (!pcibr_info) + continue; + + if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) + continue; + + conn_vhdl = pcibr_info->f_vertex; + + /* If the pci device has been disabled in the prom, + * do not set it up for driver attach. NOTE: usrpci + * and pciba will not "see" this connection point! + */ + if (device_admin_info_get(conn_vhdl, ADMIN_LBL_DISABLED)) { +#ifdef SUPPORT_PRINTING_V_FORMAT + PRINT_WARNING( "pcibr_slot_call_device_attach: %v disabled\n", + conn_vhdl); +#endif + continue; + } + if (aa) + async_attach_add_info(conn_vhdl, aa); + pciio_device_attach(conn_vhdl); + } /* next func */ + + printk("\npcibr_slot_call_device_attach: DONE\n"); + + return(0); +} +/* + * pcibr_slot_call_device_detach + * This calls the associated driver detach routine for the pci + * card in this slot. + */ +int +pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + pcibr_soft_t pcibr_soft; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + int func; + devfs_handle_t conn_vhdl; + int nfunc; + int ndetach = 1; + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (!pcibr_soft || !PCIBR_VALID_SLOT(slot)) + return(1); + + + if (pcibr_soft->bs_slot[slot].has_host) + return(0); + + + nfunc = pcibr_soft->bs_slot[slot].bss_ninfo; + pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos; + + for (func = 0; func < nfunc; ++func) { + + pcibr_info = pcibr_infoh[func]; + + if (!pcibr_info) + continue; + + if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) + continue; + + conn_vhdl = pcibr_info->f_vertex; + + /* Make sure that we do not detach a system critical device + * vertex. + */ + if (is_sys_critical_vertex(conn_vhdl)) { +#ifdef SUPPORT_PRINTING_V_FORMAT + PRINT_WARNING( "%v is a system critical device vertex\n", + conn_vhdl); +#endif + continue; + } + + ndetach = 0; + pciio_device_detach(conn_vhdl); + } /* next func */ + + + return(ndetach); +} + +/* + * pcibr_device_attach + * This is a place holder routine to keep track of all the + * slot-specific initialization that needs to be done. + * This is usually called when we want to initialize a new + * pci card on the bus. + */ +int +pcibr_device_attach(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + return ( + /* Reset the slot */ + pcibr_slot_reset(pcibr_vhdl,slot) || + /* FInd out what is out there */ + pcibr_slot_info_init(pcibr_vhdl,slot) || + + /* Set up the address space for this slot in the pci land */ + pcibr_slot_addr_space_init(pcibr_vhdl,slot) || + + /* Setup the device register */ + pcibr_slot_device_init(pcibr_vhdl, slot) || + + /* Setup host/guest relations */ + pcibr_slot_guest_info_init(pcibr_vhdl,slot) || + + /* Initial RRB management */ + pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot) || + + /* Call the device attach */ + pcibr_slot_call_device_attach(pcibr_vhdl,slot) + ); + +} +/* + * pcibr_device_detach + * This is a place holder routine to keep track of all the + * slot-specific freeing that needs to be done. + */ +int +pcibr_device_detach(devfs_handle_t pcibr_vhdl, + pciio_slot_t slot) +{ + + /* Call the device detach */ + return (pcibr_slot_call_device_detach(pcibr_vhdl,slot)); + +} +/* + * pcibr_device_unregister + * This frees up any hardware resources reserved for this pci device + * and removes any pci infrastructural information setup for it. + * This is usually used at the time of shutting down of the pci card. + */ +void +pcibr_device_unregister(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info; + devfs_handle_t pcibr_vhdl; + pciio_slot_t slot; + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + + pciio_info = pciio_info_get(pconn_vhdl); + + /* Detach the pciba name space */ + pciio_device_detach(pconn_vhdl); + + pcibr_vhdl = pciio_info_master_get(pciio_info); + slot = pciio_info_slot_get(pciio_info); + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge = pcibr_soft->bs_base; + + /* Clear all the hardware xtalk resources for this device */ + xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot); + + /* Flush all the rrbs */ + pcibr_rrb_flush(pconn_vhdl); + + /* Free the rrbs allocated to this slot */ + do_pcibr_rrb_free(bridge, slot, + pcibr_soft->bs_rrb_valid[slot] + + pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL]); + + + pcibr_soft->bs_rrb_valid[slot] = 0; + pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0; + pcibr_soft->bs_rrb_res[slot] = 0; + + /* Flush the write buffers !! */ + (void)pcibr_wrb_flush(pconn_vhdl); + /* Clear the information specific to the slot */ + (void)pcibr_slot_info_free(pcibr_vhdl, slot); + +} + +/* + * build a convenience link path in the + * form of "...//bus/" + * + * returns 1 on success, 0 otherwise + * + * depends on hwgraph separator == '/' + */ +int +pcibr_bus_cnvlink(devfs_handle_t f_c, int slot) +{ + char dst[MAXDEVNAME]; + char *dp = dst; + char *cp, *xp; + int widgetnum; + char pcibus[8]; + devfs_handle_t nvtx, svtx; + int rv; + +#if DEBUG + printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", + slot, f_c); + { + int pos; + char dname[256]; + pos = devfs_generate_path(f_c, dname, 256); + printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); + } +#endif + + if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME)) + return 0; + + /* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */ + + /* find the widget number */ + xp = strstr(dst, "/"EDGE_LBL_XTALK"/"); + if (xp == NULL) + return 0; + widgetnum = atoi(xp+7); + if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F) + return 0; + + /* remove "/pci/direct" from path */ + cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct"); + if (cp == NULL) + return 0; + *cp = (char)NULL; + + /* get the vertex for the widget */ + if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx)) + return 0; + + *xp = (char)NULL; /* remove "/xtalk/..." from path */ + + /* dst example now == /hw/module/001c02/Pbrick */ + + /* get the bus number */ + strcat(dst, "/bus"); + sprintf(pcibus, "%d", p_busnum[widgetnum]); + + /* link to bus to widget */ + rv = hwgraph_path_add(NULL, dp, &nvtx); + if (GRAPH_SUCCESS == rv) + rv = hwgraph_edge_add(nvtx, svtx, pcibus); + + return (rv == GRAPH_SUCCESS); +} + +/* + * pcibr_attach: called every time the crosstalk + * infrastructure is asked to initialize a widget + * that matches the part number we handed to the + * registration routine above. + */ +/*ARGSUSED */ +int +pcibr_attach(devfs_handle_t xconn_vhdl) +{ + /* REFERENCED */ + graph_error_t rc; + devfs_handle_t pcibr_vhdl; + devfs_handle_t ctlr_vhdl; + bridge_t *bridge = NULL; + bridgereg_t id; + int rev; + pcibr_soft_t pcibr_soft; + pcibr_info_t pcibr_info; + xwidget_info_t info; + xtalk_intr_t xtalk_intr; + device_desc_t dev_desc; + int slot; + int ibit; + devfs_handle_t noslot_conn; + char devnm[MAXDEVNAME], *s; + pcibr_hints_t pcibr_hints; + bridgereg_t b_int_enable; + unsigned rrb_fixed = 0; + + iopaddr_t pci_io_fb, pci_io_fl; + iopaddr_t pci_lo_fb, pci_lo_fl; + iopaddr_t pci_hi_fb, pci_hi_fl; + + int spl_level; + char *nicinfo = (char *)0; + +#if PCI_FBBE + int fast_back_to_back_enable; +#endif + + async_attach_t aa = NULL; + + aa = async_attach_get_info(xconn_vhdl); + +#if DEBUG && ATTACH_DEBUG + printk("pcibr_attach: xconn_vhdl= %p\n", xconn_vhdl); + { + int pos; + char dname[256]; + pos = devfs_generate_path(xconn_vhdl, dname, 256); + printk("%s : path= %s \n", __FUNCTION__, &dname[pos]); + } +#endif + + /* Setup the PRB for the bridge in CONVEYOR BELT + * mode. PRBs are setup in default FIRE-AND-FORGET + * mode during the initialization. + */ + hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR); + + bridge = (bridge_t *) + xtalk_piotrans_addr(xconn_vhdl, NULL, + 0, sizeof(bridge_t), 0); + +#ifndef MEDUSA_HACK + if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0) + return -1; /* someone else handles GIO bridges. */ +#endif + +#ifdef BRINGUP + if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A) + NeedXbridgeSwap = 1; +#endif + + printk("pcibr_attach: Called with vertex 0x%p, b_wid_stat 0x%x, gio 0x%x\n",xconn_vhdl, bridge->b_wid_stat, BRIDGE_STAT_PCI_GIO_N); + + /* + * Create the vertex for the PCI bus, which we + * will also use to hold the pcibr_soft and + * which will be the "master" vertex for all the + * pciio connection points we will hang off it. + * This needs to happen before we call nic_bridge_vertex_info + * as we are some of the *_vmc functions need access to the edges. + * + * Opening this vertex will provide access to + * the Bridge registers themselves. + */ + rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl); + ASSERT(rc == GRAPH_SUCCESS); + + rc = hwgraph_char_device_add(pcibr_vhdl, EDGE_LBL_CONTROLLER, "pcibr_", &ctlr_vhdl); + ASSERT(rc == GRAPH_SUCCESS); + + /* + * decode the nic, and hang its stuff off our + * connection point where other drivers can get + * at it. + */ +#ifdef LATER + nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic); +#endif + + /* + * Get the hint structure; if some NIC callback + * marked this vertex as "hands-off" then we + * just return here, before doing anything else. + */ + pcibr_hints = pcibr_hints_get(xconn_vhdl, 0); + + if (pcibr_hints && pcibr_hints->ph_hands_off) + return -1; /* generic operations disabled */ + + id = bridge->b_wid_id; + rev = XWIDGET_PART_REV_NUM(id); + + hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev); + + /* + * allocate soft state structure, fill in some + * fields, and hook it up to our vertex. + */ + NEW(pcibr_soft); + BZERO(pcibr_soft, sizeof *pcibr_soft); + pcibr_soft_set(pcibr_vhdl, pcibr_soft); + + pcibr_soft->bs_conn = xconn_vhdl; + pcibr_soft->bs_vhdl = pcibr_vhdl; + pcibr_soft->bs_base = bridge; + pcibr_soft->bs_rev_num = rev; + pcibr_soft->bs_intr_bits = pcibr_intr_bits; + if (is_xbridge(bridge)) { + pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES; + pcibr_soft->bs_xbridge = 1; + } else { + pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES; + pcibr_soft->bs_xbridge = 0; + } + + pcibr_soft->bsi_err_intr = 0; + + /* Bridges up through REV C + * are unable to set the direct + * byteswappers to BYTE_STREAM. + */ + if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) { + pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES; + pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES; + } +#if PCIBR_SOFT_LIST + { + pcibr_list_p self; + + NEW(self); + self->bl_soft = pcibr_soft; + self->bl_vhdl = pcibr_vhdl; + self->bl_next = pcibr_list; + self->bl_next = swap_ptr((void **) &pcibr_list, (void *)self); + } +#endif + + /* + * get the name of this bridge vertex and keep the info. Use this + * only where it is really needed now: like error interrupts. + */ + s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME); + pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL); + strcpy(pcibr_soft->bs_name, s); + +#if SHOW_REVS || DEBUG +#if !DEBUG + if (kdebug) +#endif + printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n", + is_xbridge(bridge) ? "X" : "", + (rev == BRIDGE_PART_REV_A) ? "A" : + (rev == BRIDGE_PART_REV_B) ? "B" : + (rev == BRIDGE_PART_REV_C) ? "C" : + (rev == BRIDGE_PART_REV_D) ? "D" : + (rev == XBRIDGE_PART_REV_A) ? "A" : + (rev == XBRIDGE_PART_REV_B) ? "B" : + "unknown", + rev, pcibr_soft->bs_name); +#endif + + info = xwidget_info_get(xconn_vhdl); + pcibr_soft->bs_xid = xwidget_info_id_get(info); + pcibr_soft->bs_master = xwidget_info_master_get(info); + pcibr_soft->bs_mxid = xwidget_info_masterid_get(info); + + /* + * Init bridge lock. + */ + spinlock_init(&pcibr_soft->bs_lock, "pcibr_loc"); + + /* + * If we have one, process the hints structure. + */ + if (pcibr_hints) { + rrb_fixed = pcibr_hints->ph_rrb_fixed; + + pcibr_soft->bs_rrb_fixed = rrb_fixed; + + if (pcibr_hints->ph_intr_bits) + pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits; + + for (slot = 0; slot < 8; ++slot) { + int hslot = pcibr_hints->ph_host_slot[slot] - 1; + + if (hslot < 0) { + pcibr_soft->bs_slot[slot].host_slot = slot; + } else { + pcibr_soft->bs_slot[slot].has_host = 1; + pcibr_soft->bs_slot[slot].host_slot = hslot; + } + } + } + /* + * set up initial values for state fields + */ + for (slot = 0; slot < 8; ++slot) { + pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE; + pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET; + pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET; + pcibr_soft->bs_slot[slot].bss_ext_ates_active = 0; + } + + for (ibit = 0; ibit < 8; ++ibit) { + pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0; + pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_list = 0; + } + + /* + * connect up our error handler + */ + xwidget_error_register(xconn_vhdl, pcibr_error_handler, pcibr_soft); + + /* + * Initialize various Bridge registers. + */ + + /* + * On pre-Rev.D bridges, set the PCI_RETRY_CNT + * to zero to avoid dropping stores. (#475347) + */ + if (rev < BRIDGE_PART_REV_D) + bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK; + + /* + * Clear all pending interrupts. + */ + bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR); + + /* + * Until otherwise set up, + * assume all interrupts are + * from slot 7. + */ + bridge->b_int_device = (uint32_t) 0xffffffff; + + { + bridgereg_t dirmap; + paddr_t paddr; + iopaddr_t xbase; + xwidgetnum_t xport; + iopaddr_t offset; + int num_entries; + int entry; + cnodeid_t cnodeid; + nasid_t nasid; + char *node_val; + devfs_handle_t node_vhdl; + char vname[MAXDEVNAME]; + + /* Set the Bridge's 32-bit PCI to XTalk + * Direct Map register to the most useful + * value we can determine. Note that we + * must use a single xid for all of: + * direct-mapped 32-bit DMA accesses + * direct-mapped 64-bit DMA accesses + * DMA accesses through the PMU + * interrupts + * This is the only way to guarantee that + * completion interrupts will reach a CPU + * after all DMA data has reached memory. + * (Of course, there may be a few special + * drivers/controlers that explicitly manage + * this ordering problem.) + */ + + cnodeid = 0; /* default node id */ + /* + * Determine the base address node id to be used for all 32-bit + * Direct Mapping I/O. The default is node 0, but this can be changed + * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE + * attribute in the irix.sm config file. A device driver can obtain + * this node value via a call to pcibr_get_dmatrans_node(). + */ + node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE); + if (node_val != NULL) { + node_vhdl = hwgraph_path_to_vertex(node_val); + if (node_vhdl != GRAPH_VERTEX_NONE) { + cnodeid = nodevertex_to_cnodeid(node_vhdl); + } + if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) { + cnodeid = 0; + vertex_to_name(pcibr_vhdl, vname, sizeof(vname)); + PRINT_WARNING( "Invalid hwgraph node path specified:\n DEVICE_ADMIN: %s %s=%s\n", + vname, ADMIN_LBL_DMATRANS_NODE, node_val); + } + } + nasid = COMPACT_TO_NASID_NODEID(cnodeid); + paddr = NODE_OFFSET(nasid) + 0; + + /* currently, we just assume that if we ask + * for a DMA mapping to "zero" the XIO + * host will transmute this into a request + * for the lowest hunk of memory. + */ + xbase = xtalk_dmatrans_addr(xconn_vhdl, 0, + paddr, _PAGESZ, 0); + + if (xbase != XIO_NOWHERE) { + if (XIO_PACKED(xbase)) { + xport = XIO_PORT(xbase); + xbase = XIO_ADDR(xbase); + } else + xport = pcibr_soft->bs_mxid; + + offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull); + xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT; + + dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT; + +#ifdef IRIX + dirmap |= BRIDGE_DIRMAP_RMF_64; +#endif + + if (xbase) + dirmap |= BRIDGE_DIRMAP_OFF & xbase; + else if (offset >= (512 << 20)) + dirmap |= BRIDGE_DIRMAP_ADD512; + + bridge->b_dir_map = dirmap; + } + /* + * Set bridge's idea of page size according to the system's + * idea of "IO page size". TBD: The idea of IO page size + * should really go away. + */ + /* + * ensure that we write and read without any interruption. + * The read following the write is required for the Bridge war + */ + spl_level = splhi(); +#if IOPGSIZE == 4096 + bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; +#elif IOPGSIZE == 16384 + bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE; +#else + <<>>; +#endif + bridge->b_wid_control; /* inval addr bug war */ + splx(spl_level); + + /* Initialize internal mapping entries */ + for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++) + bridge->b_int_ate_ram[entry].wr = 0; + + /* + * Determine if there's external mapping SSRAM on this + * bridge. Set up Bridge control register appropriately, + * inititlize SSRAM, and set software up to manage RAM + * entries as an allocatable resource. + * + * Currently, we just use the rm* routines to manage ATE + * allocation. We should probably replace this with a + * Best Fit allocator. + * + * For now, if we have external SSRAM, avoid using + * the internal ssram: we can't turn PREFETCH on + * when we use the internal SSRAM; and besides, + * this also guarantees that no allocation will + * straddle the internal/external line, so we + * can increment ATE write addresses rather than + * recomparing against BRIDGE_INTERNAL_ATES every + * time. + */ +#ifdef BRINGUP + /* + * 082799: for some reason pcibr_init_ext_ate_ram is causing + * a Data Bus Error. It should be zero anyway so just force it. + */ + num_entries = 0; +#else + num_entries = pcibr_init_ext_ate_ram(bridge); +#endif + + /* 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); +#if PCIBR_ATE_DEBUG + printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size); +#endif + + 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); +#if PCIBR_ATE_DEBUG + printk("pcibr_attach: %d EXTERNAL ATEs\n", + num_entries - pcibr_soft->bs_int_ate_size); +#endif + } + } + + { + bridgereg_t dirmap; + iopaddr_t xbase; + + /* + * now figure the *real* xtalk base address + * that dirmap sends us to. + */ + dirmap = bridge->b_dir_map; + if (dirmap & BRIDGE_DIRMAP_OFF) + xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF) + << BRIDGE_DIRMAP_OFF_ADDRSHFT; + else if (dirmap & BRIDGE_DIRMAP_ADD512) + xbase = 512 << 20; + else + xbase = 0; + + pcibr_soft->bs_dir_xbase = xbase; + + /* it is entirely possible that we may, at this + * point, have our dirmap pointing somewhere + * other than our "master" port. + */ + pcibr_soft->bs_dir_xport = + (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT; + } + + /* pcibr sources an error interrupt; + * figure out where to send it. + * + * If any interrupts are enabled in bridge, + * then the prom set us up and our interrupt + * has already been reconnected in mlreset + * above. + * + * Need to set the D_INTR_ISERR flag + * in the dev_desc used for alocating the + * error interrupt, so our interrupt will + * be properly routed and prioritized. + * + * If our crosstalk provider wants to + * fix widget error interrupts to specific + * destinations, D_INTR_ISERR is how it + * knows to do this. + */ + + dev_desc = device_desc_dup(pcibr_vhdl); + device_desc_flags_set(dev_desc, + device_desc_flags_get(dev_desc) | D_INTR_ISERR); + device_desc_intr_name_set(dev_desc, "Bridge error"); + + xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl); + ASSERT(xtalk_intr != NULL); + + device_desc_free(dev_desc); + + pcibr_soft->bsi_err_intr = xtalk_intr; + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + /* + * On IP35 with XBridge, we do some extra checks in pcibr_setwidint + * in order to work around some addressing limitations. In order + * for that fire wall to work properly, we need to make sure we + * start from a known clean state. + */ + pcibr_clearwidint(bridge); +#endif + + printk("pribr_attach: FIXME Error Interrupt not registered\n"); + + xtalk_intr_connect(xtalk_intr, + (intr_func_t) pcibr_error_intr_handler, + (intr_arg_t) pcibr_soft, + (xtalk_intr_setfunc_t) pcibr_setwidint, + (void *) bridge, + (void *) 0); + + /* + * now we can start handling error interrupts; + * enable all of them. + * NOTE: some PCI ints may already be enabled. + */ + b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS; + + + bridge->b_int_enable = b_int_enable; + bridge->b_int_mode = 0; /* do not send "clear interrupt" packets */ + + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + + /* + * Depending on the rev of bridge, disable certain features. + * Easiest way seems to be to force the PCIBR_NOwhatever + * flag to be on for all DMA calls, which overrides any + * PCIBR_whatever flag or even the setting of whatever + * from the PCIIO_DMA_class flags (or even from the other + * PCIBR flags, since NO overrides YES). + */ + pcibr_soft->bs_dma_flags = 0; + + /* PREFETCH: + * Always completely disabled for REV.A; + * at "pcibr_prefetch_enable_rev", anyone + * asking for PCIIO_PREFETCH gets it. + * Between these two points, you have to ask + * for PCIBR_PREFETCH, which promises that + * your driver knows about known Bridge WARs. + */ + if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B) + pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH; + else if (pcibr_soft->bs_rev_num < + (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev)) + pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH; + + /* WRITE_GATHER: + * Disabled up to but not including the + * rev number in pcibr_wg_enable_rev. There + * is no "WAR range" as with prefetch. + */ + if (pcibr_soft->bs_rev_num < + (BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev)) + pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER; + + pciio_provider_register(pcibr_vhdl, &pcibr_provider); + pciio_provider_startup(pcibr_vhdl); + + pci_io_fb = 0x00000004; /* I/O FreeBlock Base */ + pci_io_fl = 0xFFFFFFFF; /* I/O FreeBlock Last */ + + pci_lo_fb = 0x00000010; /* Low Memory FreeBlock Base */ + pci_lo_fl = 0x001FFFFF; /* Low Memory FreeBlock Last */ + + pci_hi_fb = 0x00200000; /* High Memory FreeBlock Base */ + pci_hi_fl = 0x3FFFFFFF; /* High Memory FreeBlock Last */ + + + PCI_ADDR_SPACE_LIMITS_STORE(); + + /* build "no-slot" connection point + */ + pcibr_info = pcibr_device_info_new + (pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE, + PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE); + noslot_conn = pciio_device_info_register + (pcibr_vhdl, &pcibr_info->f_c); + + /* Remember the no slot connection point info for tearing it + * down during detach. + */ + pcibr_soft->bs_noslot_conn = noslot_conn; + pcibr_soft->bs_noslot_info = pcibr_info; +#if PCI_FBBE + fast_back_to_back_enable = 1; +#endif + +#if PCI_FBBE + if (fast_back_to_back_enable) { + /* + * All devices on the bus are capable of fast back to back, so + * we need to set the fast back to back bit in all devices on + * the bus that are capable of doing such accesses. + */ + } +#endif + +#ifdef IRIX + /* If the bridge has been reset then there is no need to reset + * the individual PCI slots. + */ + for (slot = 0; slot < 8; ++slot) + /* Reset all the slots */ + (void)pcibr_slot_reset(pcibr_vhdl,slot); +#endif + + for (slot = 0; slot < 8; ++slot) + /* Find out what is out there */ + (void)pcibr_slot_info_init(pcibr_vhdl,slot); + + for (slot = 0; slot < 8; ++slot) + /* Set up the address space for this slot in the pci land */ + (void)pcibr_slot_addr_space_init(pcibr_vhdl,slot); + + for (slot = 0; slot < 8; ++slot) + /* Setup the device register */ + (void)pcibr_slot_device_init(pcibr_vhdl, slot); + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + for (slot = 0; slot < 8; ++slot) + /* Set up convenience links */ + if (is_xbridge(bridge)) + if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */ + pcibr_bus_cnvlink(pcibr_info->f_vertex, slot); +#endif + + for (slot = 0; slot < 8; ++slot) + /* Setup host/guest relations */ + (void)pcibr_slot_guest_info_init(pcibr_vhdl,slot); + + for (slot = 0; slot < 8; ++slot) + /* Initial RRB management */ + (void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot); + +#ifdef dagum + /* driver attach routines should be called out from generic linux code */ + for (slot = 0; slot < 8; ++slot) + /* Call the device attach */ + (void)pcibr_slot_call_device_attach(pcibr_vhdl,slot); +#endif /* dagum */ + +#ifdef LATER + if (strstr(nicinfo, XTALK_PCI_PART_NUM)) { + do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8); +#if PCIBR_RRB_DEBUG + printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl); + + printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n", + pcibr_vhdl, + pcibr_soft->bs_rrb_avail[0], + pcibr_soft->bs_rrb_avail[1]); + + for (slot = 0; slot < 8; ++slot) + printf("\t%d+%d+%d", + 0xFFF & pcibr_soft->bs_rrb_valid[slot], + 0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], + pcibr_soft->bs_rrb_res[slot]); + + printf("\n"); +#endif + } +#else + printk("pcibr_attach: FIXME to call do_pcibr_rrb_autoalloc nicinfo 0x%p\n", nicinfo); +#endif + + if (aa) + async_attach_add_info(noslot_conn, aa); + + pciio_device_attach(noslot_conn); + + + /* + * Tear down pointer to async attach info -- async threads for + * bridge's descendants may be running but the bridge's work is done. + */ + if (aa) + async_attach_del_info(xconn_vhdl); + + return 0; +} +/* + * pcibr_detach: + * Detach the bridge device from the hwgraph after cleaning out all the + * underlying vertices. + */ +int +pcibr_detach(devfs_handle_t xconn) +{ + pciio_slot_t slot; + devfs_handle_t pcibr_vhdl; + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + + /* Get the bridge vertex from its xtalk connection point */ + if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS) + return(1); + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + bridge = pcibr_soft->bs_base; + + /* Disable the interrupts from the bridge */ + bridge->b_int_enable = 0; + + /* Detach all the PCI devices talking to this bridge */ + for(slot = 0; slot < 8; slot++) { +#ifdef DEBUG + printk("pcibr_device_detach called for %p/%d\n", + pcibr_vhdl,slot); +#endif + pcibr_device_detach(pcibr_vhdl, slot); + } + + /* Unregister the no-slot connection point */ + pciio_device_info_unregister(pcibr_vhdl, + &(pcibr_soft->bs_noslot_info->f_c)); + + spinlock_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. + */ + xtalk_intr_disconnect(pcibr_soft->bsi_err_intr); + xtalk_intr_free(pcibr_soft->bsi_err_intr); + + /* Clear the software state maintained by the bridge driver for this + * bridge. + */ + DEL(pcibr_soft); + /* Remove the Bridge revision labelled info */ + (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL); + /* Remove the character device associated with this bridge */ + (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL); + /* Remove the PCI bridge vertex */ + (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL); + + return(0); +} + +int +pcibr_asic_rev(devfs_handle_t pconn_vhdl) +{ + devfs_handle_t pcibr_vhdl; + arbitrary_info_t ainfo; + + if (GRAPH_SUCCESS != + hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl)) + return -1; + + if (GRAPH_SUCCESS != + hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo)) + return -1; + + return (int) ainfo; +} + +int +pcibr_write_gather_flush(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + pciio_slot_t slot; + slot = pciio_info_slot_get(pciio_info); + pcibr_device_write_gather_flush(pcibr_soft, slot); + return 0; +} + +/* ===================================================================== + * PIO MANAGEMENT + */ + +LOCAL iopaddr_t +pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl, + pciio_slot_t slot, + pciio_space_t space, + iopaddr_t pci_addr, + size_t req_size, + unsigned flags) +{ + pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); + pciio_info_t pciio_info = &pcibr_info->f_c; + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridge_t *bridge = pcibr_soft->bs_base; + + unsigned bar; /* which BASE reg on device is decoding */ + iopaddr_t xio_addr = XIO_NOWHERE; + + pciio_space_t wspace; /* which space device is decoding */ + iopaddr_t wbase; /* base of device decode on PCI */ + size_t wsize; /* size of device decode on PCI */ + + int try; /* DevIO(x) window scanning order control */ + int win; /* which DevIO(x) window is being used */ + pciio_space_t mspace; /* target space for devio(x) register */ + iopaddr_t mbase; /* base of devio(x) mapped area on PCI */ + size_t msize; /* size of devio(x) mapped area on PCI */ + size_t mmask; /* addr bits stored in Device(x) */ + + unsigned s; + + s = pcibr_lock(pcibr_soft); + + if (pcibr_soft->bs_slot[slot].has_host) { + slot = pcibr_soft->bs_slot[slot].host_slot; + pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0]; + } + if (space == PCIIO_SPACE_NONE) + goto done; + + if (space == PCIIO_SPACE_CFG) { + /* + * Usually, the first mapping + * established to a PCI device + * is to its config space. + * + * In any case, we definitely + * do NOT need to worry about + * PCI BASE registers, and + * MUST NOT attempt to point + * the DevIO(x) window at + * this access ... + */ + if (((flags & PCIIO_BYTE_STREAM) == 0) && + ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF)) + xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot); + + goto done; + } + if (space == PCIIO_SPACE_ROM) { + /* PIO to the Expansion Rom. + * Driver is responsible for + * enabling and disabling + * decodes properly. + */ + wbase = pcibr_info->f_rbase; + wsize = pcibr_info->f_rsize; + + /* + * While the driver should know better + * than to attempt to map more space + * than the device is decoding, he might + * do it; better to bail out here. + */ + if ((pci_addr + req_size) > wsize) + goto done; + + pci_addr += wbase; + space = PCIIO_SPACE_MEM; + } + /* + * reduce window mappings to raw + * space mappings (maybe allocating + * windows), and try for DevIO(x) + * usage (setting it if it is available). + */ + bar = space - PCIIO_SPACE_WIN0; + if (bar < 6) { + wspace = pcibr_info->f_window[bar].w_space; + if (wspace == PCIIO_SPACE_NONE) + goto done; + + /* get pci base and size */ + wbase = pcibr_info->f_window[bar].w_base; + wsize = pcibr_info->f_window[bar].w_size; + + /* + * While the driver should know better + * than to attempt to map more space + * than the device is decoding, he might + * do it; better to bail out here. + */ + if ((pci_addr + req_size) > wsize) + goto done; + + /* shift from window relative to + * decoded space relative. + */ + pci_addr += wbase; + space = wspace; + } else + bar = -1; + + /* Scan all the DevIO(x) windows twice looking for one + * that can satisfy our request. The first time through, + * only look at assigned windows; the second time, also + * look at PCIIO_SPACE_NONE windows. Arrange the order + * so we always look at our own window first. + * + * We will not attempt to satisfy a single request + * by concatinating multiple windows. + */ + for (try = 0; try < 16; ++try) { + bridgereg_t devreg; + unsigned offset; + + win = (try + slot) % 8; + + /* If this DevIO(x) mapping area can provide + * a mapping to this address, use it. + */ + msize = (win < 2) ? 0x200000 : 0x100000; + mmask = -msize; + if (space != PCIIO_SPACE_IO) + mmask &= 0x3FFFFFFF; + + offset = pci_addr & (msize - 1); + + /* If this window can't possibly handle that request, + * go on to the next window. + */ + if (((pci_addr & (msize - 1)) + req_size) > msize) + continue; + + devreg = pcibr_soft->bs_slot[win].bss_device; + + /* Is this window "nailed down"? + * If not, maybe we can use it. + * (only check this the second time through) + */ + mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space; + if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) { + + /* If this is the primary DevIO(x) window + * for some other device, skip it. + */ + if ((win != slot) && + (PCIIO_VENDOR_ID_NONE != + pcibr_soft->bs_slot[win].bss_vendor_id)) + continue; + + /* It's a free window, and we fit in it. + * Set up Device(win) to our taste. + */ + mbase = pci_addr & mmask; + + /* check that we would really get from + * here to there. + */ + if ((mbase | offset) != pci_addr) + continue; + + devreg &= ~BRIDGE_DEV_OFF_MASK; + if (space != PCIIO_SPACE_IO) + devreg |= BRIDGE_DEV_DEV_IO_MEM; + else + devreg &= ~BRIDGE_DEV_DEV_IO_MEM; + devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK; + + /* default is WORD_VALUES. + * if you specify both, + * operation is undefined. + */ + if (flags & PCIIO_BYTE_STREAM) + devreg |= BRIDGE_DEV_DEV_SWAP; + else + devreg &= ~BRIDGE_DEV_DEV_SWAP; + + if (pcibr_soft->bs_slot[win].bss_device != devreg) { + bridge->b_device[win].reg = devreg; + pcibr_soft->bs_slot[win].bss_device = devreg; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + +#if DEBUG && PCI_DEBUG + printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg); +#endif + } + pcibr_soft->bs_slot[win].bss_devio.bssd_space = space; + pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase; + xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase); + +#if DEBUG && PCI_DEBUG + printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", + __FUNCTION__, __LINE__, space, space_desc, + pci_addr, pci_addr + req_size - 1, + slot, win, devreg); +#endif + + goto done; + } /* endif DevIO(x) not pointed */ + mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base; + + /* Now check for request incompat with DevIO(x) + */ + if ((mspace != space) || + (pci_addr < mbase) || + ((pci_addr + req_size) > (mbase + msize)) || + ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) || + (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP))) + continue; + + /* DevIO(x) window is pointed at PCI space + * that includes our target. Calculate the + * final XIO address, release the lock and + * return. + */ + xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase); + +#if DEBUG && PCI_DEBUG + printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n", + __FUNCTION__, __LINE__, space, pci_addr, pci_addr + req_size - 1, slot, win); +#endif + goto done; + } + + switch (space) { + /* + * Accesses to device decode + * areas that do a not fit + * within the DevIO(x) space are + * modified to be accesses via + * the direct mapping areas. + * + * If necessary, drivers can + * explicitly ask for mappings + * into these address spaces, + * but this should never be needed. + */ + case PCIIO_SPACE_MEM: /* "mem space" */ + case PCIIO_SPACE_MEM32: /* "mem, use 32-bit-wide bus" */ + if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <= + BRIDGE_PCI_MEM32_LIMIT) + xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE; + break; + + case PCIIO_SPACE_MEM64: /* "mem, use 64-bit-wide bus" */ + if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <= + BRIDGE_PCI_MEM64_LIMIT) + xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE; + break; + + case PCIIO_SPACE_IO: /* "i/o space" */ + /* Bridge Hardware Bug WAR #482741: + * The 4G area that maps directly from + * XIO space to PCI I/O space is busted + * until Bridge Rev D. + */ + if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) && + ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <= + BRIDGE_PCI_IO_LIMIT)) + xio_addr = pci_addr + BRIDGE_PCI_IO_BASE; + break; + } + + /* Check that "Direct PIO" byteswapping matches, + * try to change it if it does not. + */ + if (xio_addr != XIO_NOWHERE) { + unsigned bst; /* nonzero to set bytestream */ + unsigned *bfp; /* addr of record of how swapper is set */ + unsigned swb; /* which control bit to mung */ + unsigned bfo; /* current swapper setting */ + unsigned bfn; /* desired swapper setting */ + + bfp = ((space == PCIIO_SPACE_IO) + ? (&pcibr_soft->bs_pio_end_io) + : (&pcibr_soft->bs_pio_end_mem)); + + bfo = *bfp; + + bst = flags & PCIIO_BYTE_STREAM; + + bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES; + + if (bfn == bfo) { /* we already match. */ + ; + } else if (bfo != 0) { /* we have a conflict. */ +#if DEBUG && PCI_DEBUG + printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n", + space, + bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "", + bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "", + bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "", + bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : ""); +#endif + xio_addr = XIO_NOWHERE; + } else { /* OK to make the change. */ + bridgereg_t octl, nctl; + + swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP; + octl = bridge->b_wid_control; + nctl = bst ? octl | swb : octl & ~swb; + + if (octl != nctl) /* make the change if any */ + bridge->b_wid_control = nctl; + + *bfp = bfn; /* record the assignment */ + +#if DEBUG && PCI_DEBUG + printk("pcibr_addr_pci_to_xio: swap for space %d set to%s%s\n", + space, + bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "", + bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : ""); +#endif + } + } + done: + pcibr_unlock(pcibr_soft, s); + return xio_addr; +} + +/*ARGSUSED6 */ +pcibr_piomap_t +pcibr_piomap_alloc(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + pciio_space_t space, + iopaddr_t pci_addr, + size_t req_size, + size_t req_size_max, + unsigned flags) +{ + pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); + pciio_info_t pciio_info = &pcibr_info->f_c; + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + + pcibr_piomap_t *mapptr; + pcibr_piomap_t maplist; + pcibr_piomap_t pcibr_piomap; + iopaddr_t xio_addr; + xtalk_piomap_t xtalk_piomap; + unsigned s; + + /* Make sure that the req sizes are non-zero */ + if ((req_size < 1) || (req_size_max < 1)) + return NULL; + + /* + * Code to translate slot/space/addr + * into xio_addr is common between + * this routine and pcibr_piotrans_addr. + */ + xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags); + + if (xio_addr == XIO_NOWHERE) + return NULL; + + /* Check the piomap list to see if there is already an allocated + * piomap entry but not in use. If so use that one. Otherwise + * allocate a new piomap entry and add it to the piomap list + */ + mapptr = &(pcibr_info->f_piomap); + + s = pcibr_lock(pcibr_soft); + for (pcibr_piomap = *mapptr; + pcibr_piomap != NULL; + pcibr_piomap = pcibr_piomap->bp_next) { + if (pcibr_piomap->bp_mapsz == 0) + break; + } + + if (pcibr_piomap) + mapptr = NULL; + else { + pcibr_unlock(pcibr_soft, s); + NEW(pcibr_piomap); + } + + pcibr_piomap->bp_dev = pconn_vhdl; + pcibr_piomap->bp_slot = pciio_slot; + pcibr_piomap->bp_flags = flags; + pcibr_piomap->bp_space = space; + pcibr_piomap->bp_pciaddr = pci_addr; + pcibr_piomap->bp_mapsz = req_size; + pcibr_piomap->bp_soft = pcibr_soft; + pcibr_piomap->bp_toc[0] = 0; + + if (mapptr) { + s = pcibr_lock(pcibr_soft); + maplist = *mapptr; + pcibr_piomap->bp_next = maplist; + *mapptr = pcibr_piomap; + } + pcibr_unlock(pcibr_soft, s); + + + if (pcibr_piomap) { + xtalk_piomap = + xtalk_piomap_alloc(xconn_vhdl, 0, + xio_addr, + req_size, req_size_max, + flags & PIOMAP_FLAGS); + if (xtalk_piomap) { + pcibr_piomap->bp_xtalk_addr = xio_addr; + pcibr_piomap->bp_xtalk_pio = xtalk_piomap; + } else { + pcibr_piomap->bp_mapsz = 0; + pcibr_piomap = 0; + } + } + return pcibr_piomap; +} + +/*ARGSUSED */ +void +pcibr_piomap_free(pcibr_piomap_t pcibr_piomap) +{ + xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio); + pcibr_piomap->bp_xtalk_pio = 0; + pcibr_piomap->bp_mapsz = 0; +} + +/*ARGSUSED */ +caddr_t +pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap, + iopaddr_t pci_addr, + size_t req_size) +{ + return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio, + pcibr_piomap->bp_xtalk_addr + + pci_addr - pcibr_piomap->bp_pciaddr, + req_size); +} + +/*ARGSUSED */ +void +pcibr_piomap_done(pcibr_piomap_t pcibr_piomap) +{ + xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio); +} + +/*ARGSUSED */ +caddr_t +pcibr_piotrans_addr(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + pciio_space_t space, + iopaddr_t pci_addr, + size_t req_size, + unsigned flags) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + + iopaddr_t xio_addr; + + xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags); + + if (xio_addr == XIO_NOWHERE) + return NULL; + + return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS); +} + +/* + * PIO Space allocation and management. + * Allocate and Manage the PCI PIO space (mem and io space) + * This routine is pretty simplistic at this time, and + * does pretty trivial management of allocation and freeing.. + * The current scheme is prone for fragmentation.. + * Change the scheme to use bitmaps. + */ + +/*ARGSUSED */ +iopaddr_t +pcibr_piospace_alloc(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + pciio_space_t space, + size_t req_size, + size_t alignment) +{ + pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); + pciio_info_t pciio_info = &pcibr_info->f_c; + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + + pciio_piospace_t piosp; + int s; + + iopaddr_t *pciaddr, *pcilast; + iopaddr_t start_addr; + size_t align_mask; + + /* + * Check for proper alignment + */ + ASSERT(alignment >= NBPP); + ASSERT((alignment & (alignment - 1)) == 0); + + align_mask = alignment - 1; + s = pcibr_lock(pcibr_soft); + + /* + * First look if a previously allocated chunk exists. + */ + if ((piosp = pcibr_info->f_piospace) != (pciio_piospace_t)0) { + /* + * Look through the list for a right sized free chunk. + */ + do { + if (piosp->free && + (piosp->space == space) && + (piosp->count >= req_size) && + !(piosp->start & align_mask)) { + piosp->free = 0; + pcibr_unlock(pcibr_soft, s); + return piosp->start; + } + piosp = piosp->next; + } while (piosp); + } + ASSERT(!piosp); + + switch (space) { + case PCIIO_SPACE_IO: + pciaddr = &pcibr_soft->bs_spinfo.pci_io_base; + pcilast = &pcibr_soft->bs_spinfo.pci_io_last; + break; + case PCIIO_SPACE_MEM: + case PCIIO_SPACE_MEM32: + pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base; + pcilast = &pcibr_soft->bs_spinfo.pci_mem_last; + break; + default: + ASSERT(0); + pcibr_unlock(pcibr_soft, s); + return 0; + } + + start_addr = *pciaddr; + + /* + * Align start_addr. + */ + if (start_addr & align_mask) + start_addr = (start_addr + align_mask) & ~align_mask; + + if ((start_addr + req_size) > *pcilast) { + /* + * If too big a request, reject it. + */ + pcibr_unlock(pcibr_soft, s); + return 0; + } + *pciaddr = (start_addr + req_size); + + NEW(piosp); + piosp->free = 0; + piosp->space = space; + piosp->start = start_addr; + piosp->count = req_size; + piosp->next = pcibr_info->f_piospace; + pcibr_info->f_piospace = piosp; + + pcibr_unlock(pcibr_soft, s); + return start_addr; +} + +/*ARGSUSED */ +void +pcibr_piospace_free(devfs_handle_t pconn_vhdl, + pciio_space_t space, + iopaddr_t pciaddr, + size_t req_size) +{ + pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; + + pciio_piospace_t piosp; + int s; + char name[1024]; + + /* + * Look through the bridge data structures for the pciio_piospace_t + * structure corresponding to 'pciaddr' + */ + s = pcibr_lock(pcibr_soft); + piosp = pcibr_info->f_piospace; + while (piosp) { + /* + * Piospace free can only be for the complete + * chunk and not parts of it.. + */ + if (piosp->start == pciaddr) { + if (piosp->count == req_size) + break; + /* + * Improper size passed for freeing.. + * Print a message and break; + */ + hwgraph_vertex_name_get(pconn_vhdl, name, 1024); + PRINT_WARNING("pcibr_piospace_free: error"); + PRINT_WARNING("Device %s freeing size (0x%lx) different than allocated (0x%lx)", + name, req_size, piosp->count); + PRINT_WARNING("Freeing 0x%lx instead", piosp->count); + break; + } + piosp = piosp->next; + } + + if (!piosp) { + PRINT_WARNING( + "pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n", + pciaddr, req_size); + pcibr_unlock(pcibr_soft, s); + return; + } + piosp->free = 1; + pcibr_unlock(pcibr_soft, s); + return; +} + +/* ===================================================================== + * DMA MANAGEMENT + * + * The Bridge ASIC provides three methods of doing + * DMA: via a "direct map" register available in + * 32-bit PCI space (which selects a contiguous 2G + * address space on some other widget), via + * "direct" addressing via 64-bit PCI space (all + * destination information comes from the PCI + * address, including transfer attributes), and via + * a "mapped" region that allows a bunch of + * different small mappings to be established with + * the PMU. + * + * For efficiency, we most prefer to use the 32-bit + * direct mapping facility, since it requires no + * resource allocations. The advantage of using the + * PMU over the 64-bit direct is that single-cycle + * PCI addressing can be used; the advantage of + * using 64-bit direct over PMU addressing is that + * we do not have to allocate entries in the PMU. + */ + +/* + * Convert PCI-generic software flags and Bridge-specific software flags + * into Bridge-specific Direct Map attribute bits. + */ +LOCAL iopaddr_t +pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft) +{ + iopaddr_t attributes = 0; + + /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */ +#ifdef IRIX + ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64)); +#endif + + /* Generic macro flags + */ + if (flags & PCIIO_DMA_DATA) { /* standard data channel */ + attributes &= ~PCI64_ATTR_BAR; /* no barrier bit */ + attributes |= PCI64_ATTR_PREF; /* prefetch on */ + } + if (flags & PCIIO_DMA_CMD) { /* standard command channel */ + attributes |= PCI64_ATTR_BAR; /* barrier bit on */ + attributes &= ~PCI64_ATTR_PREF; /* disable prefetch */ + } + /* Generic detail flags + */ + if (flags & PCIIO_PREFETCH) + attributes |= PCI64_ATTR_PREF; + if (flags & PCIIO_NOPREFETCH) + attributes &= ~PCI64_ATTR_PREF; + + /* the swap bit is in the address attributes for xbridge */ + if (pcibr_soft->bs_xbridge) { + if (flags & PCIIO_BYTE_STREAM) + attributes |= PCI64_ATTR_SWAP; + if (flags & PCIIO_WORD_VALUES) + attributes &= ~PCI64_ATTR_SWAP; + } + + /* Provider-specific flags + */ + if (flags & PCIBR_BARRIER) + attributes |= PCI64_ATTR_BAR; + if (flags & PCIBR_NOBARRIER) + attributes &= ~PCI64_ATTR_BAR; + + if (flags & PCIBR_PREFETCH) + attributes |= PCI64_ATTR_PREF; + if (flags & PCIBR_NOPREFETCH) + attributes &= ~PCI64_ATTR_PREF; + + if (flags & PCIBR_PRECISE) + attributes |= PCI64_ATTR_PREC; + if (flags & PCIBR_NOPRECISE) + attributes &= ~PCI64_ATTR_PREC; + + if (flags & PCIBR_VCHAN1) + attributes |= PCI64_ATTR_VIRTUAL; + if (flags & PCIBR_VCHAN0) + attributes &= ~PCI64_ATTR_VIRTUAL; + + return (attributes); +} + +/* + * Convert PCI-generic software flags and Bridge-specific software flags + * into Bridge-specific Address Translation Entry attribute bits. + */ +LOCAL bridge_ate_t +pcibr_flags_to_ate(unsigned flags) +{ + bridge_ate_t attributes; + + /* default if nothing specified: + * NOBARRIER + * NOPREFETCH + * NOPRECISE + * COHERENT + * Plus the valid bit + */ + attributes = ATE_CO | ATE_V; + + /* Generic macro flags + */ + if (flags & PCIIO_DMA_DATA) { /* standard data channel */ + attributes &= ~ATE_BAR; /* no barrier */ + attributes |= ATE_PREF; /* prefetch on */ + } + if (flags & PCIIO_DMA_CMD) { /* standard command channel */ + attributes |= ATE_BAR; /* barrier bit on */ + attributes &= ~ATE_PREF; /* disable prefetch */ + } + /* Generic detail flags + */ + if (flags & PCIIO_PREFETCH) + attributes |= ATE_PREF; + if (flags & PCIIO_NOPREFETCH) + attributes &= ~ATE_PREF; + + /* Provider-specific flags + */ + if (flags & PCIBR_BARRIER) + attributes |= ATE_BAR; + if (flags & PCIBR_NOBARRIER) + attributes &= ~ATE_BAR; + + if (flags & PCIBR_PREFETCH) + attributes |= ATE_PREF; + if (flags & PCIBR_NOPREFETCH) + attributes &= ~ATE_PREF; + + if (flags & PCIBR_PRECISE) + attributes |= ATE_PREC; + if (flags & PCIBR_NOPRECISE) + attributes &= ~ATE_PREC; + + return (attributes); +} + +/*ARGSUSED */ +pcibr_dmamap_t +pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + size_t req_size_max, + unsigned flags) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + pciio_slot_t slot; + xwidgetnum_t xio_port; + + xtalk_dmamap_t xtalk_dmamap; + pcibr_dmamap_t pcibr_dmamap; + int ate_count; + int ate_index; + + /* merge in forced flags */ + flags |= pcibr_soft->bs_dma_flags; + + NEWf(pcibr_dmamap, flags); + if (!pcibr_dmamap) + return 0; + + xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max, + flags & DMAMAP_FLAGS); + if (!xtalk_dmamap) { +#if PCIBR_ATE_DEBUG + printk("pcibr_attach: xtalk_dmamap_alloc failed\n"); +#endif + DEL(pcibr_dmamap); + return 0; + } + xio_port = pcibr_soft->bs_mxid; + slot = pciio_info_slot_get(pciio_info); + + pcibr_dmamap->bd_dev = pconn_vhdl; + pcibr_dmamap->bd_slot = slot; + pcibr_dmamap->bd_soft = pcibr_soft; + pcibr_dmamap->bd_xtalk = xtalk_dmamap; + pcibr_dmamap->bd_max_size = req_size_max; + pcibr_dmamap->bd_xio_port = xio_port; + + if (flags & PCIIO_DMA_A64) { + if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) { + iopaddr_t pci_addr; + int have_rrbs; + int min_rrbs; + + /* Device is capable of A64 operations, + * and the attributes of the DMA are + * consistant with any previous DMA + * mappings using shared resources. + */ + + pci_addr = pcibr_flags_to_d64(flags, pcibr_soft); + + pcibr_dmamap->bd_flags = flags; + pcibr_dmamap->bd_xio_addr = 0; + pcibr_dmamap->bd_pci_addr = pci_addr; + + /* Make sure we have an RRB (or two). + */ + if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) { + if (flags & PCIBR_VCHAN1) + slot += PCIBR_RRB_SLOT_VIRTUAL; + have_rrbs = pcibr_soft->bs_rrb_valid[slot]; + if (have_rrbs < 2) { + if (pci_addr & PCI64_ATTR_PREF) + min_rrbs = 2; + else + min_rrbs = 1; + if (have_rrbs < min_rrbs) + do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs); + } + } +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: using direct64\n"); +#endif + return pcibr_dmamap; + } +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: unable to use direct64\n"); +#endif + flags &= ~PCIIO_DMA_A64; + } + if (flags & PCIIO_FIXED) { + /* warning: mappings may fail later, + * if direct32 can't get to the address. + */ + if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) { + /* User desires DIRECT A32 operations, + * and the attributes of the DMA are + * consistant with any previous DMA + * mappings using shared resources. + * Mapping calls may fail if target + * is outside the direct32 range. + */ +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: using direct32\n"); +#endif + pcibr_dmamap->bd_flags = flags; + pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase; + pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE; + return pcibr_dmamap; + } +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: unable to use direct32\n"); +#endif + /* If the user demands FIXED and we can't + * give it to him, fail. + */ + xtalk_dmamap_free(xtalk_dmamap); + DEL(pcibr_dmamap); + return 0; + } + /* + * Allocate Address Translation Entries from the mapping RAM. + * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified, + * the maximum number of ATEs is based on the worst-case + * scenario, where the requested target is in the + * last byte of an ATE; thus, mapping IOPGSIZE+2 + * does end up requiring three ATEs. + */ + if (!(flags & PCIBR_NO_ATE_ROUNDUP)) { + ate_count = IOPG((IOPGSIZE - 1) /* worst case start offset */ + +req_size_max /* max mapping bytes */ + - 1) + 1; /* round UP */ + } else { /* assume requested target is page aligned */ + ate_count = IOPG(req_size_max /* max mapping bytes */ + - 1) + 1; /* round UP */ + } + + ate_index = pcibr_ate_alloc(pcibr_soft, ate_count); + + if (ate_index != -1) { + if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) { + bridge_ate_t ate_proto; + int have_rrbs; + int min_rrbs; + +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: using PMU\n"); +#endif + + ate_proto = pcibr_flags_to_ate(flags); + + pcibr_dmamap->bd_flags = flags; + pcibr_dmamap->bd_pci_addr = + PCI32_MAPPED_BASE + IOPGSIZE * ate_index; + /* + * for xbridge the byte-swap bit == bit 29 of pci address + */ + if (pcibr_soft->bs_xbridge) { + if (flags & PCIIO_BYTE_STREAM) + ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr); + /* + * If swap was set in bss_device in pcibr_endian_set() + * we need to change the address bit. + */ + if (pcibr_soft->bs_slot[slot].bss_device & + BRIDGE_DEV_SWAP_PMU) + ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr); + if (flags & PCIIO_WORD_VALUES) + ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr); + } + pcibr_dmamap->bd_xio_addr = 0; + pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index); + pcibr_dmamap->bd_ate_index = ate_index; + pcibr_dmamap->bd_ate_count = ate_count; + pcibr_dmamap->bd_ate_proto = ate_proto; + + /* Make sure we have an RRB (or two). + */ + if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) { + have_rrbs = pcibr_soft->bs_rrb_valid[slot]; + if (have_rrbs < 2) { + if (ate_proto & ATE_PREF) + min_rrbs = 2; + else + min_rrbs = 1; + if (have_rrbs < min_rrbs) + do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs); + } + } + if (ate_index >= pcibr_soft->bs_int_ate_size && + !pcibr_soft->bs_xbridge) { + bridge_t *bridge = pcibr_soft->bs_base; + volatile unsigned *cmd_regp; + unsigned cmd_reg; + unsigned s; + + pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM; + + s = pcibr_lock(pcibr_soft); + cmd_regp = &(bridge-> + b_type0_cfg_dev[slot]. + l[PCI_CFG_COMMAND / 4]); + cmd_reg = *cmd_regp; + pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp; + pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg; + pcibr_unlock(pcibr_soft, s); + } + return pcibr_dmamap; + } +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: unable to use PMU\n"); +#endif + pcibr_ate_free(pcibr_soft, ate_index, ate_count); + } + /* total failure: sorry, you just can't + * get from here to there that way. + */ +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_alloc: complete failure.\n"); +#endif + xtalk_dmamap_free(xtalk_dmamap); + DEL(pcibr_dmamap); + return 0; +} + +/*ARGSUSED */ +void +pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap) +{ + pcibr_soft_t pcibr_soft = pcibr_dmamap->bd_soft; + pciio_slot_t slot = pcibr_dmamap->bd_slot; + +#ifdef IRIX + unsigned flags = pcibr_dmamap->bd_flags; +#endif + + /* Make sure that bss_ext_ates_active + * is properly kept up to date. + */ +#ifdef IRIX + if (PCIBR_DMAMAP_BUSY & flags) + if (PCIBR_DMAMAP_SSRAM & flags) + atomicAddInt(&(pcibr_soft-> + bs_slot[slot]. + bss_ext_ates_active), -1); +#endif + + xtalk_dmamap_free(pcibr_dmamap->bd_xtalk); + + if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) { + pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS); + } + if (pcibr_dmamap->bd_ate_count) { + pcibr_ate_free(pcibr_dmamap->bd_soft, + pcibr_dmamap->bd_ate_index, + pcibr_dmamap->bd_ate_count); + pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS); + } + DEL(pcibr_dmamap); +} + +/* + * Setup an Address Translation Entry as specified. Use either the Bridge + * internal maps or the external map RAM, as appropriate. + */ +LOCAL bridge_ate_p +pcibr_ate_addr(pcibr_soft_t pcibr_soft, + int ate_index) +{ + bridge_t *bridge = pcibr_soft->bs_base; + + return (ate_index < pcibr_soft->bs_int_ate_size) + ? &(bridge->b_int_ate_ram[ate_index].wr) + : &(bridge->b_ext_ate_ram[ate_index]); +} + +/* + * pcibr_addr_xio_to_pci: given a PIO range, hand + * back the corresponding base PCI MEM address; + * this is used to short-circuit DMA requests that + * loop back onto this PCI bus. + */ +LOCAL iopaddr_t +pcibr_addr_xio_to_pci(pcibr_soft_t soft, + iopaddr_t xio_addr, + size_t req_size) +{ + iopaddr_t xio_lim = xio_addr + req_size - 1; + iopaddr_t pci_addr; + pciio_slot_t slot; + + if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) && + (xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) { + pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE; + return pci_addr; + } + if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) && + (xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) { + pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE; + return pci_addr; + } + for (slot = 0; slot < 8; ++slot) + if ((xio_addr >= BRIDGE_DEVIO(slot)) && + (xio_lim < BRIDGE_DEVIO(slot + 1))) { + bridgereg_t dev; + + dev = soft->bs_slot[slot].bss_device; + pci_addr = dev & BRIDGE_DEV_OFF_MASK; + pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT; + pci_addr += xio_addr - BRIDGE_DEVIO(slot); + return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE; + } + return 0; +} + +/* We are starting to get more complexity + * surrounding writing ATEs, so pull + * the writing code into this new function. + * XXX mail ranga@engr for IP27 prom! + */ + +#if PCIBR_FREEZE_TIME +#define ATE_FREEZE() s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs) +#else +#define ATE_FREEZE() s = ate_freeze(pcibr_dmamap, cmd_regs) +#endif + +LOCAL unsigned +ate_freeze(pcibr_dmamap_t pcibr_dmamap, +#if PCIBR_FREEZE_TIME + unsigned *freeze_time_ptr, +#endif + unsigned *cmd_regs) +{ + pcibr_soft_t pcibr_soft = pcibr_dmamap->bd_soft; +#ifdef IRIX + int dma_slot = pcibr_dmamap->bd_slot; +#endif + int ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM; + int slot; + + unsigned s; + unsigned cmd_reg; + volatile unsigned *cmd_lwa; + unsigned cmd_lwd; + + if (!ext_ates) + return 0; + + /* Bridge Hardware Bug WAR #484930: + * Bridge can't handle updating External ATEs + * while DMA is occuring that uses External ATEs, + * even if the particular ATEs involved are disjoint. + */ + + /* need to prevent anyone else from + * unfreezing the grant while we + * are working; also need to prevent + * this thread from being interrupted + * to keep PCI grant freeze time + * at an absolute minimum. + */ + s = pcibr_lock(pcibr_soft); + +#ifdef IRIX + /* just in case pcibr_dmamap_done was not called */ + if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) { + pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY; + if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM) + atomicAddInt(&(pcibr_soft-> + bs_slot[dma_slot]. + bss_ext_ates_active), -1); + xtalk_dmamap_done(pcibr_dmamap->bd_xtalk); + } +#endif +#if PCIBR_FREEZE_TIME + *freeze_time_ptr = get_timestamp(); +#endif + + cmd_lwa = 0; + for (slot = 0; slot < 8; ++slot) + if (pcibr_soft-> + bs_slot[slot]. + bss_ext_ates_active) { + + cmd_reg = pcibr_soft-> + bs_slot[slot]. + bss_cmd_shadow; + if (cmd_reg & PCI_CMD_BUS_MASTER) { + cmd_lwa = pcibr_soft-> + bs_slot[slot]. + bss_cmd_pointer; + cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER; + cmd_lwa[0] = cmd_lwd; + } + cmd_regs[slot] = cmd_reg; + } else + cmd_regs[slot] = 0; + + if (cmd_lwa) { + bridge_t *bridge = pcibr_soft->bs_base; + + /* Read the last master bit that has been cleared. This PIO read + * on the PCI bus is to ensure the completion of any DMAs that + * are due to bus requests issued by PCI devices before the + * clearing of master bits. + */ + cmd_lwa[0]; + + /* Flush all the write buffers in the bridge */ + for (slot = 0; slot < 8; ++slot) + if (pcibr_soft-> + bs_slot[slot]. + bss_ext_ates_active) { + /* Flush the write buffer associated with this + * PCI device which might be using dma map RAM. + */ + bridge->b_wr_req_buf[slot].reg; + } + } + return s; +} + +#define ATE_WRITE() ate_write(ate_ptr, ate_count, ate) + +LOCAL void +ate_write(bridge_ate_p ate_ptr, + int ate_count, + bridge_ate_t ate) +{ + while (ate_count-- > 0) { + *ate_ptr++ = ate; + ate += IOPGSIZE; + } +} + + +#if PCIBR_FREEZE_TIME +#define ATE_THAW() ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s) +#else +#define ATE_THAW() ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s) +#endif + +LOCAL void +ate_thaw(pcibr_dmamap_t pcibr_dmamap, + int ate_index, +#if PCIBR_FREEZE_TIME + bridge_ate_t ate, + int ate_total, + unsigned freeze_time_start, +#endif + unsigned *cmd_regs, + unsigned s) +{ + pcibr_soft_t pcibr_soft = pcibr_dmamap->bd_soft; +#ifdef IRIX + int dma_slot = pcibr_dmamap->bd_slot; +#endif + int slot; + bridge_t *bridge = pcibr_soft->bs_base; + int ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM; + + unsigned cmd_reg; + +#if PCIBR_FREEZE_TIME + unsigned freeze_time; + static unsigned max_freeze_time = 0; + static unsigned max_ate_total; +#endif + + if (!ext_ates) + return; + + /* restore cmd regs */ + for (slot = 0; slot < 8; ++slot) + if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER) + bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg; + + pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY; +#ifdef IRIX + atomicAddInt(&(pcibr_soft-> + bs_slot[dma_slot]. + bss_ext_ates_active), 1); +#endif + +#if PCIBR_FREEZE_TIME + freeze_time = get_timestamp() - freeze_time_start; + + if ((max_freeze_time < freeze_time) || + (max_ate_total < ate_total)) { + if (max_freeze_time < freeze_time) + max_freeze_time = freeze_time; + if (max_ate_total < ate_total) + max_ate_total = ate_total; + pcibr_unlock(pcibr_soft, s); + printk("%s: pci freeze time %d usec for %d ATEs\n" + "\tfirst ate: %R\n", + pcibr_soft->bs_name, + freeze_time * 1000 / 1250, + ate_total, + ate, ate_bits); + } else +#endif + pcibr_unlock(pcibr_soft, s); +} + +/*ARGSUSED */ +iopaddr_t +pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap, + paddr_t paddr, + size_t req_size) +{ + pcibr_soft_t pcibr_soft; + iopaddr_t xio_addr; + xwidgetnum_t xio_port; + iopaddr_t pci_addr; + unsigned flags; + + ASSERT(pcibr_dmamap != NULL); + ASSERT(req_size > 0); + ASSERT(req_size <= pcibr_dmamap->bd_max_size); + + pcibr_soft = pcibr_dmamap->bd_soft; + + flags = pcibr_dmamap->bd_flags; + + xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size); + if (XIO_PACKED(xio_addr)) { + xio_port = XIO_PORT(xio_addr); + xio_addr = XIO_ADDR(xio_addr); + } else + xio_port = pcibr_dmamap->bd_xio_port; + + /* If this DMA is to an addres that + * refers back to this Bridge chip, + * reduce it back to the correct + * PCI MEM address. + */ + if (xio_port == pcibr_soft->bs_xid) { + pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size); + } else if (flags & PCIIO_DMA_A64) { + /* A64 DMA: + * always use 64-bit direct mapping, + * which always works. + * Device(x) was set up during + * dmamap allocation. + */ + + /* attributes are already bundled up into bd_pci_addr. + */ + pci_addr = pcibr_dmamap->bd_pci_addr + | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT) + | xio_addr; + + /* Bridge Hardware WAR #482836: + * If the transfer is not cache aligned + * and the Bridge Rev is <= B, force + * prefetch to be off. + */ + if (flags & PCIBR_NOPREFETCH) + pci_addr &= ~PCI64_ATTR_PREF; + +#if DEBUG && PCIBR_DMA_DEBUG + printk("pcibr_dmamap_addr (direct64):\n" + "\twanted paddr [0x%x..0x%x]\n" + "\tXIO port 0x%x offset 0x%x\n" + "\treturning PCI 0x%x\n", + paddr, paddr + req_size - 1, + xio_port, xio_addr, pci_addr); +#endif + } else if (flags & PCIIO_FIXED) { + /* A32 direct DMA: + * always use 32-bit direct mapping, + * which may fail. + * Device(x) was set up during + * dmamap allocation. + */ + + if (xio_port != pcibr_soft->bs_dir_xport) + pci_addr = 0; /* wrong DIDN */ + else if (xio_addr < pcibr_dmamap->bd_xio_addr) + pci_addr = 0; /* out of range */ + else if ((xio_addr + req_size) > + (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE)) + pci_addr = 0; /* out of range */ + else + pci_addr = pcibr_dmamap->bd_pci_addr + + xio_addr - pcibr_dmamap->bd_xio_addr; + +#if DEBUG && PCIBR_DMA_DEBUG + printk("pcibr_dmamap_addr (direct32):\n" + "\twanted paddr [0x%x..0x%x]\n" + "\tXIO port 0x%x offset 0x%x\n" + "\treturning PCI 0x%x\n", + paddr, paddr + req_size - 1, + xio_port, xio_addr, pci_addr); +#endif + } else { + bridge_t *bridge = pcibr_soft->bs_base; + iopaddr_t offset = IOPGOFF(xio_addr); + bridge_ate_t ate_proto = pcibr_dmamap->bd_ate_proto; + int ate_count = IOPG(offset + req_size - 1) + 1; + + int ate_index = pcibr_dmamap->bd_ate_index; + unsigned cmd_regs[8]; + unsigned s; + +#if PCIBR_FREEZE_TIME + int ate_total = ate_count; + unsigned freeze_time; +#endif + +#if PCIBR_ATE_DEBUG + bridge_ate_t ate_cmp; + bridge_ate_p ate_cptr; + unsigned ate_lo, ate_hi; + int ate_bad = 0; + int ate_rbc = 0; +#endif + bridge_ate_p ate_ptr = pcibr_dmamap->bd_ate_ptr; + bridge_ate_t ate; + + /* Bridge Hardware WAR #482836: + * If the transfer is not cache aligned + * and the Bridge Rev is <= B, force + * prefetch to be off. + */ + if (flags & PCIBR_NOPREFETCH) + ate_proto &= ~ATE_PREF; + + ate = ate_proto + | (xio_port << ATE_TIDSHIFT) + | (xio_addr - offset); + + pci_addr = pcibr_dmamap->bd_pci_addr + offset; + + /* Fill in our mapping registers + * with the appropriate xtalk data, + * and hand back the PCI address. + */ + + ASSERT(ate_count > 0); + if (ate_count <= pcibr_dmamap->bd_ate_count) { + ATE_FREEZE(); + ATE_WRITE(); + ATE_THAW(); + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + } else { + /* The number of ATE's required is greater than the number + * allocated for this map. One way this can happen is if + * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP + * flag, and then when that map is used (right now), the + * target address tells us we really did need to roundup. + * The other possibility is that the map is just plain too + * small to handle the requested target area. + */ +#if PCIBR_ATE_DEBUG + PRINT_WARNING( "pcibr_dmamap_addr :\n" + "\twanted paddr [0x%x..0x%x]\n" + "\tate_count 0x%x bd_ate_count 0x%x\n" + "\tATE's required > number allocated\n", + paddr, paddr + req_size - 1, + ate_count, pcibr_dmamap->bd_ate_count); +#endif + pci_addr = 0; + } + + } + return pci_addr; +} + +/*ARGSUSED */ +alenlist_t +pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap, + alenlist_t palenlist, + unsigned flags) +{ + pcibr_soft_t pcibr_soft; +#ifdef IRIX + bridge_t *bridge; +#else + bridge_t *bridge=NULL; +#endif + + unsigned al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; + int inplace = flags & PCIIO_INPLACE; + + alenlist_t pciio_alenlist = 0; + alenlist_t xtalk_alenlist; + size_t length; + iopaddr_t offset; + unsigned direct64; +#ifdef IRIX + int ate_index; + int ate_count; + int ate_total = 0; + bridge_ate_p ate_ptr; + bridge_ate_t ate_proto; +#else + int ate_index = 0; + int ate_count = 0; + int ate_total = 0; + bridge_ate_p ate_ptr = (bridge_ate_p)0; + bridge_ate_t ate_proto = (bridge_ate_t)0; +#endif + bridge_ate_t ate_prev; + bridge_ate_t ate; + alenaddr_t xio_addr; + xwidgetnum_t xio_port; + iopaddr_t pci_addr; + alenaddr_t new_addr; + + unsigned cmd_regs[8]; + unsigned s = 0; + +#if PCIBR_FREEZE_TIME + unsigned freeze_time; +#endif + int ate_freeze_done = 0; /* To pair ATE_THAW + * with an ATE_FREEZE + */ + + pcibr_soft = pcibr_dmamap->bd_soft; + + xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist, + flags & DMAMAP_FLAGS); + if (!xtalk_alenlist) + goto fail; + + alenlist_cursor_init(xtalk_alenlist, 0, NULL); + + if (inplace) { + pciio_alenlist = xtalk_alenlist; + } else { + pciio_alenlist = alenlist_create(al_flags); + if (!pciio_alenlist) + goto fail; + } + + direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64; + if (!direct64) { + bridge = pcibr_soft->bs_base; + ate_ptr = pcibr_dmamap->bd_ate_ptr; + ate_index = pcibr_dmamap->bd_ate_index; + ate_proto = pcibr_dmamap->bd_ate_proto; + ATE_FREEZE(); + ate_freeze_done = 1; /* Remember that we need to do an ATE_THAW */ + } + pci_addr = pcibr_dmamap->bd_pci_addr; + + ate_prev = 0; /* matches no valid ATEs */ + while (ALENLIST_SUCCESS == + alenlist_get(xtalk_alenlist, NULL, 0, + &xio_addr, &length, al_flags)) { + if (XIO_PACKED(xio_addr)) { + xio_port = XIO_PORT(xio_addr); + xio_addr = XIO_ADDR(xio_addr); + } else + xio_port = pcibr_dmamap->bd_xio_port; + + if (xio_port == pcibr_soft->bs_xid) { + new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length); + if (new_addr == PCI_NOWHERE) + goto fail; + } else if (direct64) { + new_addr = pci_addr | xio_addr + | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); + + /* Bridge Hardware WAR #482836: + * If the transfer is not cache aligned + * and the Bridge Rev is <= B, force + * prefetch to be off. + */ + if (flags & PCIBR_NOPREFETCH) + new_addr &= ~PCI64_ATTR_PREF; + + } else { + /* calculate the ate value for + * the first address. If it + * matches the previous + * ATE written (ie. we had + * multiple blocks in the + * same IOPG), then back up + * and reuse that ATE. + * + * We are NOT going to + * aggressively try to + * reuse any other ATEs. + */ + offset = IOPGOFF(xio_addr); + ate = ate_proto + | (xio_port << ATE_TIDSHIFT) + | (xio_addr - offset); + if (ate == ate_prev) { +#if PCIBR_ATE_DEBUG + printk("pcibr_dmamap_list: ATE share\n"); +#endif + ate_ptr--; + ate_index--; + pci_addr -= IOPGSIZE; + } + new_addr = pci_addr + offset; + + /* Fill in the hardware ATEs + * that contain this block. + */ + ate_count = IOPG(offset + length - 1) + 1; + ate_total += ate_count; + + /* Ensure that this map contains enough ATE's */ + if (ate_total > pcibr_dmamap->bd_ate_count) { +#if PCIBR_ATE_DEBUG + PRINT_WARNING( "pcibr_dmamap_list :\n" + "\twanted xio_addr [0x%x..0x%x]\n" + "\tate_total 0x%x bd_ate_count 0x%x\n" + "\tATE's required > number allocated\n", + xio_addr, xio_addr + length - 1, + ate_total, pcibr_dmamap->bd_ate_count); +#endif + goto fail; + } + + ATE_WRITE(); + + ate_index += ate_count; + ate_ptr += ate_count; + + ate_count <<= IOPFNSHIFT; + ate += ate_count; + pci_addr += ate_count; + } + + /* write the PCI DMA address + * out to the scatter-gather list. + */ + if (inplace) { + if (ALENLIST_SUCCESS != + alenlist_replace(pciio_alenlist, NULL, + &new_addr, &length, al_flags)) + goto fail; + } else { + if (ALENLIST_SUCCESS != + alenlist_append(pciio_alenlist, + new_addr, length, al_flags)) + goto fail; + } + } + if (!inplace) + alenlist_done(xtalk_alenlist); + + /* Reset the internal cursor of the alenlist to be returned back + * to the caller. + */ + alenlist_cursor_init(pciio_alenlist, 0, NULL); + + + /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the + * changes that ATE_FREEZE has done to implement the external SSRAM + * bug workaround. + */ + if (ate_freeze_done) { + ATE_THAW(); + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + } + return pciio_alenlist; + + fail: + /* There are various points of failure after doing an ATE_FREEZE + * We need to do an ATE_THAW. Otherwise the ATEs are locked forever. + * The decision to do an ATE_THAW needs to be based on whether a + * an ATE_FREEZE was done before. + */ + if (ate_freeze_done) { + ATE_THAW(); + bridge->b_wid_tflush; + } + if (pciio_alenlist && !inplace) + alenlist_destroy(pciio_alenlist); + return 0; +} + +/*ARGSUSED */ +void +pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap) +{ + /* + * We could go through and invalidate ATEs here; + * for performance reasons, we don't. + * We also don't enforce the strict alternation + * between _addr/_list and _done, but Hub does. + */ + +#ifdef IRIX + if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) { + pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY; + + if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM) + atomicAddInt(&(pcibr_dmamap->bd_soft-> + bs_slot[pcibr_dmamap->bd_slot]. + bss_ext_ates_active), -1); + } +#endif + + xtalk_dmamap_done(pcibr_dmamap->bd_xtalk); +} + + +/* + * For each bridge, the DIR_OFF value in the Direct Mapping Register + * determines the PCI to Crosstalk memory mapping to be used for all + * 32-bit Direct Mapping memory accesses. This mapping can be to any + * node in the system. This function will return that compact node id. + */ + +/*ARGSUSED */ +cnodeid_t +pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl) +{ + + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + + return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase))); +} + +/*ARGSUSED */ +iopaddr_t +pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + paddr_t paddr, + size_t req_size, + unsigned flags) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; + + xwidgetnum_t xio_port; + iopaddr_t xio_addr; + iopaddr_t pci_addr; + + int have_rrbs; + int min_rrbs; + + /* merge in forced flags */ + flags |= pcibr_soft->bs_dma_flags; + + xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size, + flags & DMAMAP_FLAGS); + + if (!xio_addr) { +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + return 0; + } + /* + * find which XIO port this goes to. + */ + if (XIO_PACKED(xio_addr)) { + if (xio_addr == XIO_NOWHERE) { +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + return 0; + } + xio_port = XIO_PORT(xio_addr); + xio_addr = XIO_ADDR(xio_addr); + + } else + xio_port = pcibr_soft->bs_mxid; + + /* + * If this DMA comes back to us, + * return the PCI MEM address on + * which it would land, or NULL + * if the target is something + * on bridge other than PCI MEM. + */ + if (xio_port == pcibr_soft->bs_xid) { + pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size); + return pci_addr; + } + /* If the caller can use A64, try to + * satisfy the request with the 64-bit + * direct map. This can fail if the + * configuration bits in Device(x) + * conflict with our flags. + */ + + if (flags & PCIIO_DMA_A64) { + pci_addr = slotp->bss_d64_base; + if (!(flags & PCIBR_VCHAN1)) + flags |= PCIBR_VCHAN0; + if ((pci_addr != PCIBR_D64_BASE_UNSET) && + (flags == slotp->bss_d64_flags)) { + + pci_addr |= xio_addr + | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); + +#if DEBUG && PCIBR_DMA_DEBUG +#if HWG_PERF_CHECK + if (xio_addr != 0x20000000) +#endif + printk("pcibr_dmatrans_addr: [reuse]\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tdirect 64bit address is 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr, pci_addr); +#endif + return (pci_addr); + } + if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) { + pci_addr = pcibr_flags_to_d64(flags, pcibr_soft); + slotp->bss_d64_flags = flags; + slotp->bss_d64_base = pci_addr; + pci_addr |= xio_addr + | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); + + /* Make sure we have an RRB (or two). + */ + if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) { + if (flags & PCIBR_VCHAN1) + pciio_slot += PCIBR_RRB_SLOT_VIRTUAL; + have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot]; + if (have_rrbs < 2) { + if (pci_addr & PCI64_ATTR_PREF) + min_rrbs = 2; + else + min_rrbs = 1; + if (have_rrbs < min_rrbs) + do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs); + } + } +#if PCIBR_DMA_DEBUG +#if HWG_PERF_CHECK + if (xio_addr != 0x20000000) +#endif + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tdirect 64bit address is 0x%x\n" + "\tnew flags: 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr, pci_addr, (uint64_t) flags); +#endif + return (pci_addr); + } + /* our flags conflict with Device(x). + */ + flags = flags + & ~PCIIO_DMA_A64 + & ~PCIBR_VCHAN0 + ; + +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tUnable to set Device(x) bits for Direct-64\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + } + /* Try to satisfy the request with the 32-bit direct + * map. This can fail if the configuration bits in + * Device(x) conflict with our flags, or if the + * target address is outside where DIR_OFF points. + */ + { + size_t map_size = 1ULL << 31; + iopaddr_t xio_base = pcibr_soft->bs_dir_xbase; + iopaddr_t offset = xio_addr - xio_base; + iopaddr_t endoff = req_size + offset; + + if ((req_size > map_size) || + (xio_addr < xio_base) || + (xio_port != pcibr_soft->bs_dir_xport) || + (endoff > map_size)) { +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\txio region outside direct32 target\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + } else { + pci_addr = slotp->bss_d32_base; + if ((pci_addr != PCIBR_D32_BASE_UNSET) && + (flags == slotp->bss_d32_flags)) { + + pci_addr |= offset; + +#if DEBUG && PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr: [reuse]\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tmapped via direct32 offset 0x%x\n" + "\twill DMA via pci addr 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr, offset, pci_addr); +#endif + return (pci_addr); + } + if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) { + + pci_addr = PCI32_DIRECT_BASE; + slotp->bss_d32_flags = flags; + slotp->bss_d32_base = pci_addr; + pci_addr |= offset; + + /* Make sure we have an RRB (or two). + */ + if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) { + have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot]; + if (have_rrbs < 2) { + if (slotp->bss_device & BRIDGE_DEV_PREF) + min_rrbs = 2; + else + min_rrbs = 1; + if (have_rrbs < min_rrbs) + do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs); + } + } +#if PCIBR_DMA_DEBUG +#if HWG_PERF_CHECK + if (xio_addr != 0x20000000) +#endif + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tmapped via direct32 offset 0x%x\n" + "\twill DMA via pci addr 0x%x\n" + "\tnew flags: 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr, offset, pci_addr, (uint64_t) flags); +#endif + return (pci_addr); + } + /* our flags conflict with Device(x). + */ +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tUnable to set Device(x) bits for Direct-32\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + } + } + +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n" + "\tno acceptable PCI address found or constructable\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + + return 0; +} + +/*ARGSUSED */ +alenlist_t +pcibr_dmatrans_list(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + alenlist_t palenlist, + unsigned flags) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_slot_t slotp = &pcibr_soft->bs_slot[pciio_slot]; + xwidgetnum_t xio_port; + + alenlist_t pciio_alenlist = 0; + alenlist_t xtalk_alenlist = 0; + + int inplace; + unsigned direct64; + unsigned al_flags; + + iopaddr_t xio_base; + alenaddr_t xio_addr; + size_t xio_size; + + size_t map_size; + iopaddr_t pci_base; + alenaddr_t pci_addr; + + unsigned relbits = 0; + + /* merge in forced flags */ + flags |= pcibr_soft->bs_dma_flags; + + inplace = flags & PCIIO_INPLACE; + direct64 = flags & PCIIO_DMA_A64; + al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0; + + if (direct64) { + map_size = 1ull << 48; + xio_base = 0; + pci_base = slotp->bss_d64_base; + if ((pci_base != PCIBR_D64_BASE_UNSET) && + (flags == slotp->bss_d64_flags)) { + /* reuse previous base info */ + } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) { + /* DMA configuration conflict */ + goto fail; + } else { + relbits = BRIDGE_DEV_D64_BITS; + pci_base = + pcibr_flags_to_d64(flags, pcibr_soft); + } + } else { + xio_base = pcibr_soft->bs_dir_xbase; + map_size = 1ull << 31; + pci_base = slotp->bss_d32_base; + if ((pci_base != PCIBR_D32_BASE_UNSET) && + (flags == slotp->bss_d32_flags)) { + /* reuse previous base info */ + } else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) { + /* DMA configuration conflict */ + goto fail; + } else { + relbits = BRIDGE_DEV_D32_BITS; + pci_base = PCI32_DIRECT_BASE; + } + } + + xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist, + flags & DMAMAP_FLAGS); + if (!xtalk_alenlist) + goto fail; + + alenlist_cursor_init(xtalk_alenlist, 0, NULL); + + if (inplace) { + pciio_alenlist = xtalk_alenlist; + } else { + pciio_alenlist = alenlist_create(al_flags); + if (!pciio_alenlist) + goto fail; + } + + while (ALENLIST_SUCCESS == + alenlist_get(xtalk_alenlist, NULL, 0, + &xio_addr, &xio_size, al_flags)) { + + /* + * find which XIO port this goes to. + */ + if (XIO_PACKED(xio_addr)) { + if (xio_addr == XIO_NOWHERE) { +#if PCIBR_DMA_DEBUG + printk("pcibr_dmatrans_addr:\n" + "\tpciio connection point %v\n" + "\txtalk connection point %v\n" + "\twanted paddr [0x%x..0x%x]\n" + "\txtalk_dmatrans_addr returned 0x%x\n", + pconn_vhdl, xconn_vhdl, + paddr, paddr + req_size - 1, + xio_addr); +#endif + return 0; + } + xio_port = XIO_PORT(xio_addr); + xio_addr = XIO_ADDR(xio_addr); + } else + xio_port = pcibr_soft->bs_mxid; + + /* + * If this DMA comes back to us, + * return the PCI MEM address on + * which it would land, or NULL + * if the target is something + * on bridge other than PCI MEM. + */ + if (xio_port == pcibr_soft->bs_xid) { + pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size); +#ifdef IRIX + if (pci_addr == NULL) +#else + if ( (pci_addr == (alenaddr_t)NULL) ) +#endif + goto fail; + } else if (direct64) { + ASSERT(xio_port != 0); + pci_addr = pci_base | xio_addr + | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT); + } else { + iopaddr_t offset = xio_addr - xio_base; + iopaddr_t endoff = xio_size + offset; + + if ((xio_size > map_size) || + (xio_addr < xio_base) || + (xio_port != pcibr_soft->bs_dir_xport) || + (endoff > map_size)) + goto fail; + + pci_addr = pci_base + (xio_addr - xio_base); + } + + /* write the PCI DMA address + * out to the scatter-gather list. + */ + if (inplace) { + if (ALENLIST_SUCCESS != + alenlist_replace(pciio_alenlist, NULL, + &pci_addr, &xio_size, al_flags)) + goto fail; + } else { + if (ALENLIST_SUCCESS != + alenlist_append(pciio_alenlist, + pci_addr, xio_size, al_flags)) + goto fail; + } + } + +#ifdef IRIX + if (relbits) +#else + if (relbits) { +#endif + if (direct64) { + slotp->bss_d64_flags = flags; + slotp->bss_d64_base = pci_base; + } else { + slotp->bss_d32_flags = flags; + slotp->bss_d32_base = pci_base; + } +#ifndef IRIX + } +#endif + if (!inplace) + alenlist_done(xtalk_alenlist); + + /* Reset the internal cursor of the alenlist to be returned back + * to the caller. + */ + alenlist_cursor_init(pciio_alenlist, 0, NULL); + return pciio_alenlist; + + fail: + if (relbits) + pcibr_release_device(pcibr_soft, pciio_slot, relbits); + if (pciio_alenlist && !inplace) + alenlist_destroy(pciio_alenlist); + return 0; +} + +void +pcibr_dmamap_drain(pcibr_dmamap_t map) +{ + xtalk_dmamap_drain(map->bd_xtalk); +} + +void +pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl, + paddr_t paddr, + size_t bytes) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + + xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes); +} + +void +pcibr_dmalist_drain(devfs_handle_t pconn_vhdl, + alenlist_t list) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + + xtalk_dmalist_drain(xconn_vhdl, list); +} + +/* + * Get the starting PCIbus address out of the given DMA map. + * This function is supposed to be used by a close friend of PCI bridge + * since it relies on the fact that the starting address of the map is fixed at + * the allocation time in the current implementation of PCI bridge. + */ +iopaddr_t +pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap) +{ + return (pcibr_dmamap->bd_pci_addr); +} + +/* ===================================================================== + * INTERRUPT MANAGEMENT + */ + +static unsigned +pcibr_intr_bits(pciio_info_t info, + pciio_intr_line_t lines) +{ + pciio_slot_t slot = pciio_info_slot_get(info); + unsigned bbits = 0; + + /* + * Currently favored mapping from PCI + * slot number and INTA/B/C/D to Bridge + * PCI Interrupt Bit Number: + * + * SLOT A B C D + * 0 0 4 0 4 + * 1 1 5 1 5 + * 2 2 6 2 6 + * 3 3 7 3 7 + * 4 4 0 4 0 + * 5 5 1 5 1 + * 6 6 2 6 2 + * 7 7 3 7 3 + */ + + if (slot < 8) { + if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C)) + bbits |= 1 << slot; + if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D)) + bbits |= 1 << (slot ^ 4); + } + return bbits; +} + +#ifdef IRIX +/* Wrapper for pcibr interrupt threads. */ +static void +pcibr_intrd(pcibr_intr_t intr) +{ + /* Called on each restart */ + ASSERT(cpuid() == intr->bi_mustruncpu); + +#ifdef ITHREAD_LATENCY + xthread_update_latstats(intr->bi_tinfo->thd_latstats); +#endif /* ITHREAD_LATENCY */ + + ASSERT(intr->bi_func != NULL); + intr->bi_func(intr->bi_arg); /* Invoke the interrupt handler */ + + ipsema(&intr->bi_tinfo.thd_isync); /* Sleep 'till next interrupt */ + /* NOTREACHED */ +} + + +static void +pcibr_intrd_start(pcibr_intr_t intr) +{ + ASSERT(intr->bi_mustruncpu >= 0); + setmustrun(intr->bi_mustruncpu); + + xthread_set_func(KT_TO_XT(curthreadp), (xt_func_t *)pcibr_intrd, (void *)intr); + atomicSetInt(&intr->bi_tinfo.thd_flags, THD_INIT); + ipsema(&intr->bi_tinfo.thd_isync); /* Comes out in pcibr_intrd */ + /* NOTREACHED */ +} + + +static void +pcibr_thread_setup(pcibr_intr_t intr, int bridge_levels, ilvl_t intr_swlevel) +{ + char thread_name[32]; + + sprintf(thread_name, "pcibr_intrd[0x%x]", bridge_levels); + + /* XXX need to adjust priority whenever an interrupt is connected */ + atomicSetInt(&intr->bi_tinfo.thd_flags, THD_ISTHREAD | THD_REG); + xthread_setup(thread_name, intr_swlevel, &intr->bi_tinfo, + (xt_func_t *)pcibr_intrd_start, + (void *)intr); +} +#endif /* IRIX */ + + + +/*ARGSUSED */ +pcibr_intr_t +pcibr_intr_alloc(devfs_handle_t pconn_vhdl, + device_desc_t dev_desc, + pciio_intr_line_t lines, + devfs_handle_t owner_dev) +{ + pcibr_info_t pcibr_info = pcibr_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pcibr_info->f_slot; + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + bridge_t *bridge = pcibr_soft->bs_base; + int is_threaded; + int thread_swlevel; + + xtalk_intr_t *xtalk_intr_p; + pcibr_intr_t *pcibr_intr_p; + pcibr_intr_list_t *intr_list_p; + pcibr_intr_wrap_t *intr_wrap_p; + + unsigned pcibr_int_bits; + unsigned pcibr_int_bit; + xtalk_intr_t xtalk_intr = (xtalk_intr_t)0; + hub_intr_t hub_intr; + pcibr_intr_t pcibr_intr; + pcibr_intr_list_t intr_entry; + pcibr_intr_list_t intr_list; + pcibr_intr_wrap_t intr_wrap; + bridgereg_t int_dev; + +#if DEBUG && INTR_DEBUG + printk("%v: pcibr_intr_alloc\n" + "%v:%s%s%s%s%s\n", + owner_dev, pconn_vhdl, + !(lines & 15) ? " No INTs?" : "", + lines & 1 ? " INTA" : "", + lines & 2 ? " INTB" : "", + lines & 4 ? " INTC" : "", + lines & 8 ? " INTD" : ""); +#endif + + NEW(pcibr_intr); + if (!pcibr_intr) + return NULL; + + if (dev_desc) { + is_threaded = !(device_desc_flags_get(dev_desc) & D_INTR_NOTHREAD); + if (is_threaded) + thread_swlevel = device_desc_intr_swlevel_get(dev_desc); + } else { + extern int default_intr_pri; + + is_threaded = 1; /* PCI interrupts are threaded, by default */ + thread_swlevel = default_intr_pri; + } + + pcibr_intr->bi_dev = pconn_vhdl; + pcibr_intr->bi_lines = lines; + pcibr_intr->bi_soft = pcibr_soft; + pcibr_intr->bi_ibits = 0; /* bits will be added below */ + pcibr_intr->bi_func = 0; /* unset until connect */ + pcibr_intr->bi_arg = 0; /* unset until connect */ + pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD; + pcibr_intr->bi_mustruncpu = CPU_NONE; + + pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines); + + + /* + * For each PCI interrupt line requested, figure + * out which Bridge PCI Interrupt Line it maps + * to, and make sure there are xtalk resources + * allocated for it. + */ +#if DEBUG && INTR_DEBUG + printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits); +#endif + for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) { + if (pcibr_int_bits & (1 << pcibr_int_bit)) { + xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr; + + xtalk_intr = *xtalk_intr_p; + + if (xtalk_intr == NULL) { + /* + * This xtalk_intr_alloc is constrained for two reasons: + * 1) Normal interrupts and error interrupts need to be delivered + * through a single xtalk target widget so that there aren't any + * ordering problems with DMA, completion interrupts, and error + * interrupts. (Use of xconn_vhdl forces this.) + * + * 2) On IP35, addressing constraints on IP35 and Bridge force + * us to use a single PI number for all interrupts from a + * single Bridge. (IP35-specific code forces this, and we + * verify in pcibr_setwidint.) + */ + xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, owner_dev); +#if DEBUG && INTR_DEBUG + printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr); +#endif + + /* both an assert and a runtime check on this: + * we need to check in non-DEBUG kernels, and + * the ASSERT gets us more information when + * we use DEBUG kernels. + */ + ASSERT(xtalk_intr != NULL); + if (xtalk_intr == NULL) { + /* it is quite possible that our + * xtalk_intr_alloc failed because + * someone else got there first, + * and we can find their results + * in xtalk_intr_p. + */ + if (!*xtalk_intr_p) { +#ifdef SUPPORT_PRINTING_V_FORMAT + PRINT_ALERT( + "pcibr_intr_alloc %v: unable to get xtalk interrupt resources", + xconn_vhdl); +#endif + /* yes, we leak resources here. */ + return 0; + } + } else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) { + /* + * now tell the bridge which slot is + * using this interrupt line. + */ + int_dev = bridge->b_int_device; + int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit); + int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit); + bridge->b_int_device = int_dev; /* XXXMP */ + +#if DEBUG && INTR_DEBUG + printk("%v: bridge intr bit %d clears my wrb\n", + pconn_vhdl, pcibr_int_bit); +#endif + } else { + /* someone else got one allocated first; + * free the one we just created, and + * retrieve the one they allocated. + */ + xtalk_intr_free(xtalk_intr); + xtalk_intr = *xtalk_intr_p; +#if PARANOID + /* once xtalk_intr is set, we never clear it, + * so if the CAS fails above, this condition + * can "never happen" ... + */ + if (!xtalk_intr) { + PRINT_ALERT( + "pcibr_intr_alloc %v: unable to set xtalk interrupt resources", + xconn_vhdl); + /* yes, we leak resources here. */ + return 0; + } +#endif + } + } + + /* + * For threaded drivers, set the interrupt thread to run wherever + * the interrupt is targeted. + */ +#ifdef notyet + if (is_threaded) { + cpuid_t old_mustrun = pcibr_intr->bi_mustruncpu; + pcibr_intr->bi_mustruncpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr)); + ASSERT(pcibr_intr->bi_mustruncpu >= 0); + + /* + * This is possible, but very unlikely: It means that 2 (or more) interrupts + * originating on a single Bridge and used by a single device were unable to + * find sufficient xtalk interrupt resources that would allow them all to be + * handled by the same CPU. If someone tries to target lots of interrupts to + * a single CPU, we might hit this case. Things should still operate correctly, + * but it's a sub-optimal configuration. + */ + if ((old_mustrun != CPU_NONE) && (old_mustrun != pcibr_intr->bi_mustruncpu)) { +#ifdef SUPPORT_PRINTING_V_FORMAT + PRINT_WARNING( "Conflict on where to schedule interrupts for %v\n", pconn_vhdl); +#endif + PRINT_WARNING( "(on cpu %d or on cpu %d)\n", old_mustrun, pcibr_intr->bi_mustruncpu); + } + } +#endif + + pcibr_intr->bi_ibits |= 1 << pcibr_int_bit; + + NEW(intr_entry); + intr_entry->il_next = NULL; + intr_entry->il_intr = pcibr_intr; + intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg); + + intr_list_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_list; + if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) { + /* we are the first interrupt on this bridge bit. + */ +#if DEBUG && INTR_DEBUG + printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n", + pconn_vhdl, pcibr_int_bits, pcibr_int_bit); +#endif + continue; + } + intr_list = *intr_list_p; + pcibr_intr_p = &intr_list->il_intr; + if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) { + /* first entry on list was erased, + * and we replaced it, so we + * don't need our intr_entry. + */ + DEL(intr_entry); +#if DEBUG && INTR_DEBUG + printk("%v INT 0x%x (bridge bit %d) replaces erased first\n", + pconn_vhdl, pcibr_int_bits, pcibr_int_bit); +#endif + continue; + } + intr_list_p = &intr_list->il_next; + if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) { + /* we are the new second interrupt on this bit. + * switch to local wrapper. + */ +#if DEBUG && INTR_DEBUG + printk("%v INT 0x%x (bridge bit %d) is new SECOND\n", + pconn_vhdl, pcibr_int_bits, pcibr_int_bit); +#endif + NEW(intr_wrap); + intr_wrap->iw_soft = pcibr_soft; + intr_wrap->iw_stat = &(bridge->b_int_status); + intr_wrap->iw_intr = 1 << pcibr_int_bit; + intr_wrap->iw_list = intr_list; + intr_wrap_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap; + if (!compare_and_swap_ptr((void **) intr_wrap_p, NULL, intr_wrap)) { + /* someone else set up the wrapper. + */ + DEL(intr_wrap); + continue; +#if DEBUG && INTR_DEBUG + } else { + printk("%v bridge bit %d wrapper state created\n", + pconn_vhdl, pcibr_int_bit); +#endif + } + continue; + } + while (1) { + pcibr_intr_p = &intr_list->il_intr; + if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) { + /* an entry on list was erased, + * and we replaced it, so we + * don't need our intr_entry. + */ + DEL(intr_entry); +#if DEBUG && INTR_DEBUG + printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n", + pconn_vhdl, pcibr_int_bits, pcibr_int_bit); +#endif + break; + } + intr_list_p = &intr_list->il_next; + if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) { + /* entry appended to share list + */ +#if DEBUG && INTR_DEBUG + printk("%v INT 0x%x (bridge bit %d) is new Nth\n", + pconn_vhdl, pcibr_int_bits, pcibr_int_bit); +#endif + break; + } + /* step to next record in chain + */ + intr_list = *intr_list_p; + } + } + } + +#ifdef IRIX + if (is_threaded) { + /* Set pcibr_intr->bi_tinfo */ + pcibr_thread_setup(pcibr_intr, pcibr_int_bits, thread_swlevel); + ASSERT(!(pcibr_intr->bi_flags & PCIIO_INTR_CONNECTED)); + } +#endif + +#if DEBUG && INTR_DEBUG + printk("%v pcibr_intr_alloc complete\n", pconn_vhdl); +#endif + hub_intr = (hub_intr_t)xtalk_intr; + pcibr_intr->bi_irq = hub_intr->i_bit; + pcibr_intr->bi_cpu = hub_intr->i_cpuid; + return pcibr_intr; +} + +/*ARGSUSED */ +void +pcibr_intr_free(pcibr_intr_t pcibr_intr) +{ + unsigned pcibr_int_bits = pcibr_intr->bi_ibits; + pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; + unsigned pcibr_int_bit; + pcibr_intr_list_t intr_list; + pcibr_intr_wrap_t intr_wrap; + xtalk_intr_t *xtalk_intrp; + + for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) { + if (pcibr_int_bits & (1 << pcibr_int_bit)) { + for (intr_list = + pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_list; + intr_list != NULL; + intr_list = intr_list->il_next) + if (compare_and_swap_ptr((void **) &intr_list->il_intr, + pcibr_intr, + NULL)) { +#if DEBUG && INTR_DEBUG + printk("%s: cleared a handler from bit %d\n", + pcibr_soft->bs_name, pcibr_int_bit); +#endif + } + /* If this interrupt line is not being shared between multiple + * devices release the xtalk interrupt resources. + */ + intr_wrap = + pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap; + xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr; + if ((intr_wrap == NULL) && (*xtalk_intrp)) { + + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t int_dev; + + xtalk_intr_free(*xtalk_intrp); + *xtalk_intrp = 0; + + /* Clear the PCI device interrupt to bridge interrupt pin + * mapping. + */ + int_dev = bridge->b_int_device; + int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit); + bridge->b_int_device = int_dev; + + } + } + } + DEL(pcibr_intr); +} + +LOCAL void +pcibr_setpciint(xtalk_intr_t xtalk_intr) +{ + iopaddr_t addr = xtalk_intr_addr_get(xtalk_intr); + xtalk_intr_vector_t vect = xtalk_intr_vector_get(xtalk_intr); + bridgereg_t *int_addr = (bridgereg_t *) + xtalk_intr_sfarg_get(xtalk_intr); + + *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) | + (BRIDGE_INT_ADDR_FLD & vect)); +} + +/*ARGSUSED */ +int +pcibr_intr_connect(pcibr_intr_t pcibr_intr, + intr_func_t intr_func, + intr_arg_t intr_arg, + void *thread) +{ + pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; + bridge_t *bridge = pcibr_soft->bs_base; + unsigned pcibr_int_bits = pcibr_intr->bi_ibits; + unsigned pcibr_int_bit; + bridgereg_t b_int_enable; + unsigned s; + + if (pcibr_intr == NULL) + return -1; + +#if DEBUG && INTR_DEBUG + printk("%v: pcibr_intr_connect 0x%X(0x%X)\n", + pcibr_intr->bi_dev, intr_func, intr_arg); +#endif + + pcibr_intr->bi_func = intr_func; + pcibr_intr->bi_arg = intr_arg; + *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED; + + /* + * For each PCI interrupt line requested, figure + * out which Bridge PCI Interrupt Line it maps + * to, and make sure there are xtalk resources + * allocated for it. + */ + for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) + if (pcibr_int_bits & (1 << pcibr_int_bit)) { + pcibr_intr_wrap_t intr_wrap; + xtalk_intr_t xtalk_intr; + int *setptr; + + xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr; + + /* if we have no wrap structure, + * tell xtalk to deliver the interrupt + * directly to the client. + */ + intr_wrap = pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap; + if (intr_wrap == NULL) { + xtalk_intr_connect(xtalk_intr, + (intr_func_t) intr_func, + (intr_arg_t) intr_arg, + (xtalk_intr_setfunc_t) pcibr_setpciint, + (void *) &(bridge->b_int_addr[pcibr_int_bit].addr), + thread); +#if DEBUG && INTR_DEBUG + printk("%v bridge bit %d routed by xtalk\n", + pcibr_intr->bi_dev, pcibr_int_bit); +#endif + continue; + } + + setptr = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_wrap_set; + if (*setptr) + continue; + + + /* We have a wrap structure, so we're sharing a Bridge interrupt level */ + + xtalk_intr_disconnect(xtalk_intr); /* Disconnect old interrupt */ + + /* + If the existing xtalk_intr was allocated without the NOTHREAD flag, + we need to allocate a new one that's NOTHREAD, and connect to the + new one. pcibr_intr_list_func expects to run at interrupt level + rather than in a thread. With today's devices, this can't happen, + so let's punt on writing the code till we need it (probably never). + Instead, just ASSERT that we're a NOTHREAD xtalk_intr. + */ +#ifdef IRIX + ASSERT_ALWAYS(!(pcibr_intr->bi_flags & PCIIO_INTR_NOTHREAD) || + xtalk_intr_flags_get(xtalk_intr) & XTALK_INTR_NOTHREAD); +#endif + + /* Use the wrapper dispatch function to handle shared Bridge interrupts */ + xtalk_intr_connect(xtalk_intr, + pcibr_intr_list_func, + (intr_arg_t) intr_wrap, + (xtalk_intr_setfunc_t) pcibr_setpciint, + (void *) &(bridge->b_int_addr[pcibr_int_bit].addr), + 0); + *setptr = 1; + +#if DEBUG && INTR_DEBUG + printk("%v bridge bit %d wrapper connected\n", + pcibr_intr->bi_dev, pcibr_int_bit); +#endif + } + s = pcibr_lock(pcibr_soft); + b_int_enable = bridge->b_int_enable; + b_int_enable |= pcibr_int_bits; + bridge->b_int_enable = b_int_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + pcibr_unlock(pcibr_soft, s); + + return 0; +} + +/*ARGSUSED */ +void +pcibr_intr_disconnect(pcibr_intr_t pcibr_intr) +{ + pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; + bridge_t *bridge = pcibr_soft->bs_base; + unsigned pcibr_int_bits = pcibr_intr->bi_ibits; + unsigned pcibr_int_bit; + pcibr_intr_wrap_t intr_wrap; + bridgereg_t b_int_enable; + unsigned s; + + /* Stop calling the function. Now. + */ + *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED; + pcibr_intr->bi_func = 0; + pcibr_intr->bi_arg = 0; + /* + * For each PCI interrupt line requested, figure + * out which Bridge PCI Interrupt Line it maps + * to, and disconnect the interrupt. + */ + + /* don't disable interrupts for lines that + * are shared between devices. + */ + for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) + if ((pcibr_int_bits & (1 << pcibr_int_bit)) && + (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_wrap_set)) + pcibr_int_bits &= ~(1 << pcibr_int_bit); + if (!pcibr_int_bits) + return; + + s = pcibr_lock(pcibr_soft); + b_int_enable = bridge->b_int_enable; + b_int_enable &= ~pcibr_int_bits; + bridge->b_int_enable = b_int_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + pcibr_unlock(pcibr_soft, s); + + for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) + if (pcibr_int_bits & (1 << pcibr_int_bit)) { + /* if we have set up the share wrapper, + * do not disconnect it. + */ + if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_wrap_set) + continue; + + xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr); + + /* if we have a share wrapper state, + * connect us up; this closes the hole + * where the connection of the wrapper + * was in progress as we disconnected. + */ + intr_wrap = pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap; + if (intr_wrap == NULL) + continue; + + + xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr, + pcibr_intr_list_func, + (intr_arg_t) intr_wrap, + (xtalk_intr_setfunc_t) pcibr_setpciint, + (void *) &(bridge->b_int_addr[pcibr_int_bit].addr), + 0); + } +} + +/*ARGSUSED */ +devfs_handle_t +pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr) +{ + pcibr_soft_t pcibr_soft = pcibr_intr->bi_soft; + unsigned pcibr_int_bits = pcibr_intr->bi_ibits; + unsigned pcibr_int_bit; + + for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) + if (pcibr_int_bits & (1 << pcibr_int_bit)) + return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr); + return 0; +} + +/* ===================================================================== + * INTERRUPT HANDLING + */ +LOCAL void +pcibr_clearwidint(bridge_t *bridge) +{ + bridge->b_wid_int_upper = 0; + bridge->b_wid_int_lower = 0; +} + + +LOCAL void +pcibr_setwidint(xtalk_intr_t intr) +{ + xwidgetnum_t targ = xtalk_intr_target_get(intr); + iopaddr_t addr = xtalk_intr_addr_get(intr); + xtalk_intr_vector_t vect = xtalk_intr_vector_get(intr); + widgetreg_t NEW_b_wid_int_upper, NEW_b_wid_int_lower; + widgetreg_t OLD_b_wid_int_upper, OLD_b_wid_int_lower; + + bridge_t *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr); + + NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) | + XTALK_ADDR_TO_UPPER(addr)); + NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); + + OLD_b_wid_int_upper = bridge->b_wid_int_upper; + OLD_b_wid_int_lower = bridge->b_wid_int_lower; + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + /* Verify that all interrupts from this Bridge are using a single PI */ + if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) { + /* + * Once set, these registers shouldn't change; they should + * be set multiple times with the same values. + * + * If we're attempting to change these registers, it means + * that our heuristics for allocating interrupts in a way + * appropriate for IP35 have failed, and the admin needs to + * explicitly direct some interrupts (or we need to make the + * heuristics more clever). + * + * In practice, we hope this doesn't happen very often, if + * at all. + */ + if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) || + (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) { + PRINT_WARNING("Interrupt allocation is too complex.\n"); + PRINT_WARNING("Use explicit administrative interrupt targetting.\n"); + PRINT_WARNING("bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ); + PRINT_WARNING("NEW=0x%x/0x%x OLD=0x%x/0x%x\n", + NEW_b_wid_int_upper, NEW_b_wid_int_lower, + OLD_b_wid_int_upper, OLD_b_wid_int_lower); + PRINT_PANIC("PCI Bridge interrupt targetting error\n"); + } + } +#endif /* CONFIG_SGI_IP35 */ + + bridge->b_wid_int_upper = NEW_b_wid_int_upper; + bridge->b_wid_int_lower = NEW_b_wid_int_lower; + bridge->b_int_host_err = vect; +} + +/* + * pcibr_intr_preset: called during mlreset time + * if the platform specific code needs to route + * one of the Bridge's xtalk interrupts before the + * xtalk infrastructure is available. + */ +void +pcibr_xintr_preset(void *which_widget, + int which_widget_intr, + xwidgetnum_t targ, + iopaddr_t addr, + xtalk_intr_vector_t vect) +{ + bridge_t *bridge = (bridge_t *) which_widget; + + if (which_widget_intr == -1) { + /* bridge widget error interrupt */ + bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) | + XTALK_ADDR_TO_UPPER(addr)); + bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); + bridge->b_int_host_err = vect; + + /* turn on all interrupts except + * the PCI interrupt requests, + * at least at heart. + */ + bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK; + + } else { + /* routing a pci device interrupt. + * targ and low 38 bits of addr must + * be the same as the already set + * value for the widget error interrupt. + */ + bridge->b_int_addr[which_widget_intr].addr = + ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) | + (BRIDGE_INT_ADDR_FLD & vect)); + /* + * now bridge can let it through; + * NB: still should be blocked at + * xtalk provider end, until the service + * function is set. + */ + bridge->b_int_enable |= 1 << vect; + } + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ +} + +void +pcibr_intr_list_func(intr_arg_t arg) +{ + pcibr_intr_wrap_t wrap = (pcibr_intr_wrap_t) arg; + reg_p statp = wrap->iw_stat; + bridgereg_t mask = wrap->iw_intr; + reg_p wrbf; + pcibr_intr_list_t list; + pcibr_intr_t intr; + intr_func_t func; + int clearit; + int thread_count = 0; + + /* + * Loop until either + * 1) All interrupts have been removed by direct-called interrupt handlers OR + * 2) We've woken up at least one interrupt thread that will presumably clear + * Bridge interrupt bits + */ + + while ((!thread_count) && (mask & *statp)) { + clearit = 1; + for (list = wrap->iw_list; + list != NULL; + list = list->il_next) { + if ((intr = list->il_intr) && + (intr->bi_flags & PCIIO_INTR_CONNECTED)) { + int is_threaded; + + ASSERT(intr->bi_func); + + /* + * This device may have initiated write + * requests since the bridge last saw + * an edge on this interrupt input; flushing + * the buffer here should help but may not + * be sufficient if we get more requests after + * the flush, followed by the card deciding + * it wants service, before the interrupt + * handler checks to see if things need + * to be done. + * + * There is a similar race condition if + * an interrupt handler loops around and + * notices further service is requred. + * Perhaps we need to have an explicit + * call that interrupt handlers need to + * do between noticing that DMA to memory + * has completed, but before observing the + * contents of memory? + */ +#ifdef IRIX + if (wrbf = list->il_wrbf) +#else + if ((wrbf = list->il_wrbf)) +#endif + (void) *wrbf; /* write request buffer flush */ + + is_threaded = !(intr->bi_flags & PCIIO_INTR_NOTHREAD); + + if (is_threaded) { + thread_count++; +#ifdef IRIX + icvsema(&intr->bi_tinfo.thd_isync, intr->bi_tinfo.thd_pri, + NULL, NULL, NULL); +#endif + } else { + /* Non-threaded. Call the interrupt handler at interrupt level */ + func = intr->bi_func; + func(intr->bi_arg); + } + + clearit = 0; + } + } + + /* If there were no handlers, + * disable the interrupt and return. + * It will get enabled again after + * a handler is connected. + * If we don't do this, we would + * sit here and spin through the + * list forever. + */ + if (clearit) { + pcibr_soft_t pcibr_soft = wrap->iw_soft; + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t b_int_enable; + unsigned s; + + s = pcibr_lock(pcibr_soft); + b_int_enable = bridge->b_int_enable; + b_int_enable &= ~mask; + bridge->b_int_enable = b_int_enable; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + pcibr_unlock(pcibr_soft, s); + return; + } + } +} + +/* ===================================================================== + * ERROR HANDLING + */ + +#ifdef DEBUG +#ifdef ERROR_DEBUG +#define BRIDGE_PIOERR_TIMEOUT 100 /* Timeout with ERROR_DEBUG defined */ +#else +#define BRIDGE_PIOERR_TIMEOUT 40 /* Timeout in debug mode */ +#endif +#else +#define BRIDGE_PIOERR_TIMEOUT 1 /* Timeout in non-debug mode */ +#endif + +LOCAL void +print_bridge_errcmd(uint32_t cmdword, char *errtype) +{ +#ifdef SUPPORT_PRINTING_R_FORMAT + PRINT_WARNING( + " Bridge %s error command word register %R", + errtype, cmdword, xio_cmd_bits); +#else + PRINT_WARNING( + " Bridge %s error command word register 0x%x", + errtype, cmdword); +#endif +} + +LOCAL char *pcibr_isr_errs[] = +{ + "", "", "", "", "", "", "", "", + "08: GIO non-contiguous byte enable in crosstalk packet", + "09: PCI to Crosstalk read request timeout", + "10: PCI retry operation count exhausted.", + "11: PCI bus device select timeout", + "12: PCI device reported parity error", + "13: PCI Address/Cmd parity error ", + "14: PCI Bridge detected parity error", + "15: PCI abort condition", + "16: SSRAM parity error", + "17: LLP Transmitter Retry count wrapped", + "18: LLP Transmitter side required Retry", + "19: LLP Receiver retry count wrapped", + "20: LLP Receiver check bit error", + "21: LLP Receiver sequence number error", + "22: Request packet overflow", + "23: Request operation not supported by bridge", + "24: Request packet has invalid address for bridge widget", + "25: Incoming request xtalk command word error bit set or invalid sideband", + "26: Incoming response xtalk command word error bit set or invalid sideband", + "27: Framing error, request cmd data size does not match actual", + "28: Framing error, response cmd data size does not match actual", + "29: Unexpected response arrived", + "30: Access to SSRAM beyond device limits", + "31: Multiple errors occurred", +}; + +/* + * PCI Bridge Error interrupt handling. + * This routine gets invoked from system interrupt dispatcher + * and is responsible for invoking appropriate error handler, + * depending on the type of error. + * This IS a duplicate of bridge_errintr defined specfic to IP30. + * There are some minor differences in terms of the return value and + * parameters passed. One of these two should be removed at some point + * of time. + */ +/*ARGSUSED */ +void +pcibr_error_dump(pcibr_soft_t pcibr_soft) +{ + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t int_status; + int i; + + int_status = (bridge->b_int_status & ~BRIDGE_ISR_INT_MSK); + + PRINT_ALERT( "%s PCI BRIDGE ERROR: int_status is 0x%X", + pcibr_soft->bs_name, int_status); + + for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++) { + if (int_status & (1 << i)) { + PRINT_WARNING( "%s", pcibr_isr_errs[i]); + } + } + + if (int_status & BRIDGE_ISR_XTALK_ERROR) { + print_bridge_errcmd(bridge->b_wid_err_cmdword, ""); + + PRINT_WARNING(" Bridge error address 0x%lx", + (((uint64_t) bridge->b_wid_err_upper << 32) | + bridge->b_wid_err_lower)); + + print_bridge_errcmd(bridge->b_wid_aux_err, "Aux"); + + if (int_status & (BRIDGE_ISR_BAD_XRESP_PKT | BRIDGE_ISR_RESP_XTLK_ERR)) { + PRINT_WARNING(" Bridge response buffer: dev-num %d buff-num %d addr 0x%lx\n", + ((bridge->b_wid_resp_upper >> 20) & 0x3), + ((bridge->b_wid_resp_upper >> 16) & 0xF), + (((uint64_t) (bridge->b_wid_resp_upper & 0xFFFF) << 32) | + bridge->b_wid_resp_lower)); + } + } + if (int_status & BRIDGE_ISR_SSRAM_PERR) + PRINT_WARNING(" Bridge SSRAM parity error register 0x%x", + bridge->b_ram_perr); + + if (int_status & BRIDGE_ISR_PCIBUS_ERROR) { + PRINT_WARNING(" PCI/GIO error upper address register 0x%x", + bridge->b_pci_err_upper); + + PRINT_WARNING(" PCI/GIO error lower address register 0x%x", + bridge->b_pci_err_lower); + } + if (int_status & BRIDGE_ISR_ERROR_FATAL) { + cmn_err_tag(14, (int)CE_PANIC, "PCI Bridge Error interrupt killed the system"); + /*NOTREACHED */ + } else { + PRINT_ALERT( "Non-fatal Error in Bridge.."); + } +} + +#define PCIBR_ERRINTR_GROUP(error) \ + (( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP) + +uint32_t +pcibr_errintr_group(uint32_t error) +{ + uint32_t group = BRIDGE_IRR_MULTI_CLR; + + if (error & BRIDGE_IRR_PCI_GRP) + group |= BRIDGE_IRR_PCI_GRP_CLR; + if (error & BRIDGE_IRR_SSRAM_GRP) + group |= BRIDGE_IRR_SSRAM_GRP_CLR; + if (error & BRIDGE_IRR_LLP_GRP) + group |= BRIDGE_IRR_LLP_GRP_CLR; + if (error & BRIDGE_IRR_REQ_DSP_GRP) + group |= BRIDGE_IRR_REQ_DSP_GRP_CLR; + if (error & BRIDGE_IRR_RESP_BUF_GRP) + group |= BRIDGE_IRR_RESP_BUF_GRP_CLR; + if (error & BRIDGE_IRR_CRP_GRP) + group |= BRIDGE_IRR_CRP_GRP_CLR; + + return group; + +} + + +/* pcibr_pioerr_check(): + * Check to see if this pcibr has a PCI PIO + * TIMEOUT error; if so, clear it and bump + * the timeout-count on any piomaps that + * could cover the address. + */ +static void +pcibr_pioerr_check(pcibr_soft_t soft) +{ + bridge_t *bridge; + bridgereg_t b_int_status; + bridgereg_t b_pci_err_lower; + bridgereg_t b_pci_err_upper; + iopaddr_t pci_addr; + pciio_slot_t slot; + pcibr_piomap_t map; + iopaddr_t base; + size_t size; + unsigned win; + int func; + + bridge = soft->bs_base; + b_int_status = bridge->b_int_status; + if (b_int_status & BRIDGE_ISR_PCIBUS_PIOERR) { + b_pci_err_lower = bridge->b_pci_err_lower; + b_pci_err_upper = bridge->b_pci_err_upper; + b_int_status = bridge->b_int_status; + if (b_int_status & BRIDGE_ISR_PCIBUS_PIOERR) { + bridge->b_int_rst_stat = (BRIDGE_IRR_PCI_GRP_CLR| + BRIDGE_IRR_MULTI_CLR); + + pci_addr = b_pci_err_upper & BRIDGE_ERRUPPR_ADDRMASK; + pci_addr = (pci_addr << 32) | b_pci_err_lower; + + slot = 8; + while (slot-- > 0) { + int nfunc = soft->bs_slot[slot].bss_ninfo; + pcibr_info_h pcibr_infoh = soft->bs_slot[slot].bss_infos; + + for (func = 0; func < nfunc; func++) { + pcibr_info_t pcibr_info = pcibr_infoh[func]; + + if (!pcibr_info) + continue; + + for (map = pcibr_info->f_piomap; + map != NULL; map = map->bp_next) { + base = map->bp_pciaddr; + size = map->bp_mapsz; + win = map->bp_space - PCIIO_SPACE_WIN(0); + if (win < 6) + base += + soft->bs_slot[slot].bss_window[win].bssw_base; + else if (map->bp_space == PCIIO_SPACE_ROM) + base += pcibr_info->f_rbase; +#ifdef IRIX + if ((pci_addr >= base) && (pci_addr < (base + size))) + atomicAddInt(map->bp_toc, 1); +#endif + } + } + } + } + } +} + +/* + * PCI Bridge Error interrupt handler. + * This gets invoked, whenever a PCI bridge sends an error interrupt. + * Primarily this servers two purposes. + * - If an error can be handled (typically a PIO read/write + * error, we try to do it silently. + * - If an error cannot be handled, we die violently. + * Interrupt due to PIO errors: + * - Bridge sends an interrupt, whenever a PCI operation + * done by the bridge as the master fails. Operations could + * be either a PIO read or a PIO write. + * PIO Read operation also triggers a bus error, and it's + * We primarily ignore this interrupt in that context.. + * For PIO write errors, this is the only indication. + * and we have to handle with the info from here. + * + * So, there is no way to distinguish if an interrupt is + * due to read or write error!. + */ + + +LOCAL void +pcibr_error_intr_handler(intr_arg_t arg) +{ + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + bridgereg_t int_status; + bridgereg_t err_status; + int i; + +#if defined(SN0_HWDEBUG) + extern int la_trigger_nasid1; + extern int la_trigger_nasid2; + extern long la_trigger_val; +#endif + + /* REFERENCED */ + bridgereg_t disable_errintr_mask = 0; +#ifdef IRIX + int rv; +#else + int rv = 0; +#endif + int error_code = IOECODE_DMA | IOECODE_READ; + ioerror_mode_t mode = MODE_DEVERROR; + ioerror_t ioe; + +#if defined(SN0_HWDEBUG) + /* + * trigger points for logic analyzer. Used to debug the DMA timeout + * note that 0xcafe is added to the trigger values to avoid false + * triggers when la_trigger_val shows up in a cacheline as data + */ + if (la_trigger_nasid1 != -1) + REMOTE_HUB_PI_S(la_trigger_nasid1, 0, PI_CPU_NUM, la_trigger_val + 0xcafe); + if (la_trigger_nasid2 != -1) + REMOTE_HUB_PI_S(la_trigger_nasid2, 0, PI_CPU_NUM, la_trigger_val + 0xcafe); +#endif + +#if PCIBR_SOFT_LIST + /* IP27 seems to be handing us junk. + */ + { + pcibr_list_p entry; + + entry = pcibr_list; + while (1) { + if (entry == NULL) { + printk("pcibr_error_intr_handler:\n" + "\tparameter (0x%p) is not a pcibr_soft!", + arg); + PRINT_PANIC("Invalid parameter to pcibr_error_intr_handler"); + } + if ((intr_arg_t) entry->bl_soft == arg) + break; + entry = entry->bl_next; + } + } +#endif + pcibr_soft = (pcibr_soft_t) arg; + bridge = pcibr_soft->bs_base; + + /* + * pcibr_error_intr_handler gets invoked whenever bridge encounters + * an error situation, and the interrupt for that error is enabled. + * This routine decides if the error is fatal or not, and takes + * action accordingly. + * + * In one case there is a need for special action. + * In case of PIO read/write timeouts due to user level, we do + * get an error interrupt. In this case, way to handle would + * be to start a timeout. If the error was due to "read", bus + * error handling code takes care of it. If error is due to write, + * it's handled at timeout + */ + + /* int_status is which bits we have to clear; + * err_status is the bits we haven't handled yet. + */ + + int_status = bridge->b_int_status & ~BRIDGE_ISR_INT_MSK; + err_status = int_status & ~BRIDGE_ISR_MULTI_ERR; + + if (!(int_status & ~BRIDGE_ISR_INT_MSK)) { + /* + * No error bit set!!. + */ + return; + } + /* If we have a PCIBUS_PIOERR, + * hand it to the logger but otherwise + * ignore the event. + */ + if (int_status & BRIDGE_ISR_PCIBUS_PIOERR) { + pcibr_pioerr_check(pcibr_soft); + err_status &= ~BRIDGE_ISR_PCIBUS_PIOERR; + int_status &= ~BRIDGE_ISR_PCIBUS_PIOERR; + } + + + if (err_status) { + struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat; + + for (i = PCIBR_ISR_ERR_START; i < PCIBR_ISR_MAX_ERRS; i++, bs_estat++) { + if (err_status & (1 << i)) { + uint32_t errrate = 0; + uint32_t errcount = 0; + uint32_t errinterval = 0, current_tick = 0; + int panic_on_llp_tx_retry = 0; + int is_llp_tx_retry_intr = 0; + + bs_estat->bs_errcount_total++; + +#ifdef IRIX + current_tick = lbolt; +#else + current_tick = 0; +#endif + errinterval = (current_tick - bs_estat->bs_lasterr_timestamp); + errcount = (bs_estat->bs_errcount_total - + bs_estat->bs_lasterr_snapshot); + + is_llp_tx_retry_intr = (BRIDGE_ISR_LLP_TX_RETRY == (1 << i)); + + /* On a non-zero error rate (which is equivalent to + * to 100 errors /sec at least) for the LLP transmitter + * retry interrupt we need to panic the system + * to prevent potential data corruption . + * NOTE : errcount is being compared to PCIBR_ERRTIME_THRESHOLD + * to make sure that we are not seing cases like x error + * interrupts per y ticks for very low x ,y (x > y ) which + * makes error rate be > 100 /sec. + */ + + /* Check for the divide by zero condition while + * calculating the error rates. + */ + + if (errinterval) { + errrate = errcount / errinterval; + /* If able to calculate error rate + * on a LLP transmitter retry interrupt check + * if the error rate is nonzero and we have seen + * a certain minimum number of errors. + */ + if (is_llp_tx_retry_intr && + errrate && + (errcount >= PCIBR_ERRTIME_THRESHOLD)) { + panic_on_llp_tx_retry = 1; + } + } else { + errrate = 0; + /* Since we are not able to calculate the + * error rate check if we exceeded a certain + * minimum number of errors for LLP transmitter + * retries. Note that this can only happen + * within the first tick after the last snapshot. + */ + if (is_llp_tx_retry_intr && + (errcount >= PCIBR_ERRINTR_DISABLE_LEVEL)) { + panic_on_llp_tx_retry = 1; + } + } + if (panic_on_llp_tx_retry) { + static uint32_t last_printed_rate; + + if (errrate > last_printed_rate) { + last_printed_rate = errrate; + /* Print the warning only if the error rate + * for the transmitter retry interrupt + * exceeded the previously printed rate. + */ + PRINT_WARNING( + "%s: %s, Excessive error interrupts : %d/tick\n", + pcibr_soft->bs_name, + pcibr_isr_errs[i], + errrate); + + } + /* + * Update snapshot, and time + */ + bs_estat->bs_lasterr_timestamp = current_tick; + bs_estat->bs_lasterr_snapshot = + bs_estat->bs_errcount_total; + + } + /* + * If the error rate is high enough, print the error rate. + */ + if (errinterval > PCIBR_ERRTIME_THRESHOLD) { + + if (errrate > PCIBR_ERRRATE_THRESHOLD) { + PRINT_NOTICE( "%s: %s, Error rate %d/tick", + pcibr_soft->bs_name, + pcibr_isr_errs[i], + errrate); + /* + * Update snapshot, and time + */ + bs_estat->bs_lasterr_timestamp = current_tick; + bs_estat->bs_lasterr_snapshot = + bs_estat->bs_errcount_total; + } + } + if (bs_estat->bs_errcount_total > PCIBR_ERRINTR_DISABLE_LEVEL) { + /* + * We have seen a fairly large number of errors of + * this type. Let's disable the interrupt. But flash + * a message about the interrupt being disabled. + */ + PRINT_NOTICE( + "%s Disabling error interrupt type %s. Error count %d", + pcibr_soft->bs_name, + pcibr_isr_errs[i], + bs_estat->bs_errcount_total); + disable_errintr_mask |= (1 << i); + } + } + } + } + + if (disable_errintr_mask) { + /* + * Disable some high frequency errors as they + * could eat up too much cpu time. + */ + bridge->b_int_enable &= ~disable_errintr_mask; + } + /* + * If we leave the PROM cacheable, T5 might + * try to do a cache line sized writeback to it, + * which will cause a BRIDGE_ISR_INVLD_ADDR. + */ + if ((err_status & BRIDGE_ISR_INVLD_ADDR) && + (0x00000000 == bridge->b_wid_err_upper) && + (0x00C00000 == (0xFFC00000 & bridge->b_wid_err_lower)) && + (0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) { + err_status &= ~BRIDGE_ISR_INVLD_ADDR; + } +#if defined (PCIBR_LLP_CONTROL_WAR) + /* + * The bridge bug, where the llp_config or control registers + * need to be read back after being written, affects an MP + * system since there could be small windows between writing + * the register and reading it back on one cpu while another + * cpu is fielding an interrupt. If we run into this scenario, + * workaround the problem by ignoring the error. (bug 454474) + * pcibr_llp_control_war_cnt keeps an approximate number of + * times we saw this problem on a system. + */ + + if ((err_status & BRIDGE_ISR_INVLD_ADDR) && + ((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower)) + == (BRIDGE_INT_RST_STAT & 0xff0))) { +#ifdef IRIX + if (kdebug) + PRINT_NOTICE( "%s bridge: ignoring llp/control address interrupt", + pcibr_soft->bs_name); +#endif + pcibr_llp_control_war_cnt++; + err_status &= ~BRIDGE_ISR_INVLD_ADDR; + } +#endif /* PCIBR_LLP_CONTROL_WAR */ + + /* Check if this is the RESP_XTALK_ERROR interrupt. + * This can happen due to a failed DMA READ operation. + */ + if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) { + /* Phase 1 : Look at the error state in the bridge and further + * down in the device layers. + */ +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + (void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP); +#endif + IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid); + (void)pcibr_error_handler((error_handler_arg_t)pcibr_soft, + error_code, + mode, + &ioe); + /* Phase 2 : Perform the action agreed upon in phase 1. + */ +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + (void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION); +#endif + rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft, + error_code, + mode, + &ioe); + } + if (rv != IOERROR_HANDLED) { +#ifdef DEBUG + if (err_status & BRIDGE_ISR_ERROR_DUMP) + pcibr_error_dump(pcibr_soft); +#else + if (err_status & BRIDGE_ISR_ERROR_FATAL) { + printk("BRIDGE ERR STATUS 0x%x\n", err_status); + pcibr_error_dump(pcibr_soft); + } +#endif + } + /* + * We can't return without re-enabling the interrupt, since + * it would cause problems for devices like IOC3 (Lost + * interrupts ?.). So, just cleanup the interrupt, and + * use saved values later.. + */ + bridge->b_int_rst_stat = pcibr_errintr_group(int_status); +} + +/* + * pcibr_addr_toslot + * Given the 'pciaddr' find out which slot this address is + * allocated to, and return the slot number. + * While we have the info handy, construct the + * function number, space code and offset as well. + * + * NOTE: if this routine is called, we don't know whether + * the address is in CFG, MEM, or I/O space. We have to guess. + * This will be the case on PIO stores, where the only way + * we have of getting the address is to check the Bridge, which + * stores the PCI address but not the space and not the xtalk + * address (from which we could get it). + */ +LOCAL int +pcibr_addr_toslot(pcibr_soft_t pcibr_soft, + iopaddr_t pciaddr, + pciio_space_t *spacep, + iopaddr_t *offsetp, + pciio_function_t *funcp) +{ +#ifdef IRIX + int s, f, w; +#else + int s, f=0, w; +#endif + iopaddr_t base; + size_t size; + pciio_piospace_t piosp; + + /* + * Check if the address is in config space + */ + + if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) { + + if (pciaddr >= BRIDGE_CONFIG1_BASE) + pciaddr -= BRIDGE_CONFIG1_BASE; + else + pciaddr -= BRIDGE_CONFIG_BASE; + + s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE; + pciaddr %= BRIDGE_CONFIG_SLOT_SIZE; + + if (funcp) { + f = pciaddr / 0x100; + pciaddr %= 0x100; + } + if (spacep) + *spacep = PCIIO_SPACE_CFG; + if (offsetp) + *offsetp = pciaddr; + if (funcp) + *funcp = f; + + return s; + } + for (s = 0; s < 8; s++) { + int nf = pcibr_soft->bs_slot[s].bss_ninfo; + pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos; + + for (f = 0; f < nf; f++) { + pcibr_info_t pcibr_info = pcibr_infoh[f]; + + if (!pcibr_info) + continue; + for (w = 0; w < 6; w++) { + if (pcibr_info->f_window[w].w_space + == PCIIO_SPACE_NONE) { + continue; + } + base = pcibr_info->f_window[w].w_base; + size = pcibr_info->f_window[w].w_size; + + if ((pciaddr >= base) && (pciaddr < (base + size))) { + if (spacep) + *spacep = PCIIO_SPACE_WIN(w); + if (offsetp) + *offsetp = pciaddr - base; + if (funcp) + *funcp = f; + return s; + } /* endif match */ + } /* next window */ + } /* next func */ + } /* next slot */ + + /* + * Check if the address was allocated as part of the + * pcibr_piospace_alloc calls. + */ + for (s = 0; s < 8; s++) { + int nf = pcibr_soft->bs_slot[s].bss_ninfo; + pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos; + + for (f = 0; f < nf; f++) { + pcibr_info_t pcibr_info = pcibr_infoh[f]; + + if (!pcibr_info) + continue; + piosp = pcibr_info->f_piospace; + while (piosp) { + if ((piosp->start <= pciaddr) && + ((piosp->count + piosp->start) > pciaddr)) { + if (spacep) + *spacep = piosp->space; + if (offsetp) + *offsetp = pciaddr - piosp->start; + return s; + } /* endif match */ + piosp = piosp->next; + } /* next piosp */ + } /* next func */ + } /* next slot */ + + /* + * Some other random address on the PCI bus ... + * we have no way of knowing whether this was + * a MEM or I/O access; so, for now, we just + * assume that the low 1G is MEM, the next + * 3G is I/O, and anything above the 4G limit + * is obviously MEM. + */ + + if (spacep) + *spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM : + (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO : + PCIIO_SPACE_MEM); + if (offsetp) + *offsetp = pciaddr; + + return PCIIO_SLOT_NONE; + +} + +LOCAL void +pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code) +{ + bridge_t *bridge = pcibr_soft->bs_base; + + ASSERT(error_code & IOECODE_PIO); + error_code = error_code; + + bridge->b_int_rst_stat = + (BRIDGE_IRR_PCI_GRP_CLR | BRIDGE_IRR_MULTI_CLR); + (void) bridge->b_wid_tflush; /* flushbus */ +} + +/* + * pcibr_error_extract + * Given the 'pcibr vertex handle' find out which slot + * the bridge status error address (from pcibr_soft info + * hanging off the vertex) + * allocated to, and return the slot number. + * While we have the info handy, construct the + * space code and offset as well. + * + * NOTE: if this routine is called, we don't know whether + * the address is in CFG, MEM, or I/O space. We have to guess. + * This will be the case on PIO stores, where the only way + * we have of getting the address is to check the Bridge, which + * stores the PCI address but not the space and not the xtalk + * address (from which we could get it). + * + * XXX- this interface has no way to return the function + * number on a multifunction card, even though that data + * is available. + */ + +pciio_slot_t +pcibr_error_extract(devfs_handle_t pcibr_vhdl, + pciio_space_t *spacep, + iopaddr_t *offsetp) +{ + pcibr_soft_t pcibr_soft = 0; + iopaddr_t bserr_addr; + bridge_t *bridge; + pciio_slot_t slot = PCIIO_SLOT_NONE; + arbitrary_info_t rev; + + /* Do a sanity check as to whether we really got a + * bridge vertex handle. + */ + if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) != + GRAPH_SUCCESS) + return(slot); + + pcibr_soft = pcibr_soft_get(pcibr_vhdl); + if (pcibr_soft) { + bridge = pcibr_soft->bs_base; + bserr_addr = + bridge->b_pci_err_lower | + ((uint64_t) (bridge->b_pci_err_upper & + BRIDGE_ERRUPPR_ADDRMASK) << 32); + + slot = pcibr_addr_toslot(pcibr_soft, bserr_addr, + spacep, offsetp, NULL); + } + return slot; +} + +/*ARGSUSED */ +void +pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum) +{ + /* + * XXX + * Device failed to handle error. Take steps to + * disable this device ? HOW TO DO IT ? + * + * If there are any Read response buffers associated + * with this device, it's time to get them back!! + * + * We can disassociate any interrupt level associated + * with this device, and disable that interrupt level + * + * For now it's just a place holder + */ +} + +/* + * pcibr_pioerror + * Handle PIO error that happened at the bridge pointed by pcibr_soft. + * + * Queries the Bus interface attached to see if the device driver + * mapping the device-number that caused error can handle the + * situation. If so, it will clean up any error, and return + * indicating the error was handled. If the device driver is unable + * to handle the error, it expects the bus-interface to disable that + * device, and takes any steps needed here to take away any resources + * associated with this device. + */ + +#define BEM_ADD_STR(s) printk("%s", (s)) +#ifdef SUPPORT_SGI_CMN_ERR_STUFF +#define BEM_ADD_VAR(v) printk("\t%20s: 0x%x\n", #v, (v)) +#define BEM_ADD_REG(r) printk("\t%20s: %R\n", #r, (r), r ## _desc) + +#define BEM_ADD_NSPC(n,s) printk("\t%20s: %R\n", n, s, space_desc) +#else +#define BEM_ADD_VAR(v) +#define BEM_ADD_REG(r) +#define BEM_ADD_NSPC(n,s) +#endif +#define BEM_ADD_SPC(s) BEM_ADD_NSPC(#s, s) + +/* BEM_ADD_IOE doesn't dump the whole ioerror, it just + * decodes the PCI specific portions -- we count on our + * callers to dump the raw IOE data. + */ +#ifdef colin +#define BEM_ADD_IOE(ioe) \ + do { \ + if (IOERROR_FIELDVALID(ioe, busspace)) { \ + unsigned spc; \ + unsigned win; \ + \ + spc = IOERROR_GETVALUE(ioe, busspace); \ + win = spc - PCIIO_SPACE_WIN(0); \ + \ + switch (spc) { \ + case PCIIO_SPACE_CFG: \ + printk("\tPCI Slot %d Func %d CFG space Offset 0x%x\n", \ + pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, widgetdev)), \ + pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, widgetdev)), \ + IOERROR_GETVALUE(ioe, busaddr)); \ + break; \ + case PCIIO_SPACE_IO: \ + printk("\tPCI I/O space Offset 0x%x\n", \ + IOERROR_GETVALUE(ioe, busaddr)); \ + break; \ + case PCIIO_SPACE_MEM: \ + case PCIIO_SPACE_MEM32: \ + case PCIIO_SPACE_MEM64: \ + printk("\tPCI MEM space Offset 0x%x\n", \ + IOERROR_GETVALUE(ioe, busaddr)); \ + break; \ + default: \ + if (win < 6) { \ + printk("\tPCI Slot %d Func %d Window %d Offset 0x%x\n",\ + pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, widgetdev)), \ + pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, widgetdev)), \ + win, \ + IOERROR_GETVALUE(ioe, busaddr)); \ + } \ + break; \ + } \ + } \ + } while (0) +#else +#define BEM_ADD_IOE(ioe) +#endif + +/*ARGSUSED */ +LOCAL int +pcibr_pioerror( + pcibr_soft_t pcibr_soft, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioe) +{ + int retval = IOERROR_HANDLED; + + devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + bridge_t *bridge = pcibr_soft->bs_base; + + bridgereg_t bridge_int_status; + bridgereg_t bridge_pci_err_lower; + bridgereg_t bridge_pci_err_upper; + bridgereg_t bridge_pci_err_addr; + + iopaddr_t bad_xaddr; + + pciio_space_t raw_space; /* raw PCI space */ + iopaddr_t raw_paddr; /* raw PCI address */ + + pciio_space_t space; /* final PCI space */ + pciio_slot_t slot; /* final PCI slot, if appropriate */ + pciio_function_t func; /* final PCI func, if appropriate */ + iopaddr_t offset; /* final PCI offset */ + + int cs, cw, cf; + pciio_space_t wx; + iopaddr_t wb; + size_t ws; + iopaddr_t wl; + + + /* + * We expect to have an "xtalkaddr" coming in, + * and need to construct the slot/space/offset. + */ + +#ifdef colin + bad_xaddr = IOERROR_GETVALUE(ioe, xtalkaddr); +#else + bad_xaddr = -1; +#endif + + slot = PCIIO_SLOT_NONE; + func = PCIIO_FUNC_NONE; + raw_space = PCIIO_SPACE_NONE; + raw_paddr = 0; + + if ((bad_xaddr >= BRIDGE_TYPE0_CFG_DEV0) && + (bad_xaddr < BRIDGE_TYPE1_CFG)) { + raw_paddr = bad_xaddr - BRIDGE_TYPE0_CFG_DEV0; + slot = raw_paddr / BRIDGE_TYPE0_CFG_SLOT_OFF; + raw_paddr = raw_paddr % BRIDGE_TYPE0_CFG_SLOT_OFF; + raw_space = PCIIO_SPACE_CFG; + } + if ((bad_xaddr >= BRIDGE_TYPE1_CFG) && + (bad_xaddr < (BRIDGE_TYPE1_CFG + 0x1000))) { + /* Type 1 config space: + * slot and function numbers not known. + * Perhaps we can read them back? + */ + raw_paddr = bad_xaddr - BRIDGE_TYPE1_CFG; + raw_space = PCIIO_SPACE_CFG; + } + if ((bad_xaddr >= BRIDGE_DEVIO0) && + (bad_xaddr < BRIDGE_DEVIO(BRIDGE_DEV_CNT))) { + int x; + + raw_paddr = bad_xaddr - BRIDGE_DEVIO0; + x = raw_paddr / BRIDGE_DEVIO_OFF; + raw_paddr %= BRIDGE_DEVIO_OFF; + /* first two devio windows are double-sized */ + if ((x == 1) || (x == 3)) + raw_paddr += BRIDGE_DEVIO_OFF; + if (x > 0) + x--; + if (x > 1) + x--; + /* x is which devio reg; no guarantee + * pci slot x will be responding. + * still need to figure out who decodes + * space/offset on the bus. + */ + raw_space = pcibr_soft->bs_slot[x].bss_devio.bssd_space; + if (raw_space == PCIIO_SPACE_NONE) { + /* Someone got an error because they + * accessed the PCI bus via a DevIO(x) + * window that pcibr has not yet assigned + * to any specific PCI address. It is + * quite possible that the Device(x) + * register has been changed since they + * made their access, but we will give it + * our best decode shot. + */ + raw_space = pcibr_soft->bs_slot[x].bss_device + & BRIDGE_DEV_DEV_IO_MEM + ? PCIIO_SPACE_MEM + : PCIIO_SPACE_IO; + raw_paddr += + (pcibr_soft->bs_slot[x].bss_device & + BRIDGE_DEV_OFF_MASK) << + BRIDGE_DEV_OFF_ADDR_SHFT; + } else + raw_paddr += pcibr_soft->bs_slot[x].bss_devio.bssd_base; + } + if ((bad_xaddr >= BRIDGE_PCI_MEM32_BASE) && + (bad_xaddr <= BRIDGE_PCI_MEM32_LIMIT)) { + raw_space = PCIIO_SPACE_MEM32; + raw_paddr = bad_xaddr - BRIDGE_PCI_MEM32_BASE; + } + if ((bad_xaddr >= BRIDGE_PCI_MEM64_BASE) && + (bad_xaddr <= BRIDGE_PCI_MEM64_LIMIT)) { + raw_space = PCIIO_SPACE_MEM64; + raw_paddr = bad_xaddr - BRIDGE_PCI_MEM64_BASE; + } + if ((bad_xaddr >= BRIDGE_PCI_IO_BASE) && + (bad_xaddr <= BRIDGE_PCI_IO_LIMIT)) { + raw_space = PCIIO_SPACE_IO; + raw_paddr = bad_xaddr - BRIDGE_PCI_IO_BASE; + } + space = raw_space; + offset = raw_paddr; + + if ((slot == PCIIO_SLOT_NONE) && (space != PCIIO_SPACE_NONE)) { + /* we've got a space/offset but not which + * pci slot decodes it. Check through our + * notions of which devices decode where. + * + * Yes, this "duplicates" some logic in + * pcibr_addr_toslot; the difference is, + * this code knows which space we are in, + * and can really really tell what is + * going on (no guessing). + */ + + for (cs = 0; (cs < 8) && (slot == PCIIO_SLOT_NONE); cs++) { + int nf = pcibr_soft->bs_slot[cs].bss_ninfo; + pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[cs].bss_infos; + + for (cf = 0; (cf < nf) && (slot == PCIIO_SLOT_NONE); cf++) { + pcibr_info_t pcibr_info = pcibr_infoh[cf]; + + if (!pcibr_info) + continue; + for (cw = 0; (cw < 6) && (slot == PCIIO_SLOT_NONE); ++cw) { + if (((wx = pcibr_info->f_window[cw].w_space) != PCIIO_SPACE_NONE) && + ((wb = pcibr_info->f_window[cw].w_base) != 0) && + ((ws = pcibr_info->f_window[cw].w_size) != 0) && + ((wl = wb + ws) > wb) && + ((wb <= offset) && (wl > offset))) { + /* MEM, MEM32 and MEM64 need to + * compare as equal ... + */ + if ((wx == space) || + (((wx == PCIIO_SPACE_MEM) || + (wx == PCIIO_SPACE_MEM32) || + (wx == PCIIO_SPACE_MEM64)) && + ((space == PCIIO_SPACE_MEM) || + (space == PCIIO_SPACE_MEM32) || + (space == PCIIO_SPACE_MEM64)))) { + slot = cs; + func = cf; + space = PCIIO_SPACE_WIN(cw); + offset -= wb; + } /* endif window space match */ + } /* endif window valid and addr match */ + } /* next window unless slot set */ + } /* next func unless slot set */ + } /* next slot unless slot set */ + /* XXX- if slot is still -1, no PCI devices are + * decoding here using their standard PCI BASE + * registers. This would be a really good place + * to cross-coordinate with the pciio PCI + * address space allocation routines, to find + * out if this address is "allocated" by any of + * our subsidiary devices. + */ + } + /* Scan all piomap records on this PCI bus to update + * the TimeOut Counters on all matching maps. If we + * don't already know the slot number, take it from + * the first matching piomap. Note that we have to + * compare maps against raw_space and raw_paddr + * since space and offset could already be + * window-relative. + * + * There is a chance that one CPU could update + * through this path, and another CPU could also + * update due to an interrupt. Closing this hole + * would only result in the possibility of some + * errors never getting logged at all, and since the + * use for bp_toc is as a logical test rather than a + * strict count, the excess counts are not a + * problem. + */ + for (cs = 0; cs < 8; ++cs) { + int nf = pcibr_soft->bs_slot[cs].bss_ninfo; + pcibr_info_h pcibr_infoh = pcibr_soft->bs_slot[cs].bss_infos; + + for (cf = 0; cf < nf; cf++) { + pcibr_info_t pcibr_info = pcibr_infoh[cf]; + pcibr_piomap_t map; + + if (!pcibr_info) + continue; + + for (map = pcibr_info->f_piomap; + map != NULL; map = map->bp_next) { + wx = map->bp_space; + wb = map->bp_pciaddr; + ws = map->bp_mapsz; + cw = wx - PCIIO_SPACE_WIN(0); + if (cw < 6) { + wb += pcibr_soft->bs_slot[cs].bss_window[cw].bssw_base; + wx = pcibr_soft->bs_slot[cs].bss_window[cw].bssw_space; + } + if (wx == PCIIO_SPACE_ROM) { + wb += pcibr_info->f_rbase; + wx = PCIIO_SPACE_MEM; + } + if ((wx == PCIIO_SPACE_MEM32) || + (wx == PCIIO_SPACE_MEM64)) + wx = PCIIO_SPACE_MEM; + wl = wb + ws; + if ((wx == raw_space) && (raw_paddr >= wb) && (raw_paddr < wl)) { +#ifdef IRIX + atomicAddInt(map->bp_toc, 1); +#endif + if (slot == PCIIO_SLOT_NONE) { + slot = cs; + space = map->bp_space; + if (cw < 6) + offset -= pcibr_soft->bs_slot[cs].bss_window[cw].bssw_base; + } + } + } + } + } + + if (space != PCIIO_SPACE_NONE) { + if (slot != PCIIO_SLOT_NONE) { +#ifdef IRIX + if (func != PCIIO_FUNC_NONE) + IOERROR_SETVALUE(ioe, widgetdev, + pciio_widgetdev_create(slot,func)); + else + IOERROR_SETVALUE(ioe, widgetdev, + pciio_widgetdev_create(slot,0)); +#else + if (func != PCIIO_FUNC_NONE) { + IOERROR_SETVALUE(ioe, widgetdev, + pciio_widgetdev_create(slot,func)); + } else { + IOERROR_SETVALUE(ioe, widgetdev, + pciio_widgetdev_create(slot,0)); + } +#endif + } + + IOERROR_SETVALUE(ioe, busspace, space); + IOERROR_SETVALUE(ioe, busaddr, offset); + } + if (mode == MODE_DEVPROBE) { + /* + * During probing, we don't really care what the + * error is. Clean up the error in Bridge, notify + * subsidiary devices, and return success. + */ + pcibr_error_cleanup(pcibr_soft, error_code); + + /* if appropriate, give the error handler for this slot + * a shot at this probe access as well. + */ + return (slot == PCIIO_SLOT_NONE) ? IOERROR_HANDLED : + pciio_error_handler(pcibr_vhdl, error_code, mode, ioe); + } + /* + * If we don't know what "PCI SPACE" the access + * was targeting, we may have problems at the + * Bridge itself. Don't touch any bridge registers, + * and do complain loudly. + */ + + if (space == PCIIO_SPACE_NONE) { + printk("XIO Bus Error at %s\n" + "\taccess to XIO bus offset 0x%lx\n" + "\tdoes not correspond to any PCI address\n", + pcibr_soft->bs_name, bad_xaddr); + + /* caller will dump contents of ioe struct */ + return IOERROR_XTALKLEVEL; + } + /* + * Read the PCI Bridge error log registers. + */ + bridge_int_status = bridge->b_int_status; + bridge_pci_err_upper = bridge->b_pci_err_upper; + bridge_pci_err_lower = bridge->b_pci_err_lower; + + bridge_pci_err_addr = + bridge_pci_err_lower + | (((iopaddr_t) bridge_pci_err_upper + & BRIDGE_ERRUPPR_ADDRMASK) << 32); + + /* + * Actual PCI Error handling situation. + * Typically happens when a user level process accesses + * PCI space, and it causes some error. + * + * Due to PCI Bridge implementation, we get two indication + * for a read error: an interrupt and a Bus error. + * We like to handle read error in the bus error context. + * But the interrupt comes and goes before bus error + * could make much progress. (NOTE: interrupd does + * come in _after_ bus error processing starts. But it's + * completed by the time bus error code reaches PCI PIO + * error handling. + * Similarly write error results in just an interrupt, + * and error handling has to be done at interrupt level. + * There is no way to distinguish at interrupt time, if an + * error interrupt is due to read/write error.. + */ + + /* We know the xtalk addr, the raw pci bus space, + * the raw pci bus address, the decoded pci bus + * space, the offset within that space, and the + * decoded pci slot (which may be "PCIIO_SLOT_NONE" if no slot + * is known to be involved). + */ + + /* + * Hand the error off to the handler registered + * for the slot that should have decoded the error, + * or to generic PCI handling (if pciio decides that + * such is appropriate). + */ + retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe); + + if (retval != IOERROR_HANDLED) { + + /* Generate a generic message for IOERROR_UNHANDLED + * since the subsidiary handlers were silent, and + * did no recovery. + */ + if (retval == IOERROR_UNHANDLED) { + retval = IOERROR_PANIC; + + /* we may or may not want to print some of this, + * depending on debug level and which error code. + */ + + PRINT_ALERT( + "PIO Error on PCI Bus %s", + pcibr_soft->bs_name); + /* this decodes part of the ioe; our caller + * will dump the raw details in DEBUG and + * kdebug kernels. + */ + BEM_ADD_IOE(ioe); + } +#if defined(FORCE_ERRORS) + if (0) { +#elif !DEBUG + if (kdebug) { +#endif + /* + * dump raw data from bridge + */ + + BEM_ADD_STR("DEBUG DATA -- raw info from Bridge ASIC:\n"); + BEM_ADD_REG(bridge_int_status); + BEM_ADD_VAR(bridge_pci_err_upper); + BEM_ADD_VAR(bridge_pci_err_lower); + BEM_ADD_VAR(bridge_pci_err_addr); + BEM_ADD_SPC(raw_space); + BEM_ADD_VAR(raw_paddr); + if (IOERROR_FIELDVALID(ioe, widgetdev)) { + +#ifdef colin + slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, + widgetdev)); + func = pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, + widgetdev)); +#else + slot = -1; + func = -1; +#endif + if (slot < 8) { +#ifdef SUPPORT_SGI_CMN_ERR_STUFF + bridgereg_t device = bridge->b_device[slot].reg; +#endif + + BEM_ADD_VAR(slot); + BEM_ADD_VAR(func); + BEM_ADD_REG(device); + } + } +#if !DEBUG || defined(FORCE_ERRORS) + } +#endif + + /* + * Since error could not be handled at lower level, + * error data logged has not been cleared. + * Clean up errors, and + * re-enable bridge to interrupt on error conditions. + * NOTE: Wheather we get the interrupt on PCI_ABORT or not is + * dependent on INT_ENABLE register. This write just makes sure + * that if the interrupt was enabled, we do get the interrupt. + * + * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges + * a group of interrupts. If while handling this error, + * some other error has occured, that would be + * implicitly cleared by this write. + * Need a way to ensure we don't inadvertently clear some + * other errors. + */ +#ifdef IRIX + if (IOERROR_FIELDVALID(ioe, widgetdev)) + pcibr_device_disable(pcibr_soft, + pciio_widgetdev_slot_get( + IOERROR_GETVALUE(ioe, widgetdev))); +#endif + + if (mode == MODE_DEVUSERERROR) + pcibr_error_cleanup(pcibr_soft, error_code); + } + return retval; +} + +/* + * bridge_dmaerror + * Some error was identified in a DMA transaction. + * This routine will identify the that caused the error, + * and try to invoke the appropriate bus service to handle this. + */ + +#define BRIDGE_DMA_READ_ERROR (BRIDGE_ISR_RESP_XTLK_ERR|BRIDGE_ISR_XREAD_REQ_TIMEOUT) + +int +pcibr_dmard_error( + pcibr_soft_t pcibr_soft, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioe) +{ + devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t bus_lowaddr, bus_uppraddr; + int retval = 0; + int bufnum; + + /* + * In case of DMA errors, bridge should have logged the + * address that caused the error. + * Look up the address, in the bridge error registers, and + * take appropriate action + */ +#ifdef colin + ASSERT(IOERROR_GETVALUE(ioe, widgetnum) == pcibr_soft->bs_xid); + ASSERT(bridge); +#endif + + /* + * read error log registers + */ + bus_lowaddr = bridge->b_wid_resp_lower; + bus_uppraddr = bridge->b_wid_resp_upper; + + bufnum = BRIDGE_RESP_ERRUPPR_BUFNUM(bus_uppraddr); + IOERROR_SETVALUE(ioe, widgetdev, + pciio_widgetdev_create( + BRIDGE_RESP_ERRUPPR_DEVICE(bus_uppraddr), + 0)); + IOERROR_SETVALUE(ioe, busaddr, + (bus_lowaddr | + ((iopaddr_t) + (bus_uppraddr & + BRIDGE_ERRUPPR_ADDRMASK) << 32))); + + /* + * need to ensure that the xtalk adress in ioe + * maps to PCI error address read from bridge. + * How to convert PCI address back to Xtalk address ? + * (better idea: convert XTalk address to PCI address + * and then do the compare!) + */ + + retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe); + if (retval != IOERROR_HANDLED) +#ifdef colin + pcibr_device_disable(pcibr_soft, + pciio_widgetdev_slot_get( + IOERROR_GETVALUE(ioe,widgetdev))); +#else + pcibr_device_disable(pcibr_soft, + pciio_widgetdev_slot_get(-1)); +#endif + + /* + * Re-enable bridge to interrupt on BRIDGE_IRR_RESP_BUF_GRP_CLR + * NOTE: Wheather we get the interrupt on BRIDGE_IRR_RESP_BUF_GRP_CLR or + * not is dependent on INT_ENABLE register. This write just makes sure + * that if the interrupt was enabled, we do get the interrupt. + */ + bridge->b_int_rst_stat = BRIDGE_IRR_RESP_BUF_GRP_CLR; + + /* + * Also, release the "bufnum" back to buffer pool that could be re-used. + * This is done by "disabling" the buffer for a moment, then restoring + * the original assignment. + */ + + { + reg_p regp; + bridgereg_t regv; + bridgereg_t mask; + + regp = (bufnum & 1) + ? &bridge->b_odd_resp + : &bridge->b_even_resp; + + mask = 0xF << ((bufnum >> 1) * 4); + + regv = *regp; + *regp = regv & ~mask; + *regp = regv; + } + + return retval; +} + +/* + * pcibr_dmawr_error: + * Handle a dma write error caused by a device attached to this bridge. + * + * ioe has the widgetnum, widgetdev, and memaddr fields updated + * But we don't know the PCI address that corresponds to "memaddr" + * nor do we know which device driver is generating this address. + * + * There is no easy way to find out the PCI address(es) that map + * to a specific system memory address. Bus handling code is also + * of not much help, since they don't keep track of the DMA mapping + * that have been handed out. + * So it's a dead-end at this time. + * + * If translation is available, we could invoke the error handling + * interface of the device driver. + */ +/*ARGSUSED */ +int +pcibr_dmawr_error( + pcibr_soft_t pcibr_soft, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioe) +{ + devfs_handle_t pcibr_vhdl = pcibr_soft->bs_vhdl; + int retval; + + retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe); + +#ifdef IRIX + if (retval != IOERROR_HANDLED) { + pcibr_device_disable(pcibr_soft, + pciio_widgetdev_slot_get( + IOERROR_GETVALUE(ioe, widgetdev))); + + } +#endif + return retval; +} + +/* + * Bridge error handler. + * Interface to handle all errors that involve bridge in some way. + * + * This normally gets called from xtalk error handler. + * ioe has different set of fields set depending on the error that + * was encountered. So, we have a bit field indicating which of the + * fields are valid. + * + * NOTE: This routine could be operating in interrupt context. So, + * don't try to sleep here (till interrupt threads work!!) + */ +LOCAL int +pcibr_error_handler( + error_handler_arg_t einfo, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioe) +{ + pcibr_soft_t pcibr_soft; + int retval = IOERROR_BADERRORCODE; + devfs_handle_t xconn_vhdl,pcibr_vhdl; +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + error_state_t e_state; +#endif + pcibr_soft = (pcibr_soft_t) einfo; + + xconn_vhdl = pcibr_soft->bs_conn; + pcibr_vhdl = pcibr_soft->bs_vhdl; + +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + e_state = error_state_get(xconn_vhdl); + + if (error_state_set(pcibr_vhdl, e_state) == + ERROR_RETURN_CODE_CANNOT_SET_STATE) + return(IOERROR_UNHANDLED); +#endif + + /* If we are in the action handling phase clean out the error state + * on the xswitch. + */ +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + if (e_state == ERROR_STATE_ACTION) + (void)error_state_set(xconn_vhdl, ERROR_STATE_NONE); +#endif + +#if DEBUG && ERROR_DEBUG + printk("%s: pcibr_error_handler\n", pcibr_soft->bs_name); +#endif + + ASSERT(pcibr_soft != NULL); + + if (error_code & IOECODE_PIO) + retval = pcibr_pioerror(pcibr_soft, error_code, mode, ioe); + + if (error_code & IOECODE_DMA) { + if (error_code & IOECODE_READ) { + /* + * DMA read error occurs when a device attached to the bridge + * tries to read some data from system memory, and this + * either results in a timeout or access error. + * First case is indicated by the bit "XREAD_REQ_TOUT" + * and second case by "RESP_XTALK_ERROR" bit in bridge error + * interrupt status register. + * + * pcibr_error_intr_handler would get invoked first, and it has + * the responsibility of calling pcibr_error_handler with + * suitable parameters. + */ + + retval = pcibr_dmard_error(pcibr_soft, error_code, MODE_DEVERROR, ioe); + } + if (error_code & IOECODE_WRITE) { + /* + * A device attached to this bridge has been generating + * bad DMA writes. Find out the device attached, and + * slap on it's wrist. + */ + + retval = pcibr_dmawr_error(pcibr_soft, error_code, MODE_DEVERROR, ioe); + } + } + return retval; + +} + +/* + * Reenable a device after handling the error. + * This is called by the lower layers when they wish to be reenabled + * after an error. + * Note that each layer would be calling the previous layer to reenable + * first, before going ahead with their own re-enabling. + */ + +int +pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + + ASSERT(error_code & IOECODE_PIO); + + /* If the error is not known to be a write, + * we have to call devenable. + * write errors are isolated to the bridge. + */ + if (!(error_code & IOECODE_WRITE)) { + devfs_handle_t xconn_vhdl = pcibr_soft->bs_conn; + int rc; + + rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code); + if (rc != IOERROR_HANDLED) + return rc; + } + pcibr_error_cleanup(pcibr_soft, error_code); + return IOERROR_HANDLED; +} + +/* ===================================================================== + * CONFIGURATION MANAGEMENT + */ +/*ARGSUSED */ +void +pcibr_provider_startup(devfs_handle_t pcibr) +{ +} + +/*ARGSUSED */ +void +pcibr_provider_shutdown(devfs_handle_t pcibr) +{ +} + +int +pcibr_reset(devfs_handle_t conn) +{ + pciio_info_t pciio_info = pciio_info_get(conn); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridge_t *bridge = pcibr_soft->bs_base; + bridgereg_t ctlreg; + unsigned cfgctl[8]; + unsigned s; + int f, nf; + pcibr_info_h pcibr_infoh; + pcibr_info_t pcibr_info; + int win; + + if (pcibr_soft->bs_slot[pciio_slot].has_host) { + pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot; + pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0]; + } + if (pciio_slot < 4) { + s = pcibr_lock(pcibr_soft); + nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo; + pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos; + for (f = 0; f < nf; ++f) + if (pcibr_infoh[f]) + cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4]; + + ctlreg = bridge->b_wid_control; + bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot); + /* XXX delay? */ + bridge->b_wid_control = ctlreg; + /* XXX delay? */ + + for (f = 0; f < nf; ++f) +#ifdef IRIX + if (pcibr_info = pcibr_infoh[f]) +#else + if ((pcibr_info = pcibr_infoh[f])) +#endif + for (win = 0; win < 6; ++win) + if (pcibr_info->f_window[win].w_base != 0) + bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] = + pcibr_info->f_window[win].w_base; + for (f = 0; f < nf; ++f) + if (pcibr_infoh[f]) + bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f]; + pcibr_unlock(pcibr_soft, s); + + return 0; + } +#ifdef SUPPORT_PRINTING_V_FORMAT + PRINT_WARNING( "%v: pcibr_reset unimplemented for slot %d\n", + conn, pciio_slot); +#endif + return -1; +} + +pciio_endian_t +pcibr_endian_set(devfs_handle_t pconn_vhdl, + pciio_endian_t device_end, + pciio_endian_t desired_end) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridgereg_t devreg; + unsigned s; + + /* + * Bridge supports hardware swapping; so we can always + * arrange for the caller's desired endianness. + */ + + s = pcibr_lock(pcibr_soft); + devreg = pcibr_soft->bs_slot[pciio_slot].bss_device; + if (device_end != desired_end) + devreg |= BRIDGE_DEV_SWAP_BITS; + else + devreg &= ~BRIDGE_DEV_SWAP_BITS; + + /* NOTE- if we ever put SWAP bits + * onto the disabled list, we will + * have to change the logic here. + */ + if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) { + bridge_t *bridge = pcibr_soft->bs_base; + + bridge->b_device[pciio_slot].reg = devreg; + pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + } + pcibr_unlock(pcibr_soft, s); + +#if DEBUG && PCIBR_DEV_DEBUG + printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg); +#endif + + return desired_end; +} + +/* This (re)sets the GBR and REALTIME bits and also keeps track of how + * many sets are outstanding. Reset succeeds only if the number of outstanding + * sets == 1. + */ +int +pcibr_priority_bits_set(pcibr_soft_t pcibr_soft, + pciio_slot_t pciio_slot, + pciio_priority_t device_prio) +{ + int s; + int *counter; + bridgereg_t rtbits = 0; + bridgereg_t devreg; + int rc = PRIO_SUCCESS; + + /* in dual-slot configurations, the host and the + * guest have separate DMA resources, so they + * have separate requirements for priority bits. + */ + + counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr); + + /* + * Bridge supports PCI notions of LOW and HIGH priority + * arbitration rings via a "REAL_TIME" bit in the per-device + * Bridge register. The "GBR" bit controls access to the GBR + * ring on the xbow. These two bits are (re)set together. + * + * XXX- Bug in Rev B Bridge Si: + * Symptom: Prefetcher starts operating incorrectly. This happens + * due to corruption of the address storage ram in the prefetcher + * when a non-real time pci request is pulled and a real-time one is + * put in it's place. Workaround: Use only a single arbitration ring + * on pci bus. GBR and RR can still be uniquely used per + * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C. + */ + + if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B) + rtbits |= BRIDGE_DEV_RT; + + /* NOTE- if we ever put DEV_RT or DEV_GBR on + * the disabled list, we will have to take + * it into account here. + */ + + s = pcibr_lock(pcibr_soft); + devreg = pcibr_soft->bs_slot[pciio_slot].bss_device; + if (device_prio == PCI_PRIO_HIGH) { +#ifdef IRIX + if (++*counter == 1) +#else + if ((++*counter == 1)) { +#endif + if (rtbits) + devreg |= rtbits; + else + rc = PRIO_FAIL; +#ifndef IRIX + } +#endif + } else if (device_prio == PCI_PRIO_LOW) { + if (*counter <= 0) + rc = PRIO_FAIL; + else if (--*counter == 0) + if (rtbits) + devreg &= ~rtbits; + } + if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) { + bridge_t *bridge = pcibr_soft->bs_base; + + bridge->b_device[pciio_slot].reg = devreg; + pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + } + pcibr_unlock(pcibr_soft, s); + + return rc; +} + +pciio_priority_t +pcibr_priority_set(devfs_handle_t pconn_vhdl, + pciio_priority_t device_prio) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + + (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio); + + return device_prio; +} + +/* + * Interfaces to allow special (e.g. SGI) drivers to set/clear + * Bridge-specific device flags. Many flags are modified through + * PCI-generic interfaces; we don't allow them to be directly + * manipulated here. Only flags that at this point seem pretty + * Bridge-specific can be set through these special interfaces. + * We may add more flags as the need arises, or remove flags and + * create PCI-generic interfaces as the need arises. + * + * Returns 0 on failure, 1 on success + */ +int +pcibr_device_flags_set(devfs_handle_t pconn_vhdl, + pcibr_device_flags_t flags) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + bridgereg_t set = 0; + bridgereg_t clr = 0; + + ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags); + + if (flags & PCIBR_WRITE_GATHER) + set |= BRIDGE_DEV_PMU_WRGA_EN; + if (flags & PCIBR_NOWRITE_GATHER) + clr |= BRIDGE_DEV_PMU_WRGA_EN; + + if (flags & PCIBR_WRITE_GATHER) + set |= BRIDGE_DEV_DIR_WRGA_EN; + if (flags & PCIBR_NOWRITE_GATHER) + clr |= BRIDGE_DEV_DIR_WRGA_EN; + + if (flags & PCIBR_PREFETCH) + set |= BRIDGE_DEV_PREF; + if (flags & PCIBR_NOPREFETCH) + clr |= BRIDGE_DEV_PREF; + + if (flags & PCIBR_PRECISE) + set |= BRIDGE_DEV_PRECISE; + if (flags & PCIBR_NOPRECISE) + clr |= BRIDGE_DEV_PRECISE; + + if (flags & PCIBR_BARRIER) + set |= BRIDGE_DEV_BARRIER; + if (flags & PCIBR_NOBARRIER) + clr |= BRIDGE_DEV_BARRIER; + + if (flags & PCIBR_64BIT) + set |= BRIDGE_DEV_DEV_SIZE; + if (flags & PCIBR_NO64BIT) + clr |= BRIDGE_DEV_DEV_SIZE; + + if (set || clr) { + bridgereg_t devreg; + unsigned s; + + s = pcibr_lock(pcibr_soft); + devreg = pcibr_soft->bs_slot[pciio_slot].bss_device; +#ifdef IRIX + devreg = devreg & ~clr | set; +#else + devreg = (devreg & ~clr) | set; +#endif + if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) { + bridge_t *bridge = pcibr_soft->bs_base; + + bridge->b_device[pciio_slot].reg = devreg; + pcibr_soft->bs_slot[pciio_slot].bss_device = devreg; + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + } + pcibr_unlock(pcibr_soft, s); +#if DEBUG && PCIBR_DEV_DEBUG + printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits); +#endif + } + return (1); +} + +#ifdef LITTLE_ENDIAN +/* + * on sn-ia we need to twiddle the the addresses going out + * the pci bus because we use the unswizzled synergy space + * (the alternative is to use the swizzled synergy space + * and byte swap the data) + */ +#define CB(b,r) (((volatile uint8_t *) b)[((r)^4)]) +#define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)]) +#define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)]) +#else +#define CB(b,r) (((volatile uint8_t *) cfgbase)[(r)^3]) +#define CS(b,r) (((volatile uint16_t *) cfgbase)[((r)/2)^1]) +#define CW(b,r) (((volatile uint32_t *) cfgbase)[(r)/4]) +#endif /* LITTLE_ENDIAN */ + + +LOCAL cfg_p +pcibr_config_addr(devfs_handle_t conn, + unsigned reg) +{ + pcibr_info_t pcibr_info; + pciio_slot_t pciio_slot; + pciio_function_t pciio_func; + pcibr_soft_t pcibr_soft; + bridge_t *bridge; + cfg_p cfgbase = (cfg_p)0; + + pcibr_info = pcibr_info_get(conn); + + pciio_slot = pcibr_info->f_slot; + if (pciio_slot == PCIIO_SLOT_NONE) + pciio_slot = PCI_TYPE1_SLOT(reg); + + pciio_func = pcibr_info->f_func; + if (pciio_func == PCIIO_FUNC_NONE) + pciio_func = PCI_TYPE1_FUNC(reg); + + pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast; + + if ( (pcibr_soft_t)0 != pcibr_soft ) { + bridge = pcibr_soft->bs_base; + if ( (bridge_t *)0 != bridge ) { + cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l; + } + } + + + return cfgbase; +} + +uint64_t +pcibr_config_get(devfs_handle_t conn, + unsigned reg, + unsigned size) +{ + return do_pcibr_config_get(pcibr_config_addr(conn, reg), + PCI_TYPE1_REG(reg), size); +} + +LOCAL uint64_t +do_pcibr_config_get( + cfg_p cfgbase, + unsigned reg, + unsigned size) +{ + unsigned value; + + + value = CW(cfgbase, reg); + + if (reg & 3) + value >>= 8 * (reg & 3); + if (size < 4) + value &= (1 << (8 * size)) - 1; + + return value; +} + +void +pcibr_config_set(devfs_handle_t conn, + unsigned reg, + unsigned size, + uint64_t value) +{ + do_pcibr_config_set(pcibr_config_addr(conn, reg), + PCI_TYPE1_REG(reg), size, value); +} + +LOCAL void +do_pcibr_config_set(cfg_p cfgbase, + unsigned reg, + unsigned size, + uint64_t value) +{ + switch (size) { + case 1: + CB(cfgbase, reg) = value; + break; + case 2: + if (reg & 1) { + CB(cfgbase, reg) = value; + CB(cfgbase, reg + 1) = value >> 8; + } else + CS(cfgbase, reg) = value; + break; + case 3: + if (reg & 1) { + CB(cfgbase, reg) = value; + CS(cfgbase, reg + 1) = value >> 8; + } else { + CS(cfgbase, reg) = value; + CB(cfgbase, reg + 2) = value >> 16; + } + break; + + case 4: + CW(cfgbase, reg) = value; + break; + } +} + +pciio_provider_t pcibr_provider = +{ + (pciio_piomap_alloc_f *) pcibr_piomap_alloc, + (pciio_piomap_free_f *) pcibr_piomap_free, + (pciio_piomap_addr_f *) pcibr_piomap_addr, + (pciio_piomap_done_f *) pcibr_piomap_done, + (pciio_piotrans_addr_f *) pcibr_piotrans_addr, + (pciio_piospace_alloc_f *) pcibr_piospace_alloc, + (pciio_piospace_free_f *) pcibr_piospace_free, + + (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc, + (pciio_dmamap_free_f *) pcibr_dmamap_free, + (pciio_dmamap_addr_f *) pcibr_dmamap_addr, + (pciio_dmamap_list_f *) pcibr_dmamap_list, + (pciio_dmamap_done_f *) pcibr_dmamap_done, + (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr, + (pciio_dmatrans_list_f *) pcibr_dmatrans_list, + (pciio_dmamap_drain_f *) pcibr_dmamap_drain, + (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain, + (pciio_dmalist_drain_f *) pcibr_dmalist_drain, + + (pciio_intr_alloc_f *) pcibr_intr_alloc, + (pciio_intr_free_f *) pcibr_intr_free, + (pciio_intr_connect_f *) pcibr_intr_connect, + (pciio_intr_disconnect_f *) pcibr_intr_disconnect, + (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get, + + (pciio_provider_startup_f *) pcibr_provider_startup, + (pciio_provider_shutdown_f *) pcibr_provider_shutdown, + (pciio_reset_f *) pcibr_reset, + (pciio_write_gather_flush_f *) pcibr_write_gather_flush, + (pciio_endian_set_f *) pcibr_endian_set, + (pciio_priority_set_f *) pcibr_priority_set, + (pciio_config_get_f *) pcibr_config_get, + (pciio_config_set_f *) pcibr_config_set, + + (pciio_error_devenable_f *) pcibr_error_devenable, + (pciio_error_extract_f *) pcibr_error_extract, +}; + +LOCAL pcibr_hints_t +pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc) +{ + arbitrary_info_t ainfo = 0; + graph_error_t rv; + pcibr_hints_t hint; + + rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo); + + if (alloc && (rv != GRAPH_SUCCESS)) { + + NEW(hint); + hint->rrb_alloc_funct = NULL; + hint->ph_intr_bits = NULL; + rv = hwgraph_info_add_LBL(xconn_vhdl, + INFO_LBL_PCIBR_HINTS, + (arbitrary_info_t) hint); + if (rv != GRAPH_SUCCESS) + goto abnormal_exit; + + rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo); + + if (rv != GRAPH_SUCCESS) + goto abnormal_exit; + + if (ainfo != (arbitrary_info_t) hint) + goto abnormal_exit; + } + return (pcibr_hints_t) ainfo; + +abnormal_exit: +#ifdef IRIX + printf("SHOULD NOT BE HERE\n"); +#endif + DEL(hint); + return(NULL); + +} + +void +pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask) +{ + pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); + + if (hint) + hint->ph_rrb_fixed = mask; +#if DEBUG + else + printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n" + "\t%p\n", xconn_vhdl); +#endif +} + +void +pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl) +{ + pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF); +} + +void +pcibr_hints_dualslot(devfs_handle_t xconn_vhdl, + pciio_slot_t host, + pciio_slot_t guest) +{ + pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); + + if (hint) + hint->ph_host_slot[guest] = host + 1; +#if DEBUG + else + printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n" + "\t%p\n", xconn_vhdl); +#endif +} + +void +pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl, + pcibr_intr_bits_f *xxx_intr_bits) +{ + pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); + + if (hint) + hint->ph_intr_bits = xxx_intr_bits; +#if DEBUG + else + printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n" + "\t%p\n", xconn_vhdl); +#endif +} + +void +pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct) +{ + pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); + + if (hint) + hint->rrb_alloc_funct = rrb_alloc_funct; +} + +void +pcibr_hints_handsoff(devfs_handle_t xconn_vhdl) +{ + pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1); + + if (hint) + hint->ph_hands_off = 1; +#if DEBUG + else + printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n" + "\t%p\n", xconn_vhdl); +#endif +} + +void +pcibr_hints_subdevs(devfs_handle_t xconn_vhdl, + pciio_slot_t slot, + uint64_t subdevs) +{ + arbitrary_info_t ainfo = 0; + char sdname[16]; + devfs_handle_t pconn_vhdl = GRAPH_VERTEX_NONE; + + sprintf(sdname, "pci/%d", slot); + (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl); + if (pconn_vhdl == GRAPH_VERTEX_NONE) { +#if DEBUG + printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n" + "\t%p (seeking %s)\n", xconn_vhdl, sdname); +#endif + return; + } + hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo); + if (ainfo == 0) { + uint64_t *subdevp; + + NEW(subdevp); + if (!subdevp) { +#if DEBUG + printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n" + "\t%p\n", pconn_vhdl); +#endif + return; + } + *subdevp = subdevs; + hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp); + hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo); + if (ainfo == (arbitrary_info_t) subdevp) + return; + DEL(subdevp); +#ifdef IRIX + if (ainfo == NULL) +#else + if (ainfo == (arbitrary_info_t) NULL) +#endif + { +#if DEBUG + printk("pcibr_hints_subdevs: null subdevs ptr at\n" + "\t%p\n", pconn_vhdl); +#endif + return; + } +#if DEBUG + printk("pcibr_subdevs_get: dup subdev add_LBL at\n" + "\t%p\n", pconn_vhdl); +#endif + } + *(uint64_t *) ainfo = subdevs; +} + + +#ifdef colin + +#include +#include + +char *pci_space[] = {"NONE", + "ROM", + "IO", + "", + "MEM", + "MEM32", + "MEM64", + "CFG", + "WIN0", + "WIN1", + "WIN2", + "WIN3", + "WIN4", + "WIN5", + "", + "BAD"}; + +void +idbg_pss_func(pcibr_info_h pcibr_infoh, int func) +{ + pcibr_info_t pcibr_info = pcibr_infoh[func]; + char name[MAXDEVNAME]; + int win; + + if (!pcibr_info) + return; + qprintf("Per-slot Function Info\n"); +#ifdef SUPPORT_PRINTING_V_FORMAT + sprintf(name, "%v", pcibr_info->f_vertex); +#endif + qprintf("\tSlot Name : %s\n",name); + qprintf("\tPCI Bus : %d ",pcibr_info->f_bus); + qprintf("Slot : %d ", pcibr_info->f_slot); + qprintf("Function : %d ", pcibr_info->f_func); + qprintf("VendorId : 0x%x " , pcibr_info->f_vendor); + qprintf("DeviceId : 0x%x\n", pcibr_info->f_device); +#ifdef SUPPORT_PRINTING_V_FORMAT + sprintf(name, "%v", pcibr_info->f_master); +#endif + qprintf("\tBus provider : %s\n",name); + qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops); + qprintf("Error Handler : 0x%x Arg 0x%x\n", + pcibr_info->f_efunc,pcibr_info->f_einfo); + for(win = 0 ; win < 6 ; win++) + qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n", + win,pci_space[pcibr_info->f_window[win].w_space], + pcibr_info->f_window[win].w_base, + pcibr_info->f_window[win].w_size); + + qprintf("\tRom base 0x%x size 0x%x\n", + pcibr_info->f_rbase,pcibr_info->f_rsize); + + qprintf("\tInterrupt Bit Map\n"); + qprintf("\t\tPCI Int#\tBridge Pin#\n"); + for (win = 0 ; win < 4; win++) + qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]); + qprintf("\n"); +} + + +void +idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot) +{ + pcibr_soft_slot_t pss; + char slot_conn_name[MAXDEVNAME]; + int func; + + pss = &pcibr_soft->bs_slot[slot]; + qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot); + qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no"); + qprintf("\tHost Slot : %d\n",pss->host_slot); + sprintf(slot_conn_name, "%v", pss->slot_conn); + qprintf("\tSlot Conn : %s\n",slot_conn_name); + qprintf("\t#Functions : %d\n",pss->bss_ninfo); + for (func = 0; func < pss->bss_ninfo; func++) + idbg_pss_func(pss->bss_infos,func); + qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]); + qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base); + qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device); + qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n", + pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr); + + qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x" + "d32_base 0x%x d32_flags 0x%x\n", + pss->bss_d64_base, pss->bss_d64_flags, + pss->bss_d32_base, pss->bss_d32_flags); + + qprintf("\tExt ATEs active ? %s", + pss->bss_ext_ates_active ? "yes" : "no"); + qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer); + qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow); + + qprintf("\tRRB Info : Valid %d+%d Reserved %d\n", + pcibr_soft->bs_rrb_valid[slot], + pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL], + pcibr_soft->bs_rrb_res[slot]); + +} + +int ips = 0; + +void +idbg_pss(pcibr_soft_t pcibr_soft) +{ + pciio_slot_t slot; + + + if (ips >= 0 && ips < 8) + idbg_pss_info(pcibr_soft,ips); + else if (ips < 0) + for (slot = 0; slot < 8; slot++) + idbg_pss_info(pcibr_soft,slot); + else + qprintf("Invalid ips %d\n",ips); +} + +#endif /* colin */ + +int +pcibr_dma_enabled(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info); + + + return xtalk_dma_enabled(pcibr_soft->bs_conn); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/pciio.c linux-2.4.0-test12-lia/arch/ia64/sn/io/pciio.c --- linux-2.4.0-test12/arch/ia64/sn/io/pciio.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/pciio.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,1562 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#define USRPCI 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_PCIIO +#undef DEBUG_PCIIO /* turn this on for yet more console output */ + + +#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) +#define DEL(ptr) (kfree(ptr)) + +char pciio_info_fingerprint[] = "pciio_info"; + +cdl_p pciio_registry = NULL; + +int +badaddr_val(volatile void *addr, int len, volatile void *ptr) +{ + switch (len) { + case 4: *(volatile u32*)ptr = *(((volatile u32*)(((u64) addr)^4))); + default: printk("FIXME: argh fix badaddr_val\n"); + } + /* no such thing as a bad addr .... */ + return(0); +} + + +void +cmn_err_tag(int seqnumber, register int level, char *fmt, ...) +{ +} + +nasid_t +get_console_nasid(void) +{ +#ifdef IRIX + return console_nasid; +#else + return 0; +#endif +} + +int +hub_dma_enabled(devfs_handle_t xconn_vhdl) +{ + return(0); +} + +int +hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) +{ + return(0); +} + +void +ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror) +{ +} + +/****** + ****** end hack defines ...... + ******/ + + + + +/* ===================================================================== + * PCI Generic Bus Provider + * Implement PCI provider operations. The pciio* layer provides a + * platform-independent interface for PCI devices. This layer + * switches among the possible implementations of a PCI adapter. + */ + +/* ===================================================================== + * Provider Function Location SHORTCUT + * + * On platforms with only one possible PCI provider, macros can be + * set up at the top that cause the table lookups and indirections to + * completely disappear. + */ + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +/* + * For the moment, we will assume that IP27 + * only use Bridge ASICs to provide PCI support. + */ +#include +#define DEV_FUNC(dev,func) pcibr_##func +#define CAST_PIOMAP(x) ((pcibr_piomap_t)(x)) +#define CAST_DMAMAP(x) ((pcibr_dmamap_t)(x)) +#define CAST_INTR(x) ((pcibr_intr_t)(x)) +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + +/* ===================================================================== + * Function Table of Contents + */ + +#if !defined(DEV_FUNC) +static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev); +#endif + +pciio_piomap_t pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned); +void pciio_piomap_free(pciio_piomap_t); +caddr_t pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t); + +void pciio_piomap_done(pciio_piomap_t); +caddr_t pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned); +caddr_t pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned); + +iopaddr_t pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t); +void pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t); + +pciio_dmamap_t pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +void pciio_dmamap_free(pciio_dmamap_t); +iopaddr_t pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t); +alenlist_t pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned); +void pciio_dmamap_done(pciio_dmamap_t); +iopaddr_t pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); +alenlist_t pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +void pciio_dmamap_drain(pciio_dmamap_t); +void pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t); +void pciio_dmalist_drain(devfs_handle_t, alenlist_t); +iopaddr_t pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned); + +pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +void pciio_intr_free(pciio_intr_t); +int pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t, void *thread); +void pciio_intr_disconnect(pciio_intr_t); +devfs_handle_t pciio_intr_cpu_get(pciio_intr_t); + +void pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t); +static pciio_info_t pciio_cardinfo_get(devfs_handle_t, pciio_slot_t); +int pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); +int pciio_error_devenable(devfs_handle_t, int); + +void pciio_provider_startup(devfs_handle_t); +void pciio_provider_shutdown(devfs_handle_t); + +pciio_endian_t pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t); +pciio_priority_t pciio_priority_set(devfs_handle_t, pciio_priority_t); +devfs_handle_t pciio_intr_dev_get(pciio_intr_t); + +devfs_handle_t pciio_pio_dev_get(pciio_piomap_t); +pciio_slot_t pciio_pio_slot_get(pciio_piomap_t); +pciio_space_t pciio_pio_space_get(pciio_piomap_t); +iopaddr_t pciio_pio_pciaddr_get(pciio_piomap_t); +ulong pciio_pio_mapsz_get(pciio_piomap_t); +caddr_t pciio_pio_kvaddr_get(pciio_piomap_t); + +devfs_handle_t pciio_dma_dev_get(pciio_dmamap_t); +pciio_slot_t pciio_dma_slot_get(pciio_dmamap_t); + +pciio_info_t pciio_info_chk(devfs_handle_t); +pciio_info_t pciio_info_get(devfs_handle_t); +void pciio_info_set(devfs_handle_t, pciio_info_t); +devfs_handle_t pciio_info_dev_get(pciio_info_t); +pciio_slot_t pciio_info_slot_get(pciio_info_t); +pciio_function_t pciio_info_function_get(pciio_info_t); +pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t); +pciio_device_id_t pciio_info_device_id_get(pciio_info_t); +devfs_handle_t pciio_info_master_get(pciio_info_t); +arbitrary_info_t pciio_info_mfast_get(pciio_info_t); +pciio_provider_t *pciio_info_pops_get(pciio_info_t); +error_handler_f *pciio_info_efunc_get(pciio_info_t); +error_handler_arg_t *pciio_info_einfo_get(pciio_info_t); +pciio_space_t pciio_info_bar_space_get(pciio_info_t, int); +iopaddr_t pciio_info_bar_base_get(pciio_info_t, int); +size_t pciio_info_bar_size_get(pciio_info_t, int); +iopaddr_t pciio_info_rom_base_get(pciio_info_t); +size_t pciio_info_rom_size_get(pciio_info_t); + +void pciio_init(void); +int pciio_attach(devfs_handle_t); + +void pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns); +void pciio_provider_unregister(devfs_handle_t); +pciio_provider_t *pciio_provider_fns_get(devfs_handle_t); + +int pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned); +void pciio_driver_unregister(char *driver_prefix); + +devfs_handle_t pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); + +void pciio_device_unregister(devfs_handle_t); +pciio_info_t pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t); +void pciio_device_info_free(pciio_info_t); +devfs_handle_t pciio_device_info_register(devfs_handle_t, pciio_info_t); +void pciio_device_info_unregister(devfs_handle_t, pciio_info_t); +int pciio_device_attach(devfs_handle_t); +int pciio_device_detach(devfs_handle_t); +void pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t); + +int pciio_reset(devfs_handle_t); +int pciio_write_gather_flush(devfs_handle_t); +int pciio_slot_inuse(devfs_handle_t); + +/* ===================================================================== + * Provider Function Location + * + * If there is more than one possible provider for + * this platform, we need to examine the master + * vertex of the current vertex for a provider + * function structure, and indirect through the + * appropriately named member. + */ + +#if !defined(DEV_FUNC) + +static pciio_provider_t * +pciio_to_provider_fns(devfs_handle_t dev) +{ + pciio_info_t card_info; + pciio_provider_t *provider_fns; + + card_info = pciio_info_get(dev); + ASSERT(card_info != NULL); + + provider_fns = pciio_info_pops_get(card_info); + ASSERT(provider_fns != NULL); + + return (provider_fns); +} + +#define DEV_FUNC(dev,func) pciio_to_provider_fns(dev)->func +#define CAST_PIOMAP(x) ((pciio_piomap_t)(x)) +#define CAST_DMAMAP(x) ((pciio_dmamap_t)(x)) +#define CAST_INTR(x) ((pciio_intr_t)(x)) +#endif + +/* + * Many functions are not passed their vertex + * information directly; rather, they must + * dive through a resource map. These macros + * are available to coordinate this detail. + */ +#define PIOMAP_FUNC(map,func) DEV_FUNC((map)->pp_dev,func) +#define DMAMAP_FUNC(map,func) DEV_FUNC((map)->pd_dev,func) +#define INTR_FUNC(intr_hdl,func) DEV_FUNC((intr_hdl)->pi_dev,func) + +/* ===================================================================== + * PIO MANAGEMENT + * + * For mapping system virtual address space to + * pciio space on a specified card + */ + +pciio_piomap_t +pciio_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ + iopaddr_t addr, /* lowest address (or offset in window) */ + size_t byte_count, /* size of region containing our mappings */ + size_t byte_count_max, /* maximum size of a mapping */ + unsigned flags) +{ /* defined in sys/pio.h */ + return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc) + (dev, dev_desc, space, addr, byte_count, byte_count_max, flags); +} + +void +pciio_piomap_free(pciio_piomap_t pciio_piomap) +{ + PIOMAP_FUNC(pciio_piomap, piomap_free) + (CAST_PIOMAP(pciio_piomap)); +} + +caddr_t +pciio_piomap_addr(pciio_piomap_t pciio_piomap, /* mapping resources */ + iopaddr_t pciio_addr, /* map for this pciio address */ + size_t byte_count) +{ /* map this many bytes */ + pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr) + (CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count); + + return pciio_piomap->pp_kvaddr; +} + +void +pciio_piomap_done(pciio_piomap_t pciio_piomap) +{ + PIOMAP_FUNC(pciio_piomap, piomap_done) + (CAST_PIOMAP(pciio_piomap)); +} + +caddr_t +pciio_piotrans_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ + iopaddr_t addr, /* starting address (or offset in window) */ + size_t byte_count, /* map this many bytes */ + unsigned flags) +{ /* (currently unused) */ + return DEV_FUNC(dev, piotrans_addr) + (dev, dev_desc, space, addr, byte_count, flags); +} + +caddr_t +pciio_pio_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_space_t space, /* CFG, MEM, IO, or a device-decoded window */ + iopaddr_t addr, /* starting address (or offset in window) */ + size_t byte_count, /* map this many bytes */ + pciio_piomap_t *mapp, /* where to return the map pointer */ + unsigned flags) +{ /* PIO flags */ + pciio_piomap_t map = 0; + int errfree = 0; + caddr_t res; + + if (mapp) { + map = *mapp; /* possible pre-allocated map */ + *mapp = 0; /* record "no map used" */ + } + + res = pciio_piotrans_addr + (dev, dev_desc, space, addr, byte_count, flags); + if (res) + return res; /* pciio_piotrans worked */ + + if (!map) { + map = pciio_piomap_alloc + (dev, dev_desc, space, addr, byte_count, byte_count, flags); + if (!map) + return res; /* pciio_piomap_alloc failed */ + errfree = 1; + } + + res = pciio_piomap_addr + (map, addr, byte_count); + if (!res) { + if (errfree) + pciio_piomap_free(map); + return res; /* pciio_piomap_addr failed */ + } + if (mapp) + *mapp = map; /* pass back map used */ + + return res; /* pciio_piomap_addr succeeded */ +} + +iopaddr_t +pciio_piospace_alloc(devfs_handle_t dev, /* Device requiring space */ + device_desc_t dev_desc, /* Device descriptor */ + pciio_space_t space, /* MEM32/MEM64/IO */ + size_t byte_count, /* Size of mapping */ + size_t align) +{ /* Alignment needed */ + if (align < NBPP) + align = NBPP; + return DEV_FUNC(dev, piospace_alloc) + (dev, dev_desc, space, byte_count, align); +} + +void +pciio_piospace_free(devfs_handle_t dev, /* Device freeing space */ + pciio_space_t space, /* Type of space */ + iopaddr_t pciaddr, /* starting address */ + size_t byte_count) +{ /* Range of address */ + DEV_FUNC(dev, piospace_free) + (dev, space, pciaddr, byte_count); +} + +/* ===================================================================== + * DMA MANAGEMENT + * + * For mapping from pci space to system + * physical space. + */ + +pciio_dmamap_t +pciio_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ + device_desc_t dev_desc, /* device descriptor */ + size_t byte_count_max, /* max size of a mapping */ + unsigned flags) +{ /* defined in dma.h */ + return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc) + (dev, dev_desc, byte_count_max, flags); +} + +void +pciio_dmamap_free(pciio_dmamap_t pciio_dmamap) +{ + DMAMAP_FUNC(pciio_dmamap, dmamap_free) + (CAST_DMAMAP(pciio_dmamap)); +} + +iopaddr_t +pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ + paddr_t paddr, /* map for this address */ + size_t byte_count) +{ /* map this many bytes */ + return DMAMAP_FUNC(pciio_dmamap, dmamap_addr) + (CAST_DMAMAP(pciio_dmamap), paddr, byte_count); +} + +alenlist_t +pciio_dmamap_list(pciio_dmamap_t pciio_dmamap, /* use these mapping resources */ + alenlist_t alenlist, /* map this Address/Length List */ + unsigned flags) +{ + return DMAMAP_FUNC(pciio_dmamap, dmamap_list) + (CAST_DMAMAP(pciio_dmamap), alenlist, flags); +} + +void +pciio_dmamap_done(pciio_dmamap_t pciio_dmamap) +{ + DMAMAP_FUNC(pciio_dmamap, dmamap_done) + (CAST_DMAMAP(pciio_dmamap)); +} + +iopaddr_t +pciio_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + unsigned flags) +{ /* defined in dma.h */ + return DEV_FUNC(dev, dmatrans_addr) + (dev, dev_desc, paddr, byte_count, flags); +} + +alenlist_t +pciio_dmatrans_list(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + alenlist_t palenlist, /* system address/length list */ + unsigned flags) +{ /* defined in dma.h */ + return DEV_FUNC(dev, dmatrans_list) + (dev, dev_desc, palenlist, flags); +} + +iopaddr_t +pciio_dma_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + pciio_dmamap_t *mapp, /* map to use, then map we used */ + unsigned flags) +{ /* PIO flags */ + pciio_dmamap_t map = 0; + int errfree = 0; + iopaddr_t res; + + if (mapp) { + map = *mapp; /* possible pre-allocated map */ + *mapp = 0; /* record "no map used" */ + } + + res = pciio_dmatrans_addr + (dev, dev_desc, paddr, byte_count, flags); + if (res) + return res; /* pciio_dmatrans worked */ + + if (!map) { + map = pciio_dmamap_alloc + (dev, dev_desc, byte_count, flags); + if (!map) + return res; /* pciio_dmamap_alloc failed */ + errfree = 1; + } + + res = pciio_dmamap_addr + (map, paddr, byte_count); + if (!res) { + if (errfree) + pciio_dmamap_free(map); + return res; /* pciio_dmamap_addr failed */ + } + if (mapp) + *mapp = map; /* pass back map used */ + + return res; /* pciio_dmamap_addr succeeded */ +} + +void +pciio_dmamap_drain(pciio_dmamap_t map) +{ + DMAMAP_FUNC(map, dmamap_drain) + (CAST_DMAMAP(map)); +} + +void +pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) +{ + DEV_FUNC(dev, dmaaddr_drain) + (dev, addr, size); +} + +void +pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list) +{ + DEV_FUNC(dev, dmalist_drain) + (dev, list); +} + +/* ===================================================================== + * INTERRUPT MANAGEMENT + * + * Allow crosstalk devices to establish interrupts + */ + +/* + * Allocate resources required for an interrupt as specified in intr_desc. + * Return resource handle in intr_hdl. + */ +pciio_intr_t +pciio_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_intr_line_t lines, /* INTR line(s) to attach */ + devfs_handle_t owner_dev) +{ /* owner of this interrupt */ + return (pciio_intr_t) DEV_FUNC(dev, intr_alloc) + (dev, dev_desc, lines, owner_dev); +} + +/* + * Free resources consumed by intr_alloc. + */ +void +pciio_intr_free(pciio_intr_t intr_hdl) +{ + INTR_FUNC(intr_hdl, intr_free) + (CAST_INTR(intr_hdl)); +} + +/* + * Associate resources allocated with a previous pciio_intr_alloc call with the + * described handler, arg, name, etc. + * + * Returns 0 on success, returns <0 on failure. + */ +int +pciio_intr_connect(pciio_intr_t intr_hdl, /* pciio intr resource handle */ + intr_func_t intr_func, /* pciio intr handler */ + intr_arg_t intr_arg, /* arg to intr handler */ + void *thread) +{ /* intr thread to use */ + return INTR_FUNC(intr_hdl, intr_connect) + (CAST_INTR(intr_hdl), intr_func, intr_arg, thread); +} + +/* + * Disassociate handler with the specified interrupt. + */ +void +pciio_intr_disconnect(pciio_intr_t intr_hdl) +{ + INTR_FUNC(intr_hdl, intr_disconnect) + (CAST_INTR(intr_hdl)); +} + +/* + * Return a hwgraph vertex that represents the CPU currently + * targeted by an interrupt. + */ +devfs_handle_t +pciio_intr_cpu_get(pciio_intr_t intr_hdl) +{ + return INTR_FUNC(intr_hdl, intr_cpu_get) + (CAST_INTR(intr_hdl)); +} + +/* ===================================================================== + * ERROR MANAGEMENT + */ + +void +pciio_slot_func_to_name(char *name, + pciio_slot_t slot, + pciio_function_t func) +{ + /* + * standard connection points: + * + * PCIIO_SLOT_NONE: .../pci/direct + * PCIIO_FUNC_NONE: .../pci/ ie. .../pci/3 + * multifunction: .../pci/ ie. .../pci/3c + */ + + if (slot == PCIIO_SLOT_NONE) + sprintf(name, "direct"); + else if (func == PCIIO_FUNC_NONE) + sprintf(name, "%d", slot); + else + sprintf(name, "%d%c", slot, 'a'+func); +} + +/* + * pciio_cardinfo_get + * + * Get the pciio info structure corresponding to the + * specified PCI "slot" (we like it when the same index + * number is used for the PCI IDSEL, the REQ/GNT pair, + * and the interrupt line being used for INTA. We like + * it so much we call it the slot number). + */ +static pciio_info_t +pciio_cardinfo_get( + devfs_handle_t pciio_vhdl, + pciio_slot_t pci_slot) +{ + char namebuf[16]; + pciio_info_t info = 0; + devfs_handle_t conn; + + pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE); + if (GRAPH_SUCCESS == + hwgraph_traverse(pciio_vhdl, namebuf, &conn)) { + info = pciio_info_chk(conn); + hwgraph_vertex_unref(conn); + } + + return info; +} + +/* + * pciio_error_handler: + * dispatch an error to the appropriate + * pciio connection point, or process + * it as a generic pci error. + * Yes, the first parameter is the + * provider vertex at the middle of + * the bus; we get to the pciio connect + * point using the ioerror widgetdev field. + * + * This function is called by the + * specific PCI provider, after it has figured + * out where on the PCI bus (including which slot, + * if it can tell) the error came from. + */ +/*ARGSUSED */ +int +pciio_error_handler( + devfs_handle_t pciio_vhdl, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioerror) +{ + pciio_info_t pciio_info; + devfs_handle_t pconn_vhdl; +#if USRPCI + devfs_handle_t usrpci_v; +#endif + pciio_slot_t slot; + + int retval; +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + error_state_t e_state; +#endif + +#ifdef IRIX +#if DEBUG && ERROR_DEBUG + cmn_err(CE_CONT, "%v: pciio_error_handler\n", pciio_vhdl); +#endif +#endif + + IOERR_PRINTF(cmn_err(CE_NOTE, + "%v: PCI Bus Error: Error code: %d Error mode: %d\n", + pciio_vhdl, error_code, mode)); + + /* If there is an error handler sitting on + * the "no-slot" connection point, give it + * first crack at the error. NOTE: it is + * quite possible that this function may + * do further refining of the ioerror. + */ + pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE); + if (pciio_info && pciio_info->c_efunc) { + pconn_vhdl = pciio_info_dev_get(pciio_info); +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + e_state = error_state_get(pciio_vhdl); + + if (e_state == ERROR_STATE_ACTION) + (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); + + if (error_state_set(pconn_vhdl,e_state) == + ERROR_RETURN_CODE_CANNOT_SET_STATE) + return(IOERROR_UNHANDLED); +#endif + retval = pciio_info->c_efunc + (pciio_info->c_einfo, error_code, mode, ioerror); + if (retval != IOERROR_UNHANDLED) + return retval; + } + + /* Is the error associated with a particular slot? + */ + if (IOERROR_FIELDVALID(ioerror, widgetdev)) { + /* + * NOTE : + * widgetdev is a 4byte value encoded as slot in the higher order + * 2 bytes and function in the lower order 2 bytes. + */ +#ifdef IRIX + slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioerror, widgetdev)); +#else + slot = 0; +#endif + + /* If this slot has an error handler, + * deliver the error to it. + */ + pciio_info = pciio_cardinfo_get(pciio_vhdl, slot); + if (pciio_info != NULL) { + if (pciio_info->c_efunc != NULL) { + + pconn_vhdl = pciio_info_dev_get(pciio_info); +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + e_state = error_state_get(pciio_vhdl); + + if (e_state == ERROR_STATE_ACTION) + (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE); + + if (error_state_set(pconn_vhdl,e_state) == + ERROR_RETURN_CODE_CANNOT_SET_STATE) + return(IOERROR_UNHANDLED); +#endif + retval = pciio_info->c_efunc + (pciio_info->c_einfo, error_code, mode, ioerror); + if (retval != IOERROR_UNHANDLED) + return retval; + } + +#if USRPCI + /* If the USRPCI driver is available and + * knows about this connection point, + * deliver the error to it. + * + * OK to use pconn_vhdl here, even though we + * have already UNREF'd it, since we know that + * it is not going away. + */ + pconn_vhdl = pciio_info_dev_get(pciio_info); + if (GRAPH_SUCCESS == + hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) { + retval = usrpci_error_handler + (usrpci_v, error_code, IOERROR_GETVALUE(ioerror, busaddr)); + hwgraph_vertex_unref(usrpci_v); + if (retval != IOERROR_UNHANDLED) { + /* + * This unref is not needed. If this code is called often enough, + * the system will crash, due to vertex reference count reaching 0, + * causing vertex to be unallocated. -jeremy + * hwgraph_vertex_unref(pconn_vhdl); + */ + return retval; + } + } +#endif + } + } + + return (mode == MODE_DEVPROBE) + ? IOERROR_HANDLED /* probes are OK */ + : IOERROR_UNHANDLED; /* otherwise, foo! */ +} + +int +pciio_error_devenable(devfs_handle_t pconn_vhdl, int error_code) +{ + return DEV_FUNC(pconn_vhdl, error_devenable) + (pconn_vhdl, error_code); + /* no cleanup specific to this layer. */ +} + +/* ===================================================================== + * CONFIGURATION MANAGEMENT + */ + +/* + * Startup a crosstalk provider + */ +void +pciio_provider_startup(devfs_handle_t pciio_provider) +{ + DEV_FUNC(pciio_provider, provider_startup) + (pciio_provider); +} + +/* + * Shutdown a crosstalk provider + */ +void +pciio_provider_shutdown(devfs_handle_t pciio_provider) +{ + DEV_FUNC(pciio_provider, provider_shutdown) + (pciio_provider); +} + +/* + * Specify endianness constraints. The driver tells us what the device + * does and how it would like to see things in memory. We reply with + * how things will actually appear in memory. + */ +pciio_endian_t +pciio_endian_set(devfs_handle_t dev, + pciio_endian_t device_end, + pciio_endian_t desired_end) +{ + ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE)); + ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE)); + +#if DEBUG + cmn_err(CE_ALERT, + "%v: pciio_endian_set is going away.\n" + "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" + "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", + dev); +#endif + + return DEV_FUNC(dev, endian_set) + (dev, device_end, desired_end); +} + +/* + * Specify PCI arbitration priority. + */ +pciio_priority_t +pciio_priority_set(devfs_handle_t dev, + pciio_priority_t device_prio) +{ + ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW)); + + return DEV_FUNC(dev, priority_set) + (dev, device_prio); +} + +/* + * Read value of configuration register + */ +uint64_t +pciio_config_get(devfs_handle_t dev, + unsigned reg, + unsigned size) +{ + uint64_t value = 0; + unsigned shift = 0; + + /* handle accesses that cross words here, + * since that's common code between all + * possible providers. + */ + while (size > 0) { + unsigned biw = 4 - (reg&3); + if (biw > size) + biw = size; + + value |= DEV_FUNC(dev, config_get) + (dev, reg, biw) << shift; + + shift += 8*biw; + reg += biw; + size -= biw; + } + return value; +} + +/* + * Change value of configuration register + */ +void +pciio_config_set(devfs_handle_t dev, + unsigned reg, + unsigned size, + uint64_t value) +{ + /* handle accesses that cross words here, + * since that's common code between all + * possible providers. + */ + while (size > 0) { + unsigned biw = 4 - (reg&3); + if (biw > size) + biw = size; + + DEV_FUNC(dev, config_set) + (dev, reg, biw, value); + reg += biw; + size -= biw; + value >>= biw * 8; + } +} + +/* ===================================================================== + * GENERIC PCI SUPPORT FUNCTIONS + */ +pciio_slot_t +pciio_error_extract(devfs_handle_t dev, + pciio_space_t *space, + iopaddr_t *offset) +{ + ASSERT(dev != NODEV); + return DEV_FUNC(dev,error_extract)(dev,space,offset); +} + +/* + * Issue a hardware reset to a card. + */ +int +pciio_reset(devfs_handle_t dev) +{ + return DEV_FUNC(dev, reset) (dev); +} + +/* + * flush write gather buffers + */ +int +pciio_write_gather_flush(devfs_handle_t dev) +{ + return DEV_FUNC(dev, write_gather_flush) (dev); +} + +devfs_handle_t +pciio_intr_dev_get(pciio_intr_t pciio_intr) +{ + return (pciio_intr->pi_dev); +} + +/****** Generic crosstalk pio interfaces ******/ +devfs_handle_t +pciio_pio_dev_get(pciio_piomap_t pciio_piomap) +{ + return (pciio_piomap->pp_dev); +} + +pciio_slot_t +pciio_pio_slot_get(pciio_piomap_t pciio_piomap) +{ + return (pciio_piomap->pp_slot); +} + +pciio_space_t +pciio_pio_space_get(pciio_piomap_t pciio_piomap) +{ + return (pciio_piomap->pp_space); +} + +iopaddr_t +pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap) +{ + return (pciio_piomap->pp_pciaddr); +} + +ulong +pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap) +{ + return (pciio_piomap->pp_mapsz); +} + +caddr_t +pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap) +{ + return (pciio_piomap->pp_kvaddr); +} + +/****** Generic crosstalk dma interfaces ******/ +devfs_handle_t +pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap) +{ + return (pciio_dmamap->pd_dev); +} + +pciio_slot_t +pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap) +{ + return (pciio_dmamap->pd_slot); +} + +/****** Generic pci slot information interfaces ******/ + +pciio_info_t +pciio_info_chk(devfs_handle_t pciio) +{ + arbitrary_info_t ainfo = 0; + + hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo); + return (pciio_info_t) ainfo; +} + +pciio_info_t +pciio_info_get(devfs_handle_t pciio) +{ + pciio_info_t pciio_info; + + pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio); + +#ifdef DEBUG_PCIIO + { + int pos; + char dname[256]; + pos = devfs_generate_path(pciio, dname, 256); + printk("%s : path= %s\n", __FUNCTION__, &dname[pos]); + } +#endif /* DEBUG_PCIIO */ + +#ifdef BRINGUP + if ((pciio_info != NULL) && + (pciio_info->c_fingerprint != pciio_info_fingerprint) + && (pciio_info->c_fingerprint != NULL)) { +#else + if ((pciio_info != NULL) && + (pciio_info->c_fingerprint != pciio_info_fingerprint)) { +#endif /* BRINGUP */ + + printk("pciio_info_get: Found fastinfo 0x%p but wrong fingerprint %s\n", pciio_info, + pciio_info->c_fingerprint); + return((pciio_info_t)-1); /* Should panic .. */ + } + + + return pciio_info; +} + +void +pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info) +{ + if (pciio_info != NULL) + pciio_info->c_fingerprint = pciio_info_fingerprint; + hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info); + + /* Also, mark this vertex as a PCI slot + * and use the pciio_info, so pciio_info_chk + * can work (and be fairly efficient). + */ + hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO, + (arbitrary_info_t) pciio_info); +} + +devfs_handle_t +pciio_info_dev_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_vertex); +} + +/*ARGSUSED*/ +pciio_bus_t +pciio_info_bus_get(pciio_info_t pciio_info) +{ + /* XXX for now O2 always gets back bus 0 */ + return (pciio_bus_t)0; +} + +pciio_slot_t +pciio_info_slot_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_slot); +} + +pciio_function_t +pciio_info_function_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_func); +} + +pciio_vendor_id_t +pciio_info_vendor_id_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_vendor); +} + +pciio_device_id_t +pciio_info_device_id_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_device); +} + +devfs_handle_t +pciio_info_master_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_master); +} + +arbitrary_info_t +pciio_info_mfast_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_mfast); +} + +pciio_provider_t * +pciio_info_pops_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_pops); +} + +error_handler_f * +pciio_info_efunc_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_efunc); +} + +error_handler_arg_t * +pciio_info_einfo_get(pciio_info_t pciio_info) +{ + return (pciio_info->c_einfo); +} + +pciio_space_t +pciio_info_bar_space_get(pciio_info_t info, int win) +{ + return info->c_window[win].w_space; +} + +iopaddr_t +pciio_info_bar_base_get(pciio_info_t info, int win) +{ + return info->c_window[win].w_base; +} + +size_t +pciio_info_bar_size_get(pciio_info_t info, int win) +{ + return info->c_window[win].w_size; +} + +iopaddr_t +pciio_info_rom_base_get(pciio_info_t info) +{ + return info->c_rbase; +} + +size_t +pciio_info_rom_size_get(pciio_info_t info) +{ + return info->c_rsize; +} + + +/* ===================================================================== + * GENERIC PCI INITIALIZATION FUNCTIONS + */ + +/* + * pciioinit: called once during device driver + * initializtion if this driver is configured into + * the system. + */ +void +pciio_init(void) +{ + cdl_p cp; + +#if DEBUG && ATTACH_DEBUG + printf("pciio_init\n"); +#endif + /* Allocate the registry. + * We might already have one. + * If we don't, go get one. + * MPness: someone might have + * set one up for us while we + * were not looking; use an atomic + * compare-and-swap to commit to + * using the new registry if and + * only if nobody else did first. + * If someone did get there first, + * toss the one we allocated back + * into the pool. + */ + if (pciio_registry == NULL) { + cp = cdl_new(EDGE_LBL_PCI, "vendor", "device"); + if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) { + cdl_del(cp); + } + } + ASSERT(pciio_registry != NULL); +} + +/* + * pciioattach: called for each vertex in the graph + * that is a PCI provider. + */ +/*ARGSUSED */ +int +pciio_attach(devfs_handle_t pciio) +{ +#if DEBUG && ATTACH_DEBUG + cmn_err(CE_CONT, "%v: pciio_attach\n", pciio); +#endif + return 0; +} + +/* + * Associate a set of pciio_provider functions with a vertex. + */ +void +pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns) +{ + hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns); +} + +/* + * Disassociate a set of pciio_provider functions with a vertex. + */ +void +pciio_provider_unregister(devfs_handle_t provider) +{ + arbitrary_info_t ainfo; + +#ifdef IRIX + hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, &ainfo); +#else + hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo); +#endif +} + +/* + * Obtain a pointer to the pciio_provider functions for a specified Crosstalk + * provider. + */ +pciio_provider_t * +pciio_provider_fns_get(devfs_handle_t provider) +{ + arbitrary_info_t ainfo = 0; + + (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo); + return (pciio_provider_t *) ainfo; +} + +/*ARGSUSED4 */ +int +pciio_driver_register( + pciio_vendor_id_t vendor_id, + pciio_device_id_t device_id, + char *driver_prefix, + unsigned flags) +{ + /* a driver's init routine might call + * pciio_driver_register before the + * system calls pciio_init; so we + * make the init call ourselves here. + */ + if (pciio_registry == NULL) + pciio_init(); + + return cdl_add_driver(pciio_registry, + vendor_id, device_id, + driver_prefix, flags); +} + +/* + * Remove an initialization function. + */ +void +pciio_driver_unregister( + char *driver_prefix) +{ + /* before a driver calls unregister, + * it must have called register; so + * we can assume we have a registry here. + */ + ASSERT(pciio_registry != NULL); + + cdl_del_driver(pciio_registry, driver_prefix); +} + +/* + * Call some function with each vertex that + * might be one of this driver's attach points. + */ +void +pciio_iterate(char *driver_prefix, + pciio_iter_f * func) +{ + /* a driver's init routine might call + * pciio_iterate before the + * system calls pciio_init; so we + * make the init call ourselves here. + */ + if (pciio_registry == NULL) + pciio_init(); + + ASSERT(pciio_registry != NULL); + + cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func); +} + +devfs_handle_t +pciio_device_register( + devfs_handle_t connectpt, /* vertex for /hw/.../pciio/%d */ + devfs_handle_t master, /* card's master ASIC (PCI provider) */ + pciio_slot_t slot, /* card's slot */ + pciio_function_t func, /* card's func */ + pciio_vendor_id_t vendor_id, + pciio_device_id_t device_id) +{ + + return pciio_device_info_register + (connectpt, pciio_device_info_new (NULL, master, slot, func, + vendor_id, device_id)); +} + +void +pciio_device_unregister(devfs_handle_t pconn) +{ + DEV_FUNC(pconn,device_unregister)(pconn); +} + +pciio_info_t +pciio_device_info_new( + pciio_info_t pciio_info, + devfs_handle_t master, + pciio_slot_t slot, + pciio_function_t func, + pciio_vendor_id_t vendor_id, + pciio_device_id_t device_id) +{ + if (!pciio_info) + NEW(pciio_info); + ASSERT(pciio_info != NULL); + + pciio_info->c_slot = slot; + pciio_info->c_func = func; + pciio_info->c_vendor = vendor_id; + pciio_info->c_device = device_id; + pciio_info->c_master = master; + pciio_info->c_mfast = hwgraph_fastinfo_get(master); + pciio_info->c_pops = pciio_provider_fns_get(master); + pciio_info->c_efunc = 0; + pciio_info->c_einfo = 0; + + return pciio_info; +} + +void +pciio_device_info_free(pciio_info_t pciio_info) +{ + /* NOTE : pciio_info is a structure within the pcibr_info + * and not a pointer to memory allocated on the heap !! + */ + BZERO((char *)pciio_info,sizeof(pciio_info)); +} + +devfs_handle_t +pciio_device_info_register( + devfs_handle_t connectpt, /* vertex at center of bus */ + pciio_info_t pciio_info) /* details about the connectpt */ +{ + char name[32]; + devfs_handle_t pconn; + + pciio_slot_func_to_name(name, + pciio_info->c_slot, + pciio_info->c_func); + + printk("pciio_device_info_register: connectpt 0x%p, pciio_info 0x%p\n", connectpt, pciio_info); + + if (GRAPH_SUCCESS != + hwgraph_path_add(connectpt, name, &pconn)) + return pconn; + + pciio_info->c_vertex = pconn; + pciio_info_set(pconn, pciio_info); +#ifdef BRINGUP + { + int pos; + char dname[256]; + pos = devfs_generate_path(pconn, dname, 256); + printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]); + } +#endif /* BRINGUP */ + + /* + * create link to our pci provider + */ + + device_master_set(pconn, pciio_info->c_master); + +#if USRPCI + /* + * Call into usrpci provider to let it initialize for + * the given slot. + */ + if (pciio_info->c_slot != PCIIO_SLOT_NONE) + usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot); +#endif + + return pconn; +} + +void +pciio_device_info_unregister(devfs_handle_t connectpt, + pciio_info_t pciio_info) +{ + char name[32]; + devfs_handle_t pconn; + + if (!pciio_info) + return; + + pciio_slot_func_to_name(name, + pciio_info->c_slot, + pciio_info->c_func); + + hwgraph_edge_remove(connectpt,name,&pconn); + pciio_info_set(pconn,0); + + /* Remove the link to our pci provider */ + hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL); + + hwgraph_vertex_unref(pconn); + hwgraph_vertex_destroy(pconn); + +} +/* Add the pci card inventory information to the hwgraph + */ +static void +pciio_device_inventory_add(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + + ASSERT(pciio_info); + ASSERT(pciio_info->c_vertex == pconn_vhdl); + + /* Donot add inventory for non-existent devices */ + if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE) || + (pciio_info->c_device == PCIIO_DEVICE_ID_NONE)) + return; + device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP, + pciio_info->c_vendor,pciio_info->c_device, + pciio_info->c_slot); +} + +static void +pciio_device_inventory_remove(devfs_handle_t pconn_vhdl) +{ +#ifdef IRIX + hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1); +#endif +} + +/*ARGSUSED */ +int +pciio_device_attach(devfs_handle_t pconn) +{ + pciio_info_t pciio_info; + pciio_vendor_id_t vendor_id; + pciio_device_id_t device_id; + + pciio_device_inventory_add(pconn); + pciio_info = pciio_info_get(pconn); + + vendor_id = pciio_info->c_vendor; + device_id = pciio_info->c_device; + + printk("pciio_device_attach: Function 0x%p, vendor 0x%x, device_id %x\n", pconn, vendor_id, device_id); + + /* we don't start attaching things until + * all the driver init routines (including + * pciio_init) have been called; so we + * can assume here that we have a registry. + */ + ASSERT(pciio_registry != NULL); + + return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn)); + +} + +int +pciio_device_detach(devfs_handle_t pconn) +{ + pciio_info_t pciio_info; + pciio_vendor_id_t vendor_id; + pciio_device_id_t device_id; + + pciio_device_inventory_remove(pconn); + pciio_info = pciio_info_get(pconn); + + vendor_id = pciio_info->c_vendor; + device_id = pciio_info->c_device; + + /* we don't start attaching things until + * all the driver init routines (including + * pciio_init) have been called; so we + * can assume here that we have a registry. + */ + ASSERT(pciio_registry != NULL); + + cdl_del_connpt(pciio_registry, vendor_id, device_id, pconn); + + return(0); + +} + +/* + * pciio_error_register: + * arrange for a function to be called with + * a specified first parameter plus other + * information when an error is encountered + * and traced to the pci slot corresponding + * to the connection point pconn. + * + * may also be called with a null function + * pointer to "unregister" the error handler. + * + * NOTE: subsequent calls silently overwrite + * previous data for this vertex. We assume that + * cooperating drivers, well, cooperate ... + */ +void +pciio_error_register(devfs_handle_t pconn, + error_handler_f *efunc, + error_handler_arg_t einfo) +{ + pciio_info_t pciio_info; + + pciio_info = pciio_info_get(pconn); + ASSERT(pciio_info != NULL); + pciio_info->c_efunc = efunc; + pciio_info->c_einfo = einfo; +} + +/* + * Check if any device has been found in this slot, and return + * true or false + * vhdl is the vertex for the slot + */ +int +pciio_slot_inuse(devfs_handle_t pconn_vhdl) +{ + pciio_info_t pciio_info = pciio_info_get(pconn_vhdl); + + ASSERT(pciio_info); + ASSERT(pciio_info->c_vertex == pconn_vhdl); + if (pciio_info->c_vendor) { + /* + * Non-zero value for vendor indicate + * a board being found in this slot. + */ + return 1; + } + return 0; +} + +int +pciio_dma_enabled(devfs_handle_t pconn_vhdl) +{ + return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/sgi_if.c linux-2.4.0-test12-lia/arch/ia64/sn/io/sgi_if.c --- linux-2.4.0-test12/arch/ia64/sn/io/sgi_if.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/sgi_if.c Wed Nov 15 19:11:35 2000 @@ -0,0 +1,73 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name); + +void * +kmem_zalloc(size_t size, int flag) +{ + void *ptr = kmalloc(size, GFP_KERNEL); + BZERO(ptr, size); + return ptr; +} + +#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); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/sgi_io_init.c linux-2.4.0-test12-lia/arch/ia64/sn/io/sgi_io_init.c --- linux-2.4.0-test12/arch/ia64/sn/io/sgi_io_init.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/sgi_io_init.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,312 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void mlreset(int ); +extern int init_hcl(void); +extern void klgraph_hack_init(void); +extern void per_hub_init(cnodeid_t); +extern void hubspc_init(void); +extern void pciba_init(void); +extern void pciio_init(void); +extern void pcibr_init(void); +extern void xtalk_init(void); +extern void xbow_init(void); +extern void xbmon_init(void); +extern void pciiox_init(void); +extern void usrpci_init(void); +extern void ioc3_init(void); +extern void initialize_io(void); +extern void init_platform_nodepda(nodepda_t *, cnodeid_t ); +extern void intr_clear_all(nasid_t); +extern void klhwg_add_all_modules(devfs_handle_t); +extern void klhwg_add_all_nodes(devfs_handle_t); + +void sn_mp_setup(void); +extern devfs_handle_t hwgraph_root; +extern void io_module_init(void); +extern cnodeid_t nasid_to_compact_node[]; +extern void pci_bus_cvlink_init(void); +extern void temp_hack(void); +extern void init_platform_pda(cpuid_t cpu); + +extern int pci_bus_to_hcl_cvlink(void); +extern synergy_da_t *Synergy_da_indr[]; + +#define DEBUG_IO_INIT +#ifdef DEBUG_IO_INIT +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG_IO_INIT */ + +/* + * kern/ml/csu.s calls mlsetup + * mlsetup calls mlreset(master) - kern/os/startup.c + * j main + * + + * SN/slave.s start_slave_loop calls slave_entry + * SN/slave.s slave_entry calls slave_loop + * SN/slave.s slave_loop calls bootstrap + * bootstrap in SN1/SN1asm.s calls cboot + * cboot calls mlreset(slave) - ml/SN/mp.c + * + * sgi_io_infrastructure_init() gets called right before pci_init() + * in Linux mainline. This routine actually mirrors the IO Infrastructure + * call sequence in IRIX, ofcourse, nicely modified for Linux. + * + * It is very IMPORTANT that this call is only made by the Master CPU! + * + */ + +void +sgi_master_io_infr_init(void) +{ +#ifdef Colin + /* + * Simulate Big Window 0. + * Only when we build for lutsen etc. .. + */ + simulated_BW0_init(); +#endif + + /* + * Do any early init stuff .. einit_tbl[] etc. + */ + DBG("--> sgi_master_io_infr_init: calling init_hcl().\n"); + init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */ + + /* + * initialize the Linux PCI to xwidget vertexes .. + */ + DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n"); + pci_bus_cvlink_init(); + + /* + * Hack to provide statically initialzed klgraph entries. + */ + DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n"); + klgraph_hack_init(); + + /* + * This is the Master CPU. Emulate mlsetup and main.c in Irix. + */ + DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n"); + mlreset(0); /* Master .. */ + + /* + * allowboot() is called by kern/os/main.c in main() + * Emulate allowboot() ... + * per_cpu_init() - only need per_hub_init() + * cpu_io_setup() - Nothing to do. + * + */ + DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n"); + sn_mp_setup(); + + DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n"); + per_hub_init(0); /* Need to get and send in actual cnode number */ + + /* We can do headless hub cnodes here .. */ + + /* + * io_init[] stuff. + * + * Get SGI IO Infrastructure drivers to init and register with + * each other etc. + */ + + DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n"); + hubspc_init(); + + DBG("--> sgi_master_io_infr_init: calling pciba_init()\n"); + pciba_init(); + + DBG("--> sgi_master_io_infr_init: calling pciio_init()\n"); + pciio_init(); + + DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n"); + pcibr_init(); + + DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n"); + xtalk_init(); + + DBG("--> sgi_master_io_infr_init: calling xbow_init()\n"); + xbow_init(); + + DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n"); + xbmon_init(); + + DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n"); + pciiox_init(); + + DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n"); + usrpci_init(); + + DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n"); + ioc3_init(); + + /* + * + * Our IO Infrastructure drivers are in place .. + * Initialize the whole IO Infrastructure .. xwidget/device probes. + * + */ + DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n"); + initialize_io(); + + DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n"); + pci_bus_to_hcl_cvlink(); + + DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n"); +} + +/* + * sgi_slave_io_infr_init - This routine must be called on all cpus except + * the Master CPU. + */ +void +sgi_slave_io_infr_init(void) +{ + /* Emulate cboot() .. */ + mlreset(1); /* This is a slave cpu */ + + per_hub_init(0); /* Need to get and send in actual cnode number */ + + /* Done */ +} + +/* + * One-time setup for MP SN. + * Allocate per-node data, slurp prom klconfig information and + * convert it to hwgraph information. + */ +void +sn_mp_setup(void) +{ + cnodeid_t cnode; + extern int maxnodes; + cpuid_t cpu; + + DBG("sn_mp_setup: Entered.\n"); + /* + * NODEPDA(x) Macro depends on nodepda + * subnodepda is also statically set to calias space which we + * do not currently support yet .. just a hack for now. + */ +#ifdef NUMA_BASE + DBG("sn_mp_setup(): maxnodes= %d numnodes= %d\n", maxnodes,numnodes); + maxnodes = numnodes; +#ifdef SIMULATED_KLGRAPH + maxnodes = 1; + numnodes = 1; +#endif /* SIMULATED_KLGRAPH */ + printk("sn_mp_setup(): Allocating backing store for *Nodepdaindr[%2d] \n", + maxnodes); + + /* + * Initialize Nodpdaindr and per-node nodepdaindr array + */ + *Nodepdaindr = (nodepda_t *) kmalloc(sizeof(nodepda_t *)*numnodes, GFP_KERNEL); + for (cnode=0; cnodepernode_pdaindr = Nodepdaindr; + subnodepda = &Nodepdaindr[cnode]->snpda[cnode]; + } + nodepda = Nodepdaindr[0]; +#else + Nodepdaindr = (nodepda_t *) kmalloc(sizeof(struct nodepda_s), GFP_KERNEL); + nodepda = Nodepdaindr[0]; + subnodepda = &Nodepdaindr[0]->snpda[0]; + +#endif /* NUMA_BASE */ + + /* + * Before we let the other processors run, set up the platform specific + * stuff in the nodepda. + * + * ???? maxnodes set in mlreset .. who sets it now ???? + * ???? cpu_node_probe() called in mlreset to set up the following: + * compact_to_nasid_node[] - cnode id gives nasid + * nasid_to_compact_node[] - nasid gives cnode id + * + * do_cpumask() sets the following: + * cpuid_to_compact_node[] - cpuid gives cnode id + * + * nasid comes from gdap->g_nasidtable[] + * ml/SN/promif.c + */ + + for (cnode = 0; cnode < maxnodes; cnode++) { + /* + * Set up platform-dependent nodepda fields. + * The following routine actually sets up the hubinfo struct + * in nodepda. + */ + DBG("sn_mp_io_setup: calling init_platform_nodepda(%2d)\n",cnode); + init_platform_nodepda(Nodepdaindr[cnode], cnode); + + /* + * This routine clears the Hub's Interrupt registers. + */ +#ifndef CONFIG_IA64_SGI_IO + /* + * We need to move this intr_clear_all() routine + * from SN/intr.c to a more appropriate file. + * Talk to Al Mayer. + */ + intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); +#endif + } + +#ifdef CONFIG_IA64_SGI_IO + for (cpu = 0; cpu < smp_num_cpus; cpu++) { + /* Skip holes in CPU space */ + if (cpu_enabled(cpu)) { + init_platform_pda(cpu); + } + } +#endif + + /* + * Initialize platform-dependent vertices in the hwgraph: + * module + * node + * cpu + * memory + * slot + * hub + * router + * xbow + */ + + DBG("sn_mp_io_setup: calling io_module_init()\n"); + io_module_init(); /* Use to be called module_init() .. */ + + DBG("sn_mp_setup: calling klhwg_add_all_modules()\n"); + klhwg_add_all_modules(hwgraph_root); + DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n"); + klhwg_add_all_nodes(hwgraph_root); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/sgi_io_sim.c linux-2.4.0-test12-lia/arch/ia64/sn/io/sgi_io_sim.c --- linux-2.4.0-test12/arch/ia64/sn/io/sgi_io_sim.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/sgi_io_sim.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,162 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +cnodeid_t nasid_to_compact_node[MAX_NASIDS]; +nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; +cnodeid_t cpuid_to_compact_node[MAXCPUS]; +cpuid_t master_procid = 0; +int maxnodes; +char arg_maxnodes[4]; + +nodepda_t *Nodepdaindr[MAX_COMPACT_NODES]; +nodepda_t *nodepda; +subnode_pda_t *subnodepda; + +synergy_da_t *Synergy_da_indr[MAX_COMPACT_NODES * 2]; + +extern void init_all_devices(void); + + +/* + * Return non-zero if the given variable was specified + */ +int +is_specified(char *s) +{ + return (strlen(s) != 0); +} + + +void pciba_init(void) +{ + FIXME("pciba_init : no-op\n"); +} + +void xbmon_init(void) +{ + FIXME("xbmon_init : no-op\n"); + +} + +void pciiox_init(void) +{ + FIXME("pciiox_init : no-op\n"); + +} + +void usrpci_init(void) +{ + FIXME("usrpci_init : no-op\n"); + +} + +void ioc3_init(void) +{ + FIXME("ioc3_init : no-op\n"); + +} + +void initialize_io(void) +{ + + init_all_devices(); +} + +/* + * Routines provided by ml/SN/promif.c. + */ +static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL; +static nasid_t console_nasid; +static char console_wid; +static char console_pcislot; + +void +set_master_bridge_base(void) +{ + +#ifdef SIMULATED_KLGRAPH + printk("set_master_bridge_base: SIMULATED_KLGRAPH FIXME hardwired master.\n"); + console_nasid = 0; + console_wid = 0x8; + console_pcislot = 0x2; +#else + console_nasid = KL_CONFIG_CH_CONS_INFO(master_nasid)->nasid; + console_wid = WIDGETID_GET(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base); + console_pcislot = KL_CONFIG_CH_CONS_INFO(master_nasid)->npci; +#endif /* SIMULATED_KLGRAPH */ + + master_bridge_base = (__psunsigned_t)NODE_SWIN_BASE(console_nasid, + console_wid); +} + +int +check_nasid_equiv(nasid_t nasida, nasid_t nasidb) +{ + if ((nasida == nasidb) || + (nasida == NODEPDA(NASID_TO_COMPACT_NODEID(nasidb))->xbow_peer)) + return 1; + else + return 0; +} + +int +is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid) +{ + + /* + * If the widget numbers are different, we're not the master. + */ + if (test_wid != (xwidgetnum_t)console_wid) + return 0; + + /* + * If the NASIDs are the same or equivalent, we're the master. + */ + if (check_nasid_equiv(test_nasid, console_nasid)) { + return 1; + } else { + return 0; + } +} + +cnodeid_t +nasid_to_compact_nodeid(nasid_t nasid) +{ + ASSERT(nasid >= 0 && nasid < MAX_NASIDS); + return nasid_to_compact_node[nasid]; +} + +nasid_t +compact_to_nasid_nodeid(cnodeid_t cnode) +{ + ASSERT(cnode >= 0 && cnode <= MAX_COMPACT_NODES); + ASSERT(compact_to_nasid_node[cnode] >= 0); + return compact_to_nasid_node[cnode]; +} + +/* + * Routines provided by ml/SN/nvram.c + */ +void +nvram_baseinit(void) +{ + FIXME("nvram_baseinit : no-op\n"); + +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/stubs.c linux-2.4.0-test12-lia/arch/ia64/sn/io/stubs.c --- linux-2.4.0-test12/arch/ia64/sn/io/stubs.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/stubs.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,257 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/****** + ****** hack defines ...... + ******/ + +int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev; +int default_intr_pri; +int force_fire_and_forget; +int ignore_conveyor_override; + +#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name); + +devfs_handle_t dummy_vrtx; /* Needed for cpuid_to_vertex() in hack.h */ + + +/* ARGSUSED */ +void hub_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) + {FIXME("hub_widgetdev_enable");} + +/* ARGSUSED */ +void hub_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) + {FIXME("hub_widgetdev_shutdown");} + +/* ARGSUSED */ +void hub_widget_reset(devfs_handle_t hubv, xwidgetnum_t widget) + {FIXME("hub_widget_reset");} + +boolean_t +is_sys_critical_vertex(devfs_handle_t x) +{ + FIXME("is_sys_critical_vertex : returns 0"); + return(0); +} + +char * +nic_bridge_vertex_info(devfs_handle_t v, nic_data_t mcr) +{ + FIXME("nic_bridge_vertex_info : returns NULL"); + return((char *)0); +} + +void * +kmem_alloc_node(register size_t size, register int flags, cnodeid_t node) +{ + /* Allocates on node 'node' */ + FIXME("kmem_alloc_node : use kmalloc"); + return(kmalloc(size, GFP_KERNEL)); +} + +void * +kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node) +{ + FIXME("kmem_zalloc_node : use kmalloc"); + return(kmalloc(size, GFP_KERNEL)); +} + +void +kmem_free(void *where, int size) +{ + FIXME("kmem_free : use kfree"); + return(kfree(where)); +} + + +void * +kmem_zone_alloc(register zone_t *zone, int flags) +{ + FIXME("kmem_zone_alloc : return null"); + return((void *)0); +} + +void +kmem_zone_free(register zone_t *zone, void *ptr) +{ + FIXME("kmem_zone_free : no-op"); +} + +zone_t * +kmem_zone_init(register int size, char *zone_name) +{ + FIXME("kmem_zone_free : returns NULL"); + return((zone_t *)0); +} + +uint64_t +rmalloc(struct map *mp, size_t size) +{ + FIXME("rmalloc : returns NULL"); + return((uint64_t)0); +} + +void +rmfree(struct map *mp, size_t size, uint64_t a) +{ + FIXME("rmfree : no-op"); +} + +struct map * +rmallocmap(uint64_t mapsiz) +{ + FIXME("rmallocmap : returns NULL"); + return((struct map *)0); +} + +void +rmfreemap(struct map *mp) +{ + FIXME("rmfreemap : no-op"); +} + +int +compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr) +{ + FIXME("compare_and_swap_ptr : NOT ATOMIC"); + if (*location == old_ptr) { + *location = new_ptr; + return(1); + } + else + return(0); +} + +void * +swap_ptr(void **loc, void *new) +{ + FIXME("swap_ptr : returns null"); + return((void *)0); +} + +/* For ml/SN/SN1/slots.c */ +/* ARGSUSED */ +slotid_t get_widget_slotnum(int xbow, int widget) + {FIXME("get_widget_slotnum"); return (unsigned char)NULL;} + +/* For router */ +int +router_init(cnodeid_t cnode,int writeid, void *npda_rip) + {FIXME("router_init"); return(0);} + +/* From io/ioerror_handling.c */ +error_return_code_t +sys_critical_graph_vertex_add(devfs_handle_t parent, devfs_handle_t child) + {FIXME("sys_critical_graph_vertex_add"); return(0);} + +/* From io/ioc3.c */ +devfs_handle_t +ioc3_console_vhdl_get(void) + {FIXME("ioc3_console_vhdl_get"); return( (devfs_handle_t)-1);} + + +#if 0 +#define io_splock(l) 1 +#define io_spunlock(l,s) + +#define spinlock_destroy(a) /* needed by pcibr_detach() */ +#define mutex_spinlock(a) 0 +#define mutex_spinunlock(a,b) +#define mutex_init(a,b,c) ; +#define mutex_lock(a,b) ; +#define mutex_unlock(a) ; +#define dev_to_vhdl(dev) 0 +#define get_timestamp() 0 +#define us_delay(a) +#define v_mapphys(a,b,c) 0 +#define splhi() 0 +#define splx(s) +#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name); +#endif /* 0 */ + +int +cap_able(uint64_t x) +{ + FIXME("cap_able : returns 1"); + return(1); +} + +int +cap_able_cred(uint64_t a, uint64_t b) +{ + FIXME("cap_able_cred : returns 1"); + return(1); +} + +void +nic_vmc_check(devfs_handle_t vhdl, char *nicinfo) +{ + + FIXME("nic_vmc_check\n"); + +} + +char * +nic_vertex_info_get(devfs_handle_t v) +{ + + FIXME("nic_vertex_info_get\n"); + return(NULL); + +} + +int +vector_read_node(net_vec_t dest, nasid_t nasid, + int write_id, int address, + uint64_t *value) +{ + FIXME("vector_read_node\n"); + return(0); +} + +int +vector_write_node(net_vec_t dest, nasid_t nasid, + int write_id, int address, + uint64_t value) +{ + FIXME("vector_write_node\n"); + return(0); +} + +int +atomicAddInt(int *int_ptr, int value) +{ +// FIXME("atomicAddInt : simple add\n"); + *int_ptr += value; + return(0); +} + +int +atomicClearInt(int *int_ptr, int value) +{ + FIXME("atomicClearInt : simple clear\n"); + *int_ptr &= ~value; + return(0); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/xbow.c linux-2.4.0-test12-lia/arch/ia64/sn/io/xbow.c --- linux-2.4.0-test12/arch/ia64/sn/io/xbow.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/xbow.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,1866 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 1 +#define XBOW_DEBUG 1 + + +/* + * Files needed to get the device driver entry points + */ + +/* #include */ + +#include +#include +#include +#include + +#include +#include + + +#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) +#define DEL(ptr) (kfree(ptr)) + +int xbow_devflag = D_MP; + +/* + * This file supports the Xbow chip. Main functions: initializtion, + * error handling, and GBR. + */ + +/* + * each vertex corresponding to an xbow chip + * has a "fastinfo" pointer pointing at one + * of these things. + */ +typedef struct xbow_soft_s *xbow_soft_t; + +struct xbow_soft_s { + devfs_handle_t conn; /* our connection point */ + devfs_handle_t vhdl; /* xbow's private vertex */ + devfs_handle_t busv; /* the xswitch vertex */ + xbow_t *base; /* PIO pointer to crossbow chip */ + char *name; /* hwgraph name */ + + xbow_perf_t xbow_perfcnt[XBOW_PERF_COUNTERS]; + xbow_perf_link_t xbow_perflink[MAX_XBOW_PORTS]; + xbow_link_status_t xbow_link_status[MAX_XBOW_PORTS]; + lock_t xbow_perf_lock; + int link_monitor; + widget_cfg_t *wpio[MAX_XBOW_PORTS]; /* cached PIO pointer */ + + /* Bandwidth allocation state. Bandwidth values are for the + * destination port since contention happens there. + * Implicit mapping from xbow ports (8..f) -> (0..7) array indices. + */ + lock_t xbow_bw_alloc_lock; /* bw allocation lock */ + unsigned long long bw_hiwm[MAX_XBOW_PORTS]; /* hiwater mark values */ + unsigned long long bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */ +}; + +#define xbow_soft_set(v,i) hwgraph_fastinfo_set((v), (arbitrary_info_t)(i)) +#define xbow_soft_get(v) ((xbow_soft_t)hwgraph_fastinfo_get((v))) + +/* + * Function Table of Contents + */ + +void xbow_mlreset(xbow_t *); +void xbow_init(void); +int xbow_attach(devfs_handle_t); + +int xbow_open(devfs_handle_t *, int, int, cred_t *); +int xbow_close(devfs_handle_t, int, int, cred_t *); + +int xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint); +int xbow_unmap(devfs_handle_t, vhandl_t *); +int xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *); + +int xbow_widget_present(xbow_t *, int); +static int xbow_link_alive(xbow_t *, int); +devfs_handle_t xbow_widget_lookup(devfs_handle_t, int); + +#ifdef LATER +static void xbow_setwidint(xtalk_intr_t); +static void xbow_errintr_handler(intr_arg_t); +static error_handler_f xbow_error_handler; +#endif +void xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t); + + + +void xbow_update_perf_counters(devfs_handle_t); +xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t); +int xbow_enable_perf_counter(devfs_handle_t, int, int, int); +xbow_link_status_t *xbow_get_llp_status(devfs_handle_t); +void xbow_update_llp_status(devfs_handle_t); + +int xbow_disable_llp_monitor(devfs_handle_t); +int xbow_enable_llp_monitor(devfs_handle_t); + +#ifdef IRIX +int xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t, + unsigned long long, unsigned long long); +#else +int xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t, + unsigned long long, unsigned long long); +#endif + + +xswitch_reset_link_f xbow_reset_link; + +void idbg_xbowregs(int64_t); + +xswitch_provider_t xbow_provider = +{ + xbow_reset_link, +}; + +/* + * xbow_mlreset: called at mlreset time if the + * platform specific code determines that there is + * a crossbow in a critical path that must be + * functional before the driver would normally get + * the device properly set up. + * + * what do we need to do, that the boot prom can + * not be counted on to have already done, that is + * generic across all platforms using crossbows? + */ +/*ARGSUSED */ +void +xbow_mlreset(xbow_t * xbow) +{ +} + +/* + * xbow_init: called with the rest of the device + * driver XXX_init routines. This platform *might* + * have a Crossbow chip, or even several, but it + * might have none. Register with the crosstalk + * generic provider so when we encounter the chip + * the right magic happens. + */ +void +xbow_init(void) +{ + +#if DEBUG && ATTACH_DEBUG + printf("xbow_init\n"); +#endif + + xwidget_driver_register(XXBOW_WIDGET_PART_NUM, + 0, /* XXBOW_WIDGET_MFGR_NUM, */ + "xbow_", + CDL_PRI_HI); /* attach before friends */ + + xwidget_driver_register(XBOW_WIDGET_PART_NUM, + XBOW_WIDGET_MFGR_NUM, + "xbow_", + CDL_PRI_HI); /* attach before friends */ +} + +#ifdef XBRIDGE_REGS_SIM +/* xbow_set_simulated_regs: sets xbow regs as needed + * for powering through the boot + */ +void +xbow_set_simulated_regs(xbow_t *xbow, int port) +{ + /* + * turn on link + */ + xbow->xb_link(port).link_status = (1<<31); + /* + * and give it a live widget too + */ + xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT; + /* + * zero the link control reg + */ + xbow->xb_link(port).link_control = 0x0; +} +#endif /* XBRIDGE_REGS_SIM */ + +/* + * xbow_attach: the crosstalk provider has + * determined that there is a crossbow widget + * present, and has handed us the connection + * point for that vertex. + * + * We not only add our own vertex, but add + * some "xtalk switch" data to the switch + * vertex (at the connect point's parent) if + * it does not have any. + */ + +/*ARGSUSED */ +int +xbow_attach(devfs_handle_t conn) +{ + /*REFERENCED */ + devfs_handle_t vhdl; + devfs_handle_t busv; + xbow_t *xbow; + xbow_soft_t soft; + int port; + xswitch_info_t info; +#ifdef LATER + xtalk_intr_t intr_hdl; + device_desc_t dev_desc; +#endif + char devnm[MAXDEVNAME], *s; + xbowreg_t id; + int rev; + int i; + int xbow_num; + +#if DEBUG && ATTACH_DEBUG + cmn_err(CE_CONT, "%v: xbow_attach\n", conn); +#endif + + /* + * Get a PIO pointer to the base of the crossbow + * chip. + */ +#ifdef XBRIDGE_REGS_SIM + printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t)); + xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL); + /* + * turn on ports e and f like in a real live ibrick + */ + xbow_set_simulated_regs(xbow, 0xe); + xbow_set_simulated_regs(xbow, 0xf); +#else + xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0); +#endif /* XBRIDGE_REGS_SIM */ + + /* + * Locate the "switch" vertex: it is the parent + * of our connection point. + */ + busv = hwgraph_connectpt_get(conn); + printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow); + + ASSERT(busv != GRAPH_VERTEX_NONE); + + /* + * Create our private vertex, and connect our + * driver information to it. This makes it possible + * for diagnostic drivers to open the crossbow + * vertex for access to registers. + */ + + /* + * We need to teach xbow drivers to provide the right set of + * file ops. + */ + vhdl = NULL; + vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, + 0, DEVFS_FL_AUTO_DEVNUM, + 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + /* &hcl_fops */ (void *)&vhdl, NULL); + if (!vhdl) { + printk("xbow_attach: Unable to create char device for xbow conn +0x%p\n", + conn); + } + + /* + * Allocate the soft state structure and attach + * it to the xbow's vertex + */ + NEW(soft); + soft->conn = conn; + soft->vhdl = vhdl; + soft->busv = busv; + soft->base = xbow; + /* does the universe really need another macro? */ + /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */ + hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); + +#define XBOW_NUM_SUFFIX_FORMAT "[xbow# %d]" + + /* Add xbow number as a suffix to the hwgraph name of the xbow. + * This is helpful while looking at the error/warning messages. + */ +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC + xbow_num = 0; +#else + xbow_num = xswitch_id_get(busv); +#endif + + /* + * get the name of this xbow vertex and keep the info. + * This is needed during errors and interupts, but as + * long as we have it, we can use it elsewhere. + */ + s = dev_to_name(vhdl, devnm, MAXDEVNAME); + soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, + GFP_KERNEL); + sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num); + +#ifdef XBRIDGE_REGS_SIM + /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined + * as 0xd000, so I'm using that for the partnum bitfield. + */ + printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n"); + id = 0x2d000049; +#else + id = xbow->xb_wid_id; +#endif /* XBRIDGE_REGS_SIM */ + rev = XWIDGET_PART_REV_NUM(id); + + /* + * Print the revision if DEBUG, or SHOW_REVS and kdebug, + * or the xbow is downrev. + * + * If xbow is downrev, make it a WARNING that the + * Crossbow is DOWNREV: these chips are not good + * to have around, and the operator should be told. + */ +#ifdef IRIX +#if !DEBUG + if ( +#if SHOW_REVS + (kdebug) || +#endif /* SHOW_REVS */ + (rev < XBOW_REV_1_1)) +#endif /* !DEBUG */ + cmn_err((rev < XBOW_REV_1_1) ? CE_WARN : CE_CONT, + "%sCrossbow ASIC: rev %s (code=%d) at %s%s", + (rev < XBOW_REV_1_1) ? "DOWNREV " : "", + (rev == XBOW_REV_1_0) ? "1.0" : + (rev == XBOW_REV_1_1) ? "1.1" : + (rev == XBOW_REV_1_2) ? "1.2" : + (rev == XBOW_REV_1_3) ? "1.3" : + (rev == XBOW_REV_2_0) ? "2.0" : + (rev == XXBOW_PART_REV_1_0) ? "Xbridge 1.0" : + (rev == XXBOW_PART_REV_2_0) ? "Xbridge 2.0" : + "unknown", + rev, soft->name, + (rev < XBOW_REV_1_1) ? "" : "\n"); +#endif /* IRIX */ + + spinlock_init(&soft->xbow_perf_lock, "xbow_perf_lock"); + soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a; + soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b; + + /* Initialization for GBR bw allocation */ + spinlock_init(&soft->xbow_bw_alloc_lock, "xbow_bw_alloc_lock"); + +#define XBOW_8_BIT_PORT_BW_MAX (400 * 1000 * 1000) /* 400 MB/s */ +#define XBOW_16_BIT_PORT_BW_MAX (800 * 1000 * 1000) /* 800 MB/s */ + + /* Set bandwidth hiwatermark and current values */ + for (i = 0; i < MAX_XBOW_PORTS; i++) { + soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX; /* for now */ + soft->bw_cur_used[i] = 0; + } + + /* + * attach the crossbow error interrupt. + */ +#ifdef LATER + dev_desc = device_desc_dup(vhdl); + device_desc_flags_set(dev_desc, + device_desc_flags_get(dev_desc) | D_INTR_ISERR); + device_desc_intr_name_set(dev_desc, "Crossbow error"); + + intr_hdl = xtalk_intr_alloc(conn, dev_desc, vhdl); + ASSERT(intr_hdl != NULL); + + xtalk_intr_connect(intr_hdl, + (intr_func_t) xbow_errintr_handler, + (intr_arg_t) soft, + (xtalk_intr_setfunc_t) xbow_setwidint, + (void *) xbow, + (void *) 0); + device_desc_free(dev_desc); + + xwidget_error_register(conn, xbow_error_handler, soft); + +#else + printk("xbow_attach: Fixme: we bypassed attaching xbow error interrupt.\n"); +#endif /* LATER */ + + /* + * Enable xbow error interrupts + */ + xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | + XB_WID_CTRL_XTALK_IE); + + /* + * take a census of the widgets present, + * leaving notes at the switch vertex. + */ + info = xswitch_info_new(busv); + + for (port = MAX_PORT_NUM - MAX_XBOW_PORTS; + port < MAX_PORT_NUM; ++port) { + if (!xbow_link_alive(xbow, port)) { +#if DEBUG && XBOW_DEBUG + printk(KERN_INFO "0x%p link %d is not alive\n", + busv, port); +#endif + continue; + } + if (!xbow_widget_present(xbow, port)) { +#if DEBUG && XBOW_DEBUG + printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port); +#endif + continue; + } +#if DEBUG && XBOW_DEBUG + printk(KERN_INFO "0x%p link %d has a widget\n", + busv, port); +#endif + + xswitch_info_link_is_ok(info, port); + /* + * Turn some error interrupts on + * and turn others off. The PROM has + * some things turned on we don't + * want to see (bandwidth allocation + * errors for instance); so if it + * is not listed here, it is not on. + */ + xbow->xb_link(port).link_control = + ( (xbow->xb_link(port).link_control + /* + * Turn off these bits; they are non-fatal, + * but we might want to save some statistics + * on the frequency of these errors. + * XXX FIXME XXX + */ + & ~XB_CTRL_RCV_CNT_OFLOW_IE + & ~XB_CTRL_XMT_CNT_OFLOW_IE + & ~XB_CTRL_BNDWDTH_ALLOC_IE + & ~XB_CTRL_RCV_IE) + /* + * These are the ones we want to turn on. + */ + | (XB_CTRL_ILLEGAL_DST_IE + | XB_CTRL_OALLOC_IBUF_IE + | XB_CTRL_XMT_MAX_RTRY_IE + | XB_CTRL_MAXREQ_TOUT_IE + | XB_CTRL_XMT_RTRY_IE + | XB_CTRL_SRC_TOUT_IE) ); + } + + xswitch_provider_register(busv, &xbow_provider); + + return 0; /* attach successful */ +} + +/*ARGSUSED */ +int +xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp) +{ + if (!_CAP_CRABLE((uint64_t)credp, CAP_DEVICE_MGT)) + return EPERM; + return 0; + +} + +/*ARGSUSED */ +int +xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp) +{ + return 0; +} + +/*ARGSUSED */ +int +xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot) +{ + devfs_handle_t vhdl = dev_to_vhdl(dev); + xbow_soft_t soft = xbow_soft_get(vhdl); + int error; + + ASSERT(soft); + len = ctob(btoc(len)); + /* XXX- this ignores the offset!!! */ + error = v_mapphys(vt, (void *) soft->base, len); + return error; +} + +/*ARGSUSED */ +int +xbow_unmap(devfs_handle_t dev, vhandl_t *vt) +{ + return 0; +} + +/* This contains special-case code for grio. There are plans to make + * this general sometime in the future, but till then this should + * be good enough. + */ +xwidgetnum_t +xbow_widget_num_get(devfs_handle_t dev) +{ + devfs_handle_t tdev; + char devname[MAXDEVNAME]; + xwidget_info_t xwidget_info; + int i; +#if IP27 + cnodeid_t cnodeid = CNODEID_NONE; +#endif + + vertex_to_name(dev, devname, MAXDEVNAME); + +#if IP30 + /* If there is a ".connection" edge from this vertex, + * then it must be "/hw/node" vertex. Return the widget + * number for heart: 8. + */ + if (hwgraph_edge_get(dev, EDGE_LBL_CONN, &tdev) == + GRAPH_SUCCESS) { + return ((xwidgetnum_t) 8); + } +#elif IP27 + if ((cnodeid = nodevertex_to_cnodeid(dev)) != CNODEID_NONE) { + ASSERT(cnodeid < maxnodes); + return(hub_widget_id(COMPACT_TO_NASID_NODEID(cnodeid))); + } +#endif + + /* If this is a pci controller vertex, traverse up using + * the ".." links to get to the widget. + */ + if (strstr(devname, EDGE_LBL_PCI) && + strstr(devname, EDGE_LBL_CONTROLLER)) { + tdev = dev; + for (i=0; i< 2; i++) { + if (hwgraph_edge_get(tdev, + HWGRAPH_EDGELBL_DOTDOT, &tdev) != + GRAPH_SUCCESS) + return XWIDGET_NONE; + } + + if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) { + return (xwidget_info_id_get(xwidget_info)); + } else { + return XWIDGET_NONE; + } + } + + return XWIDGET_NONE; +} + +int +xbow_ioctl(devfs_handle_t dev, + int cmd, + void *arg, + int flag, + struct cred *cr, + int *rvalp) +{ + devfs_handle_t vhdl; + int error = 0; + +#if defined (DEBUG) + int rc; + devfs_handle_t conn; + struct xwidget_info_s *xwidget_info; + xbow_soft_t xbow_soft; +#endif + *rvalp = 0; + + vhdl = dev_to_vhdl(dev); +#if defined (DEBUG) + xbow_soft = xbow_soft_get(vhdl); + conn = xbow_soft->conn; + + xwidget_info = xwidget_info_get(conn); + ASSERT_ALWAYS(xwidget_info != NULL); + + rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid); + ASSERT_ALWAYS(rc != 0); +#endif + switch (cmd) { +#ifdef IRIX + case XBOWIOC_PERF_ENABLE: + case XBOWIOC_PERF_DISABLE: + { + struct xbow_perfarg_t xbow_perf_en; + + if (!_CAP_CRABLE(cr, CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + if ((flag & FWRITE) == 0) { + error = EBADF; + break; + } + if (COPYIN(arg, &xbow_perf_en, sizeof(xbow_perf_en))) { + error = EFAULT; + break; + } + if (error = xbow_enable_perf_counter(vhdl, + xbow_perf_en.link, + (cmd == XBOWIOC_PERF_DISABLE) ? 0 : xbow_perf_en.mode, + xbow_perf_en.counter)) { + error = EINVAL; + break; + } + break; + } +#endif + +#ifdef IRIX + case XBOWIOC_PERF_GET: + { + xbow_perf_link_t *xbow_perf_cnt; + + if ((flag & FREAD) == 0) { + error = EBADF; + break; + } + xbow_perf_cnt = xbow_get_perf_counters(vhdl); + ASSERT_ALWAYS(xbow_perf_cnt != NULL); + + if (COPYOUT((void *) xbow_perf_cnt, (void *) arg, + MAX_XBOW_PORTS * sizeof(xbow_perf_link_t))) { + error = EFAULT; + break; + } + break; + } +#endif + + case XBOWIOC_LLP_ERROR_ENABLE: + if (!_CAP_CRABLE((uint64_t)cr, CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + if ((error = xbow_enable_llp_monitor(vhdl)) != 0) + error = EINVAL; + + break; + + case XBOWIOC_LLP_ERROR_DISABLE: + + if (!_CAP_CRABLE((uint64_t)cr, CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + if ((error = xbow_disable_llp_monitor(vhdl)) != 0) + error = EINVAL; + + break; + +#ifdef IRIX + case XBOWIOC_LLP_ERROR_GET: + { + xbow_link_status_t *xbow_llp_status; + + if ((flag & FREAD) == 0) { + error = EBADF; + break; + } + xbow_llp_status = xbow_get_llp_status(vhdl); + ASSERT_ALWAYS(xbow_llp_status != NULL); + + if (COPYOUT((void *) xbow_llp_status, (void *) arg, + MAX_XBOW_PORTS * sizeof(xbow_link_status_t))) { + error = EFAULT; + break; + } + break; + } +#endif + +#ifdef IRIX + case GIOCSETBW: + { + grio_ioctl_info_t info; + xwidgetnum_t src_widgetnum, dest_widgetnum; + + if (!cap_able(CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + + if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { + error = EFAULT; + break; + } +#ifdef GRIO_DEBUG + printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n", + info.prev_vhdl, info.next_vhdl, info.reqbw); +#endif /* GRIO_DEBUG */ + + src_widgetnum = xbow_widget_num_get(info.prev_vhdl); + dest_widgetnum = xbow_widget_num_get(info.next_vhdl); + + /* Bandwidth allocation is bi-directional. Since bandwidth + * reservations have already been done at an earlier stage, + * we cannot fail here for lack of bandwidth. + */ + xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum, + 0, info.reqbw); + xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum, + 0, info.reqbw); + + break; + } + + case GIOCRELEASEBW: + { + grio_ioctl_info_t info; + xwidgetnum_t src_widgetnum, dest_widgetnum; + + if (!cap_able(CAP_DEVICE_MGT)) { + error = EPERM; + break; + } + + if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) { + error = EFAULT; + break; + } +#ifdef GRIO_DEBUG + printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n", + info.prev_vhdl, info.next_vhdl, info.reqbw); +#endif /* GRIO_DEBUG */ + + src_widgetnum = xbow_widget_num_get(info.prev_vhdl); + dest_widgetnum = xbow_widget_num_get(info.next_vhdl); + + /* Bandwidth reservation is bi-directional. Hence, remove + * bandwidth reservations for both directions. + */ + xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum, + info.reqbw, (-1 * info.reqbw)); + xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum, + info.reqbw, (-1 * info.reqbw)); + + break; + } +#endif + + default: + break; + + } + return error; +} + +/* + * xbow_widget_present: See if a device is present + * on the specified port of this crossbow. + */ +int +xbow_widget_present(xbow_t * xbow, int port) +{ + if ( IS_RUNNING_ON_SIMULATOR() ) { + if ( (port == 14) || (port == 15) ) { + return 1; + } + else { + return 0; + } + } + else { + return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT; + } +} + +static int +xbow_link_alive(xbow_t * xbow, int port) +{ + xbwX_stat_t xbow_linkstat; + + xbow_linkstat.linkstatus = xbow->xb_link(port).link_status; + return (xbow_linkstat.link_alive); +} + +/* + * xbow_widget_lookup + * Lookup the edges connected to the xbow specified, and + * retrieve the handle corresponding to the widgetnum + * specified. + * If not found, return 0. + */ +devfs_handle_t +xbow_widget_lookup(devfs_handle_t vhdl, + int widgetnum) +{ + xswitch_info_t xswitch_info; + devfs_handle_t conn; + + xswitch_info = xswitch_info_get(vhdl); + conn = xswitch_info_vhdl_get(xswitch_info, widgetnum); + return conn; +} + +/* + * xbow_setwidint: called when xtalk + * is establishing or migrating our + * interrupt service. + */ +#ifdef LATER +static void +xbow_setwidint(xtalk_intr_t intr) +{ + xwidgetnum_t targ = xtalk_intr_target_get(intr); + iopaddr_t addr = xtalk_intr_addr_get(intr); + xtalk_intr_vector_t vect = xtalk_intr_vector_get(intr); + xbow_t *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr); + + xbow_intr_preset((void *) xbow, 0, targ, addr, vect); +} +#endif /* LATER */ + +/* + * xbow_intr_preset: called during mlreset time + * if the platform specific code needs to route + * an xbow interrupt before the xtalk infrastructure + * is available for use. + * + * Also called from xbow_setwidint, so we don't + * replicate the guts of the routine. + * + * XXX- probably should be renamed xbow_wid_intr_set or + * something to reduce confusion. + */ +/*ARGSUSED3 */ +void +xbow_intr_preset(void *which_widget, + int which_widget_intr, + xwidgetnum_t targ, + iopaddr_t addr, + xtalk_intr_vector_t vect) +{ + xbow_t *xbow = (xbow_t *) which_widget; + + xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) | + (0x000F0000 & (targ << 16)) | + XTALK_ADDR_TO_UPPER(addr)); + xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr); +} + +#define XEM_ADD_STR(s) cmn_err(CE_CONT, "%s", (s)) +#define XEM_ADD_NVAR(n,v) cmn_err(CE_CONT, "\t%20s: 0x%x\n", (n), (v)) +#define XEM_ADD_VAR(v) XEM_ADD_NVAR(#v,(v)) +#define XEM_ADD_IOEF(n) if (IOERROR_FIELDVALID(ioe,n)) \ + XEM_ADD_NVAR("ioe." #n, \ + IOERROR_GETVALUE(ioe,n)) + +#ifdef IRIX +static void +xem_add_ioe(ioerror_t *ioe) +{ + XEM_ADD_IOEF(errortype); + XEM_ADD_IOEF(widgetnum); + XEM_ADD_IOEF(widgetdev); + XEM_ADD_IOEF(srccpu); + XEM_ADD_IOEF(srcnode); + XEM_ADD_IOEF(errnode); + XEM_ADD_IOEF(sysioaddr); + XEM_ADD_IOEF(xtalkaddr); + XEM_ADD_IOEF(busspace); + XEM_ADD_IOEF(busaddr); + XEM_ADD_IOEF(vaddr); + XEM_ADD_IOEF(memaddr); + XEM_ADD_IOEF(epc); + XEM_ADD_IOEF(ef); +} + +#define XEM_ADD_IOE() (xem_add_ioe(ioe)) +#endif /* IRIX */ + +int xbow_xmit_retry_errors = 0; + +int +xbow_xmit_retry_error(xbow_soft_t soft, + int port) +{ + xswitch_info_t info; + devfs_handle_t vhdl; + widget_cfg_t *wid; + widgetreg_t id; + int part; + int mfgr; + + wid = soft->wpio[port - BASE_XBOW_PORT]; + if (wid == NULL) { + /* If we can't track down a PIO + * pointer to our widget yet, + * leave our caller knowing that + * we are interested in this + * interrupt if it occurs in + * the future. + */ + info = xswitch_info_get(soft->busv); + if (!info) + return 1; + vhdl = xswitch_info_vhdl_get(info, port); + if (vhdl == GRAPH_VERTEX_NONE) + return 1; + wid = (widget_cfg_t *) xtalk_piotrans_addr + (vhdl, 0, 0, sizeof *wid, 0); + if (!wid) + return 1; + soft->wpio[port - BASE_XBOW_PORT] = wid; + } + id = wid->w_id; + part = XWIDGET_PART_NUM(id); + mfgr = XWIDGET_MFG_NUM(id); + + /* If this thing is not a Bridge, + * do not activate the WAR, and + * tell our caller we do not need + * to be called again. + */ + if ((part != BRIDGE_WIDGET_PART_NUM) || + (mfgr != BRIDGE_WIDGET_MFGR_NUM)) { + /* FIXME: add Xbridge to the WAR. + * Shouldn't hurt anything. Later need to + * check if we can remove this. + */ + if ((part != XBRIDGE_WIDGET_PART_NUM) || + (mfgr != XBRIDGE_WIDGET_MFGR_NUM)) + return 0; + } + + /* count how many times we + * have picked up after + * LLP Transmit problems. + */ + xbow_xmit_retry_errors++; + + /* rewrite the control register + * to fix things up. + */ + wid->w_control = wid->w_control; + wid->w_control; + + return 1; +} + +/* + * xbow_errintr_handler will be called if the xbow + * sends an interrupt request to report an error. + */ + +#ifdef LATER +static void +xbow_errintr_handler(intr_arg_t arg) +{ +#ifdef IRIX + ioerror_t ioe[1]; + xbow_soft_t soft = (xbow_soft_t) arg; + xbow_t *xbow = soft->base; + xbowreg_t wid_control; + xbowreg_t wid_stat; + xbowreg_t wid_err_cmdword; + xbowreg_t wid_err_upper; + xbowreg_t wid_err_lower; + w_err_cmd_word_u wid_err; + uint64_t wid_err_addr; + + int fatal = 0; + int dump_ioe = 0; + + wid_control = xbow->xb_wid_control; + wid_stat = xbow->xb_wid_stat_clr; + wid_err_cmdword = xbow->xb_wid_err_cmdword; + wid_err_upper = xbow->xb_wid_err_upper; + wid_err_lower = xbow->xb_wid_err_lower; + xbow->xb_wid_err_cmdword = 0; + + wid_err_addr = + wid_err_lower + | (((iopaddr_t) wid_err_upper + & WIDGET_ERR_UPPER_ADDR_ONLY) + << 32); + + if (wid_stat & XB_WID_STAT_LINK_INTR_MASK) { + int port; + + wid_err.r = wid_err_cmdword; + + for (port = MAX_PORT_NUM - MAX_XBOW_PORTS; + port < MAX_PORT_NUM; port++) { + if (wid_stat & XB_WID_STAT_LINK_INTR(port)) { + xb_linkregs_t *link = &(xbow->xb_link(port)); + xbowreg_t link_control = link->link_control; + xbowreg_t link_status = link->link_status_clr; + xbowreg_t link_aux_status = link->link_aux_status; + xbowreg_t link_pend; + + link_pend = link_status & link_control & + (XB_STAT_ILLEGAL_DST_ERR + | XB_STAT_OALLOC_IBUF_ERR + | XB_STAT_RCV_CNT_OFLOW_ERR + | XB_STAT_XMT_CNT_OFLOW_ERR + | XB_STAT_XMT_MAX_RTRY_ERR + | XB_STAT_RCV_ERR + | XB_STAT_XMT_RTRY_ERR + | XB_STAT_MAXREQ_TOUT_ERR + | XB_STAT_SRC_TOUT_ERR + ); + + if (link_pend & XB_STAT_ILLEGAL_DST_ERR) { + if (wid_err.f.sidn == port) { + IOERROR_INIT(ioe); + IOERROR_SETVALUE(ioe, widgetnum, port); + IOERROR_SETVALUE(ioe, xtalkaddr, wid_err_addr); + if (IOERROR_HANDLED == + xbow_error_handler(soft, + IOECODE_DMA, + MODE_DEVERROR, + ioe)) { + link_pend &= ~XB_STAT_ILLEGAL_DST_ERR; + } else { + dump_ioe++; + } + } + } + /* Xbow/Bridge WAR: + * if the bridge signals an LLP Transmitter Retry, + * rewrite its control register. + * If someone else triggers this interrupt, + * ignore (and disable) the interrupt. + */ + if (link_pend & XB_STAT_XMT_RTRY_ERR) { + if (!xbow_xmit_retry_error(soft, port)) { + link_control &= ~XB_CTRL_XMT_RTRY_IE; + link->link_control = link_control; + link->link_control; /* stall until written */ + } + link_pend &= ~XB_STAT_XMT_RTRY_ERR; + } + if (link_pend) { + devfs_handle_t xwidget_vhdl; + char *xwidget_name; + + /* Get the widget name corresponding to the current + * xbow link. + */ + xwidget_vhdl = xbow_widget_lookup(soft->busv,port); + xwidget_name = xwidget_name_get(xwidget_vhdl); + +#ifdef IRIX + cmn_err(CE_CONT, + "%s port %X[%s] XIO Bus Error", + soft->name, port, xwidget_name); + if (link_status & XB_STAT_MULTI_ERR) + XEM_ADD_STR("\tMultiple Errors\n"); + if (link_status & XB_STAT_ILLEGAL_DST_ERR) + XEM_ADD_STR("\tInvalid Packet Destination\n"); + if (link_status & XB_STAT_OALLOC_IBUF_ERR) + XEM_ADD_STR("\tInput Overallocation Error\n"); + if (link_status & XB_STAT_RCV_CNT_OFLOW_ERR) + XEM_ADD_STR("\tLLP receive error counter overflow\n"); + if (link_status & XB_STAT_XMT_CNT_OFLOW_ERR) + XEM_ADD_STR("\tLLP transmit retry counter overflow\n"); + if (link_status & XB_STAT_XMT_MAX_RTRY_ERR) + XEM_ADD_STR("\tLLP Max Transmitter Retry\n"); + if (link_status & XB_STAT_RCV_ERR) + XEM_ADD_STR("\tLLP Receiver error\n"); + if (link_status & XB_STAT_XMT_RTRY_ERR) + XEM_ADD_STR("\tLLP Transmitter Retry\n"); + if (link_status & XB_STAT_MAXREQ_TOUT_ERR) + XEM_ADD_STR("\tMaximum Request Timeout\n"); + if (link_status & XB_STAT_SRC_TOUT_ERR) + XEM_ADD_STR("\tSource Timeout Error\n"); +#endif + + { + int other_port; + + for (other_port = 8; other_port < 16; ++other_port) { + if (link_aux_status & (1 << other_port)) { + /* XXX- need to go to "other_port" + * and clean up after the timeout? + */ + XEM_ADD_VAR(other_port); + } + } + } + +#if !DEBUG + if (kdebug) { +#endif + XEM_ADD_VAR(link_control); + XEM_ADD_VAR(link_status); + XEM_ADD_VAR(link_aux_status); + + if (dump_ioe) { + XEM_ADD_IOE(); + dump_ioe = 0; + } +#if !DEBUG + } +#endif + fatal++; + } + } + } + } + if (wid_stat & wid_control & XB_WID_STAT_WIDGET0_INTR) { + /* we have a "widget zero" problem */ + + if (wid_stat & (XB_WID_STAT_MULTI_ERR + | XB_WID_STAT_XTALK_ERR + | XB_WID_STAT_REG_ACC_ERR)) { + + cmn_err(CE_CONT, + "%s Port 0 XIO Bus Error", + soft->name); + if (wid_stat & XB_WID_STAT_MULTI_ERR) + XEM_ADD_STR("\tMultiple Error\n"); + if (wid_stat & XB_WID_STAT_XTALK_ERR) + XEM_ADD_STR("\tXIO Error\n"); + if (wid_stat & XB_WID_STAT_REG_ACC_ERR) + XEM_ADD_STR("\tRegister Access Error\n"); + + fatal++; + } + } + if (fatal) { + XEM_ADD_VAR(wid_stat); + XEM_ADD_VAR(wid_control); + XEM_ADD_VAR(wid_err_cmdword); + XEM_ADD_VAR(wid_err_upper); + XEM_ADD_VAR(wid_err_lower); + XEM_ADD_VAR(wid_err_addr); + cmn_err_tag(8, CE_PANIC, "XIO Bus Error"); + } +#endif +} +#endif /* LATER */ + +/* + * XBOW ERROR Handling routines. + * These get invoked as part of walking down the error handling path + * from hub/heart towards the I/O device that caused the error. + */ + +/* + * xbow_error_handler + * XBow error handling dispatch routine. + * This is the primary interface used by external world to invoke + * in case of an error related to a xbow. + * Only functionality in this layer is to identify the widget handle + * given the widgetnum. Otherwise, xbow does not gathers any error + * data. + */ + +#ifdef LATER +static int +xbow_error_handler( + void *einfo, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioerror) +{ +#ifdef IRIX + int retval = IOERROR_WIDGETLEVEL; + + xbow_soft_t soft = (xbow_soft_t) einfo; + int port; + devfs_handle_t conn; + devfs_handle_t busv; + + xbow_t *xbow = soft->base; + xbowreg_t wid_stat; + xbowreg_t wid_err_cmdword; + xbowreg_t wid_err_upper; + xbowreg_t wid_err_lower; + uint64_t wid_err_addr; + + xb_linkregs_t *link; + xbowreg_t link_control; + xbowreg_t link_status; + xbowreg_t link_aux_status; + + ASSERT(soft != 0); + busv = soft->busv; + +#if DEBUG && ERROR_DEBUG + cmn_err(CE_CONT, "%s: xbow_error_handler\n", soft->name, busv); +#endif + + port = IOERROR_GETVALUE(ioerror, widgetnum); + + if (port == 0) { + /* error during access to xbow: + * do NOT attempt to access xbow regs. + */ + if (mode == MODE_DEVPROBE) + return IOERROR_HANDLED; + + if (error_code & IOECODE_DMA) { + cmn_err(CE_ALERT, + "DMA error blamed on Crossbow at %s\n" + "\tbut Crosbow never initiates DMA!", + soft->name); + } + if (error_code & IOECODE_PIO) { + cmn_err(CE_ALERT, + "PIO Error on XIO Bus %s\n" + "\tattempting to access XIO controller\n" + "\twith offset 0x%X", + soft->name, + IOERROR_GETVALUE(ioerror, xtalkaddr)); + } + /* caller will dump contents of ioerror + * in DEBUG and kdebug kernels. + */ + + return retval; + } + /* + * error not on port zero: + * safe to read xbow registers. + */ + wid_stat = xbow->xb_wid_stat; + wid_err_cmdword = xbow->xb_wid_err_cmdword; + wid_err_upper = xbow->xb_wid_err_upper; + wid_err_lower = xbow->xb_wid_err_lower; + + wid_err_addr = + wid_err_lower + | (((iopaddr_t) wid_err_upper + & WIDGET_ERR_UPPER_ADDR_ONLY) + << 32); + + if ((port < BASE_XBOW_PORT) || + (port >= MAX_PORT_NUM)) { + + if (mode == MODE_DEVPROBE) + return IOERROR_HANDLED; + + if (error_code & IOECODE_DMA) { + cmn_err(CE_ALERT, + "DMA error blamed on XIO port at %s/%d\n" + "\tbut Crossbow does not support that port", + soft->name, port); + } + if (error_code & IOECODE_PIO) { + cmn_err(CE_ALERT, + "PIO Error on XIO Bus %s\n" + "\tattempting to access XIO port %d\n" + "\t(which Crossbow does not support)" + "\twith offset 0x%X", + soft->name, port, + IOERROR_GETVALUE(ioerror, xtalkaddr)); + } +#if !DEBUG + if (kdebug) { +#endif + XEM_ADD_STR("Raw status values for Crossbow:\n"); + XEM_ADD_VAR(wid_stat); + XEM_ADD_VAR(wid_err_cmdword); + XEM_ADD_VAR(wid_err_upper); + XEM_ADD_VAR(wid_err_lower); + XEM_ADD_VAR(wid_err_addr); +#if !DEBUG + } +#endif + + /* caller will dump contents of ioerror + * in DEBUG and kdebug kernels. + */ + + return retval; + } + /* access to valid port: + * ok to check port status. + */ + + link = &(xbow->xb_link(port)); + link_control = link->link_control; + link_status = link->link_status; + link_aux_status = link->link_aux_status; + + /* Check that there is something present + * in that XIO port. + */ + if (!(link_aux_status & XB_AUX_STAT_PRESENT)) { + /* nobody connected. */ + if (mode == MODE_DEVPROBE) + return IOERROR_HANDLED; + + if (error_code & IOECODE_DMA) { + cmn_err(CE_ALERT, + "DMA error blamed on XIO port at %s/%d\n" + "\tbut there is no device connected there.", + soft->name, port); + } + if (error_code & IOECODE_PIO) { + cmn_err(CE_ALERT, + "PIO Error on XIO Bus %s\n" + "\tattempting to access XIO port %d\n" + "\t(which has no device connected)" + "\twith offset 0x%X", + soft->name, port, + IOERROR_GETVALUE(ioerror, xtalkaddr)); + } +#if !DEBUG + if (kdebug) { +#endif + XEM_ADD_STR("Raw status values for Crossbow:\n"); + XEM_ADD_VAR(wid_stat); + XEM_ADD_VAR(wid_err_cmdword); + XEM_ADD_VAR(wid_err_upper); + XEM_ADD_VAR(wid_err_lower); + XEM_ADD_VAR(wid_err_addr); + XEM_ADD_VAR(port); + XEM_ADD_VAR(link_control); + XEM_ADD_VAR(link_status); + XEM_ADD_VAR(link_aux_status); +#if !DEBUG + } +#endif + return retval; + + } + /* Check that the link is alive. + */ + if (!(link_status & XB_STAT_LINKALIVE)) { + /* nobody connected. */ + if (mode == MODE_DEVPROBE) + return IOERROR_HANDLED; + + cmn_err(CE_ALERT, + "%s%sError on XIO Bus %s port %d", + (error_code & IOECODE_DMA) ? "DMA " : "", + (error_code & IOECODE_PIO) ? "PIO " : "", + soft->name, port); + + if ((error_code & IOECODE_PIO) && + (IOERROR_FIELDVALID(ioerror, xtalkaddr))) { + cmn_err(CE_CONT, + "\tAccess attempted to offset 0x%X\n", + IOERROR_GETVALUE(ioerror, xtalkaddr)); + } + if (link_aux_status & XB_AUX_LINKFAIL_RST_BAD) + XEM_ADD_STR("\tLink never came out of reset\n"); + else + XEM_ADD_STR("\tLink failed while transferring data\n"); + + } + /* get the connection point for the widget + * involved in this error; if it exists and + * is not our connectpoint, cycle back through + * xtalk_error_handler to deliver control to + * the proper handler (or to report a generic + * crosstalk error). + * + * If the downstream handler won't handle + * the problem, we let our upstream caller + * deal with it, after (in DEBUG and kdebug + * kernels) dumping the xbow state for this + * port. + */ + conn = xbow_widget_lookup(busv, port); + if ((conn != GRAPH_VERTEX_NONE) && + (conn != soft->conn)) { + retval = xtalk_error_handler(conn, error_code, mode, ioerror); + if (retval == IOERROR_HANDLED) + return IOERROR_HANDLED; + } + if (mode == MODE_DEVPROBE) + return IOERROR_HANDLED; + + if (retval == IOERROR_UNHANDLED) { + retval = IOERROR_PANIC; + + cmn_err(CE_ALERT, + "%s%sError on XIO Bus %s port %d", + (error_code & IOECODE_DMA) ? "DMA " : "", + (error_code & IOECODE_PIO) ? "PIO " : "", + soft->name, port); + + if ((error_code & IOECODE_PIO) && + (IOERROR_FIELDVALID(ioerror, xtalkaddr))) { + cmn_err(CE_CONT, + "\tAccess attempted to offset 0x%X\n", + IOERROR_GETVALUE(ioerror, xtalkaddr)); + } + } + +#if !DEBUG + if (kdebug) { +#endif + XEM_ADD_STR("Raw status values for Crossbow:\n"); + XEM_ADD_VAR(wid_stat); + XEM_ADD_VAR(wid_err_cmdword); + XEM_ADD_VAR(wid_err_upper); + XEM_ADD_VAR(wid_err_lower); + XEM_ADD_VAR(wid_err_addr); + XEM_ADD_VAR(port); + XEM_ADD_VAR(link_control); + XEM_ADD_VAR(link_status); + XEM_ADD_VAR(link_aux_status); +#if !DEBUG + } +#endif + /* caller will dump raw ioerror data + * in DEBUG and kdebug kernels. + */ + + return retval; +#endif /* IRIX */ +} + +#endif /* LATER */ + +void +xbow_update_perf_counters(devfs_handle_t vhdl) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; + xbow_perf_link_t *xbow_plink = xbow_soft->xbow_perflink; + xbow_perfcount_t perf_reg; + int link, s, i; + + for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) { + if (xbow_perf->xp_mode == XBOW_MONITOR_NONE) + continue; + + s = mutex_spinlock(&xbow_soft->xbow_perf_lock); + + perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; + + link = perf_reg.xb_perf.link_select; + + (xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] += + ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK); + xbow_perf->xp_current = perf_reg.xb_perf.count; + + mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); + } + /* Do port /mode multiplexing here */ + +#ifdef IRIX + (void) timeout(xbow_update_perf_counters, + (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT); +#endif + +} + +xbow_perf_link_t * +xbow_get_perf_counters(devfs_handle_t vhdl) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + xbow_perf_link_t *xbow_perf_link = xbow_soft->xbow_perflink; + + return xbow_perf_link; +} + +int +xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + xbow_perf_t *xbow_perf = xbow_soft->xbow_perfcnt; + xbow_linkctrl_t xbow_link_ctrl; + xbow_t *xbow = xbow_soft->base; + xbow_perfcount_t perf_reg; + int s, i; + + link -= BASE_XBOW_PORT; + if ((link < 0) || (link >= MAX_XBOW_PORTS)) + return -1; + + if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK)) + return -1; + + if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS)) + return -1; + + s = mutex_spinlock(&xbow_soft->xbow_perf_lock); + + if ((xbow_perf + counter)->xp_mode && mode) { + mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); + return -1; + } + for (i = 0; i < XBOW_PERF_COUNTERS; i++) { + if (i == counter) + continue; + if (((xbow_perf + i)->xp_link == link) && + ((xbow_perf + i)->xp_mode)) { + mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); + return -1; + } + } + xbow_perf += counter; + + xbow_perf->xp_curlink = xbow_perf->xp_link = link; + xbow_perf->xp_curmode = xbow_perf->xp_mode = mode; + + xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control; + xbow_link_ctrl.xb_linkcontrol.perf_mode = mode; + xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword; + + perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg; + perf_reg.xb_perf.link_select = link; + *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val; + xbow_perf->xp_current = perf_reg.xb_perf.count; + +#ifdef IRIX + (void) timeout(xbow_update_perf_counters, + (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT); +#endif + + mutex_spinunlock(&xbow_soft->xbow_perf_lock, s); + + return 0; +} + +xbow_link_status_t * +xbow_get_llp_status(devfs_handle_t vhdl) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; + + return xbow_llp_status; +} + +void +xbow_update_llp_status(devfs_handle_t vhdl) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + xbow_link_status_t *xbow_llp_status = xbow_soft->xbow_link_status; + xbow_t *xbow; + xbwX_stat_t lnk_sts; + xbow_aux_link_status_t aux_sts; + int link; + devfs_handle_t xwidget_vhdl; + char *xwidget_name; + + xbow = (xbow_t *) xbow_soft->base; + for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) { + /* Get the widget name corresponding the current link. + * Note : 0 <= link < MAX_XBOW_PORTS(8). + * BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10) + */ + xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT); + xwidget_name = xwidget_name_get(xwidget_vhdl); + aux_sts.aux_linkstatus + = xbow->xb_link_raw[link].link_aux_status; + lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr; + + if (lnk_sts.link_alive == 0) + continue; + + xbow_llp_status->rx_err_count += + aux_sts.xb_aux_linkstatus.rx_err_cnt; + + xbow_llp_status->tx_retry_count += + aux_sts.xb_aux_linkstatus.tx_retry_cnt; + + if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) { +#ifdef IRIX + cmn_err(CE_WARN, "link %d[%s]: bad status 0x%x\n", + link, xwidget_name, lnk_sts.linkstatus); +#endif + } + } +#ifdef IRIX + if (xbow_soft->link_monitor) + (void) timeout(xbow_update_llp_status, + (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT); +#endif +} + +int +xbow_disable_llp_monitor(devfs_handle_t vhdl) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + int port; + + for (port = 0; port < MAX_XBOW_PORTS; port++) { + xbow_soft->xbow_link_status[port].rx_err_count = 0; + xbow_soft->xbow_link_status[port].tx_retry_count = 0; + } + + xbow_soft->link_monitor = 0; + return 0; +} + +int +xbow_enable_llp_monitor(devfs_handle_t vhdl) +{ + xbow_soft_t xbow_soft = xbow_soft_get(vhdl); + +#ifdef IRIX + (void) timeout(xbow_update_llp_status, + (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT); +#endif + xbow_soft->link_monitor = 1; + return 0; +} + + +int +xbow_reset_link(devfs_handle_t xconn_vhdl) +{ + xwidget_info_t widget_info; + xwidgetnum_t port; + xbow_t *xbow; + xbowreg_t ctrl; + xbwX_stat_t stat; + unsigned itick; + unsigned dtick; + static int ticks_per_ms = 0; + + if (!ticks_per_ms) { + itick = get_timestamp(); + us_delay(1000); + ticks_per_ms = get_timestamp() - itick; + } + widget_info = xwidget_info_get(xconn_vhdl); + port = xwidget_info_id_get(widget_info); + +#ifdef XBOW_K1PTR /* defined if we only have one xbow ... */ + xbow = XBOW_K1PTR; +#else + { + devfs_handle_t xbow_vhdl; + xbow_soft_t xbow_soft; + + hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl); + xbow_soft = xbow_soft_get(xbow_vhdl); + xbow = xbow_soft->base; + } +#endif + + /* + * This requires three PIOs (reset the link, check for the + * reset, restore the control register for the link) plus + * 10us to wait for the reset. We allow up to 1ms for the + * widget to come out of reset before giving up and + * returning a failure. + */ + ctrl = xbow->xb_link(port).link_control; + xbow->xb_link(port).link_reset = 0; + itick = get_timestamp(); + while (1) { + stat.linkstatus = xbow->xb_link(port).link_status; + if (stat.link_alive) + break; + dtick = get_timestamp() - itick; + if (dtick > ticks_per_ms) { + return -1; /* never came out of reset */ + } + DELAY(2); /* don't beat on link_status */ + } + xbow->xb_link(port).link_control = ctrl; + return 0; +} + +/* + * Dump xbow registers. + * input parameter is either a pointer to + * the xbow chip or the vertex handle for + * an xbow vertex. + */ +void +idbg_xbowregs(int64_t regs) +{ + xbow_t *xbow; + int i; + xb_linkregs_t *link; + +#ifdef IRIX + if (dev_is_vertex((devfs_handle_t) regs)) { + devfs_handle_t vhdl = (devfs_handle_t) regs; + xbow_soft_t soft = xbow_soft_get(vhdl); + + xbow = soft->base; + } else +#endif + { + xbow = (xbow_t *) regs; + } + +#ifdef IRIX + qprintf("Printing xbow registers starting at 0x%x\n", xbow); + qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n", + xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper, + xbow->xb_wid_err_lower, xbow->xb_wid_control, + xbow->xb_wid_req_timeout); + qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n", + xbow->xb_wid_int_upper, xbow->xb_wid_int_lower, + xbow->xb_wid_err_cmdword, xbow->xb_wid_llp, + xbow->xb_wid_arb_reload); +#endif + + for (i = 8; i <= 0xf; i++) { + link = &xbow->xb_link(i); +#ifdef IRIX + qprintf("Link %d registers\n", i); + qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n", + link->link_control, link->link_status, + link->link_arb_upper, link->link_arb_lower, + link->link_aux_status); +#endif + } +} + + +#define XBOW_ARB_RELOAD_TICKS 25 + /* granularity: 4 MB/s, max: 124 MB/s */ +#define GRANULARITY ((100 * 1000000) / XBOW_ARB_RELOAD_TICKS) + +#define XBOW_BYTES_TO_GBR(BYTES_per_s) (int) (BYTES_per_s / GRANULARITY) + +#define XBOW_GBR_TO_BYTES(cnt) (bandwidth_t) ((cnt) * GRANULARITY) + +#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec) \ + ((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr) + +#define XBOW_ARB_GBR_MAX 31 + +#define ABS(x) ((x > 0) ? (x) : (-1 * x)) + /* absolute value */ + +int +xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec) +{ + int gbr_granted; + int new_total_gbr; + int change_gbr; + bandwidth_t new_total_bw; + +#ifdef GRIO_DEBUG + printf("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n", + old_bytes_per_sec, bytes_per_sec); +#endif /* GRIO_DEBUG */ + + gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)), + old_bytes_per_sec); + new_total_bw = old_bytes_per_sec + bytes_per_sec; + new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)), + new_total_bw); + + change_gbr = new_total_gbr - gbr_granted; + +#ifdef GRIO_DEBUG + printf("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n", + gbr_granted, new_total_gbr, change_gbr); +#endif /* GRIO_DEBUG */ + + return (change_gbr); +} + +/* Conversion from GBR to bytes */ +bandwidth_t +xbow_gbr_to_bytes(int gbr) +{ + return (XBOW_GBR_TO_BYTES(gbr)); +} + +/* Given the vhdl for the desired xbow, the src and dest. widget ids + * and the req_bw value, this xbow driver entry point accesses the + * xbow registers and allocates the desired bandwidth if available. + * + * If bandwidth allocation is successful, return success else return failure. + */ +int +xbow_prio_bw_alloc(devfs_handle_t vhdl, + xwidgetnum_t src_wid, + xwidgetnum_t dest_wid, + unsigned long long old_alloc_bw, + unsigned long long req_bw) +{ + xbow_soft_t soft = xbow_soft_get(vhdl); + volatile xbowreg_t *xreg; + xbowreg_t mask; + int s; + int error = 0; + bandwidth_t old_bw_BYTES, req_bw_BYTES; + xbowreg_t old_xreg; + int old_bw_GBR, req_bw_GBR, new_bw_GBR; + +#ifdef GRIO_DEBUG + printf("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n", + (int) vhdl, (int) src_wid, (int) dest_wid, req_bw); +#endif + + ASSERT(XBOW_WIDGET_IS_VALID(src_wid)); + ASSERT(XBOW_WIDGET_IS_VALID(dest_wid)); + + s = mutex_spinlock(&soft->xbow_bw_alloc_lock); + + /* Get pointer to the correct register */ + xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid); + + /* Get mask for GBR count value */ + mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid); + + req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw); + req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR))) + : xbow_gbr_to_bytes(req_bw_GBR); + +#ifdef GRIO_DEBUG + printf("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n", + req_bw, req_bw_BYTES, req_bw_GBR); +#endif /* GRIO_DEBUG */ + + old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS]; + old_xreg = *xreg; + old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid)); + +#ifdef GRIO_DEBUG + ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR); + + printf("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR); + + printf("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n", + req_bw_BYTES, old_bw_BYTES, + soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]); + +#endif /* GRIO_DEBUG */ + + /* Accept the request only if we don't exceed the destination + * port HIWATER_MARK *AND* the max. link GBR arbitration count + */ + if (((old_bw_BYTES + req_bw_BYTES) <= + soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) && + (req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) { + + new_bw_GBR = (old_bw_GBR + req_bw_GBR); + + /* Set this in the xbow link register */ + *xreg = (old_xreg & ~mask) | \ + (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask); + + soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] = + xbow_gbr_to_bytes(new_bw_GBR); + } else { + error = 1; + } + + mutex_spinunlock(&soft->xbow_bw_alloc_lock, s); + + return (error); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/xswitch.c linux-2.4.0-test12-lia/arch/ia64/sn/io/xswitch.c --- linux-2.4.0-test12/arch/ia64/sn/io/xswitch.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/xswitch.c Wed Nov 15 19:11:35 2000 @@ -0,0 +1,268 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) +#define DEL(ptr) (kfree(ptr)) + +int xswitch_devflag = D_MP; + +/* + * This file provides generic support for Crosstalk + * Switches, in a way that insulates crosstalk providers + * from specifics about the switch chips being used. + */ + +#include +#define DEV_FUNC(dev,func) xbow_##func + +#if !defined(DEV_FUNC) +/* + * There is more than one possible provider + * for this platform. We need to examine the + * master vertex of the current vertex for + * a provider function structure, and indirect + * through the appropriately named member. + */ +#define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func + +static xswitch_provider_t * +xwidget_to_provider_fns(devfs_handle_t xconn) +{ + devfs_handle_t busv; + xswitch_info_t xswitch_info; + xswitch_provider_t provider_fns; + + busv = hwgraph_connectpt_get(xconn_vhdl); + ASSERT(busv != GRAPH_VERTEX_NONE); + + xswitch_info = xswitch_info_get(busv); + ASSERT(xswitch_info != NULL); + + provider_fns = xswitch_info->xswitch_fns; + ASSERT(provider_fns != NULL); + + return provider_fns; +} +#endif + +#define XSWITCH_CENSUS_BIT(port) (1<<(port)) +#define XSWITCH_CENSUS_PORT_MIN (0x0) +#define XSWITCH_CENSUS_PORT_MAX (0xF) +#define XSWITCH_CENSUS_PORTS (0x10) +#define XSWITCH_WIDGET_PRESENT(infop,port) ((infop)->census & XSWITCH_CENSUS_BIT(port)) + +static char xswitch_info_fingerprint[] = "xswitch_info"; + +struct xswitch_info_s { + char *fingerprint; + unsigned census; + devfs_handle_t vhdl[XSWITCH_CENSUS_PORTS]; + devfs_handle_t master_vhdl[XSWITCH_CENSUS_PORTS]; + xswitch_provider_t *xswitch_fns; +}; + +xswitch_info_t +xswitch_info_get(devfs_handle_t xwidget) +{ + xswitch_info_t xswitch_info; + + xswitch_info = (xswitch_info_t) + hwgraph_fastinfo_get(xwidget); +#ifdef IRIX + if ((xswitch_info != NULL) && + (xswitch_info->fingerprint != xswitch_info_fingerprint)) + cmn_err(CE_PANIC, "%v xswitch_info_get bad fingerprint", xwidget); +#endif + + printk("xswitch_info_get: xwidget 0x%p xswitch_info 0x%p\n", xwidget, xswitch_info); + + return (xswitch_info); +} + +void +xswitch_info_vhdl_set(xswitch_info_t xswitch_info, + xwidgetnum_t port, + devfs_handle_t xwidget) +{ +#if XSWITCH_CENSUS_PORT_MIN + if (port < XSWITCH_CENSUS_PORT_MIN) + return; +#endif + if (port > XSWITCH_CENSUS_PORT_MAX) + return; + + xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget; +} + +devfs_handle_t +xswitch_info_vhdl_get(xswitch_info_t xswitch_info, + xwidgetnum_t port) +{ +#ifdef IRIX + if (xswitch_info == NULL) + cmn_err(CE_PANIC, "xswitch_info_vhdl_get: null xswitch_info"); +#endif + +#if XSWITCH_CENSUS_PORT_MIN + if (port < XSWITCH_CENSUS_PORT_MIN) + return GRAPH_VERTEX_NONE; +#endif + if (port > XSWITCH_CENSUS_PORT_MAX) + return GRAPH_VERTEX_NONE; + + return xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN]; +} + +/* + * Some systems may allow for multiple switch masters. On such systems, + * we assign a master for each port on the switch. These interfaces + * establish and retrieve that assignment. + */ +void +xswitch_info_master_assignment_set(xswitch_info_t xswitch_info, + xwidgetnum_t port, + devfs_handle_t master_vhdl) +{ +#if XSWITCH_CENSUS_PORT_MIN + if (port < XSWITCH_CENSUS_PORT_MIN) + return; +#endif + if (port > XSWITCH_CENSUS_PORT_MAX) + return; + + xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl; +} + +devfs_handle_t +xswitch_info_master_assignment_get(xswitch_info_t xswitch_info, + xwidgetnum_t port) +{ +#if XSWITCH_CENSUS_PORT_MIN + if (port < XSWITCH_CENSUS_PORT_MIN) + return GRAPH_VERTEX_NONE; +#endif + if (port > XSWITCH_CENSUS_PORT_MAX) + return GRAPH_VERTEX_NONE; + + return xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN]; +} + +void +xswitch_info_set(devfs_handle_t xwidget, xswitch_info_t xswitch_info) +{ + xswitch_info->fingerprint = xswitch_info_fingerprint; + hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info); +} + +xswitch_info_t +xswitch_info_new(devfs_handle_t xwidget) +{ + xswitch_info_t xswitch_info; + + xswitch_info = xswitch_info_get(xwidget); + if (xswitch_info == NULL) { + int port; + + NEW(xswitch_info); + xswitch_info->census = 0; + for (port = XSWITCH_CENSUS_PORT_MIN; + port <= XSWITCH_CENSUS_PORT_MAX; + port++) { + xswitch_info_vhdl_set(xswitch_info, port, + GRAPH_VERTEX_NONE); + + xswitch_info_master_assignment_set(xswitch_info, + port, + GRAPH_VERTEX_NONE); + } + xswitch_info_set(xwidget, xswitch_info); + printk("xswitch_info_new: xswitch_info_set xwidget 0x%p, xswitch_info 0x%p\n", + xwidget, xswitch_info); + } + return xswitch_info; +} + +void +xswitch_provider_register(devfs_handle_t busv, + xswitch_provider_t * xswitch_fns) +{ + xswitch_info_t xswitch_info = xswitch_info_get(busv); + + ASSERT(xswitch_info); + xswitch_info->xswitch_fns = xswitch_fns; +} + +void +xswitch_info_link_is_ok(xswitch_info_t xswitch_info, xwidgetnum_t port) +{ + xswitch_info->census |= XSWITCH_CENSUS_BIT(port); +} + +int +xswitch_info_link_ok(xswitch_info_t xswitch_info, xwidgetnum_t port) +{ +#if XSWITCH_CENSUS_PORT_MIN + if (port < XSWITCH_CENSUS_PORT_MIN) + return 0; +#endif + + if (port > XSWITCH_CENSUS_PORT_MAX) + return 0; + + return (xswitch_info->census & XSWITCH_CENSUS_BIT(port)); +} + +int +xswitch_reset_link(devfs_handle_t xconn_vhdl) +{ + return DEV_FUNC(xconn_vhdl, reset_link) + (xconn_vhdl); +} + +/* Given a vertex handle to the xswitch get its logical + * id. + */ +int +xswitch_id_get(devfs_handle_t xconn_vhdl) +{ + arbitrary_info_t xbow_num; + graph_error_t rv; + + rv = hwgraph_info_get_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,&xbow_num); + ASSERT(rv == GRAPH_SUCCESS); + return(xbow_num); +} + +/* Given a vertex handle to the xswitch set its logical + * id. + */ +void +xswitch_id_set(devfs_handle_t xconn_vhdl,int xbow_num) +{ + graph_error_t rv; + + rv = hwgraph_info_add_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID, + (arbitrary_info_t)xbow_num); + ASSERT(rv == GRAPH_SUCCESS); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/io/xtalk.c linux-2.4.0-test12-lia/arch/ia64/sn/io/xtalk.c --- linux-2.4.0-test12/arch/ia64/sn/io/xtalk.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/io/xtalk.c Wed Nov 15 19:11:35 2000 @@ -0,0 +1,1137 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* + * Implement crosstalk provider operations. The xtalk* layer provides a + * platform-independent interface for crosstalk devices. This layer + * switches among the possible implementations of a crosstalk adapter. + * + * On platforms with only one possible xtalk provider, macros can be + * set up at the top that cause the table lookups and indirections to + * completely disappear. + */ + +#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL)) +#define DEL(ptr) (kfree(ptr)) + +char widget_info_fingerprint[] = "widget_info"; + +cdl_p xtalk_registry = NULL; + +#include +#define DEV_FUNC(dev,func) hub_##func +#define CAST_PIOMAP(x) ((hub_piomap_t)(x)) +#define CAST_DMAMAP(x) ((hub_dmamap_t)(x)) +#define CAST_INTR(x) ((hub_intr_t)(x)) + +/* ===================================================================== + * Function Table of Contents + */ +xtalk_piomap_t xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned); +void xtalk_piomap_free(xtalk_piomap_t); +caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t); +void xtalk_piomap_done(xtalk_piomap_t); +caddr_t xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned); +caddr_t xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned); +void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *); +caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); +static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned); +xtalk_dmamap_t xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned); +void xtalk_dmamap_free(xtalk_dmamap_t); +iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t); +alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned); +void xtalk_dmamap_done(xtalk_dmamap_t); +iopaddr_t xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned); +alenlist_t xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned); +void xtalk_dmamap_drain(xtalk_dmamap_t); +void xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t); +void xtalk_dmalist_drain(devfs_handle_t, alenlist_t); +xtalk_intr_t xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t); +void xtalk_intr_free(xtalk_intr_t); +int xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *, void *); +void xtalk_intr_disconnect(xtalk_intr_t); +devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t); +int xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); +int xtalk_error_devenable(devfs_handle_t, int, int); +void xtalk_provider_startup(devfs_handle_t); +void xtalk_provider_shutdown(devfs_handle_t); +devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t); +xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t); +xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t); +iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *); +void *xtalk_intr_sfarg_get(xtalk_intr_t); +devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t); +xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t); +iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t); +ulong xtalk_pio_mapsz_get(xtalk_piomap_t); +caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t); +devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t); +xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t); +xwidget_info_t xwidget_info_chk(devfs_handle_t); +xwidget_info_t xwidget_info_get(devfs_handle_t); +void xwidget_info_set(devfs_handle_t, xwidget_info_t); +devfs_handle_t xwidget_info_dev_get(xwidget_info_t); +xwidgetnum_t xwidget_info_id_get(xwidget_info_t); +devfs_handle_t xwidget_info_master_get(xwidget_info_t); +xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t); +xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t); +xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t); +char *xwidget_info_name_get(xwidget_info_t); +void xtalk_init(void); +void xtalk_provider_register(devfs_handle_t, xtalk_provider_t *); +void xtalk_provider_unregister(devfs_handle_t); +xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t); +int xwidget_driver_register(xwidget_part_num_t, + xwidget_mfg_num_t, + char *, unsigned); +void xwidget_driver_unregister(char *); +int xwidget_register(xwidget_hwid_t, devfs_handle_t, + xwidgetnum_t, devfs_handle_t, + xwidgetnum_t, async_attach_t); +int xwidget_unregister(devfs_handle_t); +void xwidget_error_register(devfs_handle_t, error_handler_f *, + error_handler_arg_t); +void xwidget_reset(devfs_handle_t); +char *xwidget_name_get(devfs_handle_t); +#if !defined(DEV_FUNC) +/* + * There is more than one possible provider + * for this platform. We need to examine the + * master vertex of the current vertex for + * a provider function structure, and indirect + * through the appropriately named member. + */ +#define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func +#define CAST_PIOMAP(x) ((xtalk_piomap_t)(x)) +#define CAST_DMAMAP(x) ((xtalk_dmamap_t)(x)) +#define CAST_INTR(x) ((xtalk_intr_t)(x)) + +static xtalk_provider_t * +xwidget_to_provider_fns(devfs_handle_t xconn) +{ + xwidget_info_t widget_info; + xtalk_provider_t *provider_fns; + + widget_info = xwidget_info_get(xconn); + ASSERT(widget_info != NULL); + + provider_fns = xwidget_info_pops_get(widget_info); + ASSERT(provider_fns != NULL); + + return (provider_fns); +} +#endif + +/* + * Many functions are not passed their vertex + * information directly; rather, they must + * dive through a resource map. These macros + * are available to coordinate this detail. + */ +#define PIOMAP_FUNC(map,func) DEV_FUNC(map->xp_dev,func) +#define DMAMAP_FUNC(map,func) DEV_FUNC(map->xd_dev,func) +#define INTR_FUNC(intr,func) DEV_FUNC(intr_hdl->xi_dev,func) + +/* ===================================================================== + * PIO MANAGEMENT + * + * For mapping system virtual address space to + * xtalk space on a specified widget + */ + +xtalk_piomap_t +xtalk_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ + size_t byte_count, + size_t byte_count_max, /* maximum size of a mapping */ + unsigned flags) +{ /* defined in sys/pio.h */ + return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc) + (dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags); +} + + +void +xtalk_piomap_free(xtalk_piomap_t xtalk_piomap) +{ + PIOMAP_FUNC(xtalk_piomap, piomap_free) + (CAST_PIOMAP(xtalk_piomap)); +} + + +caddr_t +xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap, /* mapping resources */ + iopaddr_t xtalk_addr, /* map for this xtalk address */ + size_t byte_count) +{ /* map this many bytes */ + return PIOMAP_FUNC(xtalk_piomap, piomap_addr) + (CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count); +} + + +void +xtalk_piomap_done(xtalk_piomap_t xtalk_piomap) +{ + PIOMAP_FUNC(xtalk_piomap, piomap_done) + (CAST_PIOMAP(xtalk_piomap)); +} + + +caddr_t +xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* Crosstalk address */ + size_t byte_count, /* map this many bytes */ + unsigned flags) +{ /* (currently unused) */ + return DEV_FUNC(dev, piotrans_addr) + (dev, dev_desc, xtalk_addr, byte_count, flags); +} + +caddr_t +xtalk_pio_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t addr, /* starting address (or offset in window) */ + size_t byte_count, /* map this many bytes */ + xtalk_piomap_t *mapp, /* where to return the map pointer */ + unsigned flags) +{ /* PIO flags */ + xtalk_piomap_t map = 0; + caddr_t res; + + if (mapp) + *mapp = 0; /* record "no map used" */ + + res = xtalk_piotrans_addr + (dev, dev_desc, addr, byte_count, flags); + if (res) + return res; /* xtalk_piotrans worked */ + + map = xtalk_piomap_alloc + (dev, dev_desc, addr, byte_count, byte_count, flags); + if (!map) + return res; /* xtalk_piomap_alloc failed */ + + res = xtalk_piomap_addr + (map, addr, byte_count); + if (!res) { + xtalk_piomap_free(map); + return res; /* xtalk_piomap_addr failed */ + } + if (mapp) + *mapp = map; /* pass back map used */ + + return res; /* xtalk_piomap_addr succeeded */ +} + +/* ===================================================================== + * EARLY PIOTRANS SUPPORT + * + * There are places where drivers (mgras, for instance) + * need to get PIO translations before the infrastructure + * is extended to them (setting up textports, for + * instance). These drivers should call + * xtalk_early_piotrans_addr with their xtalk ID + * information, a sequence number (so we can use the second + * mgras for instance), and the usual piotrans parameters. + * + * Machine specific code should provide an implementation + * of early_piotrans_addr, and present a pointer to this + * function to xtalk_set_early_piotrans_addr so it can be + * used by clients without the clients having to know what + * platform or what xtalk provider is in use. + */ + +static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr; + +xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr; + +/* xtalk_set_early_piotrans_addr: + * specify the early_piotrans_addr implementation function. + */ +void +xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl) +{ + impl_early_piotrans_addr = impl; +} + +/* xtalk_early_piotrans_addr: + * figure out a PIO address for the "nth" crosstalk widget that + * matches the specified part and mfgr number. Returns NULL if + * there is no such widget, or if the requested mapping can not + * be constructed. + * Limitations on which crosstalk slots (and busses) are + * checked, and definitions of the ordering of the search across + * the crosstalk slots, are defined by the platform. + */ +caddr_t +xtalk_early_piotrans_addr(xwidget_part_num_t part_num, + xwidget_mfg_num_t mfg_num, + int which, + iopaddr_t xtalk_addr, + size_t byte_count, + unsigned flags) +{ + return impl_early_piotrans_addr + (part_num, mfg_num, which, xtalk_addr, byte_count, flags); +} + +/* null_xtalk_early_piotrans_addr: + * used as the early_piotrans_addr implementation until and + * unless a real implementation is provided. In DEBUG kernels, + * we want to know who is calling before the implementation is + * registered; in non-DEBUG kernels, return NULL representing + * lack of mapping support. + */ +/*ARGSUSED */ +static caddr_t +null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num, + xwidget_mfg_num_t mfg_num, + int which, + iopaddr_t xtalk_addr, + size_t byte_count, + unsigned flags) +{ +#if DEBUG + cmn_err(CE_PANIC, "null_xtalk_early_piotrans_addr"); +#endif + return NULL; +} + +/* ===================================================================== + * DMA MANAGEMENT + * + * For mapping from crosstalk space to system + * physical space. + */ + +xtalk_dmamap_t +xtalk_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */ + device_desc_t dev_desc, /* device descriptor */ + size_t byte_count_max, /* max size of a mapping */ + unsigned flags) +{ /* defined in dma.h */ + return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc) + (dev, dev_desc, byte_count_max, flags); +} + + +void +xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap) +{ + DMAMAP_FUNC(xtalk_dmamap, dmamap_free) + (CAST_DMAMAP(xtalk_dmamap)); +} + + +iopaddr_t +xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */ + paddr_t paddr, /* map for this address */ + size_t byte_count) +{ /* map this many bytes */ + return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr) + (CAST_DMAMAP(xtalk_dmamap), paddr, byte_count); +} + + +alenlist_t +xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */ + alenlist_t alenlist, /* map this Address/Length List */ + unsigned flags) +{ + return DMAMAP_FUNC(xtalk_dmamap, dmamap_list) + (CAST_DMAMAP(xtalk_dmamap), alenlist, flags); +} + + +void +xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap) +{ + DMAMAP_FUNC(xtalk_dmamap, dmamap_done) + (CAST_DMAMAP(xtalk_dmamap)); +} + + +iopaddr_t +xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + unsigned flags) +{ /* defined in dma.h */ + return DEV_FUNC(dev, dmatrans_addr) + (dev, dev_desc, paddr, byte_count, flags); +} + + +alenlist_t +xtalk_dmatrans_list(devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + alenlist_t palenlist, /* system address/length list */ + unsigned flags) +{ /* defined in dma.h */ + return DEV_FUNC(dev, dmatrans_list) + (dev, dev_desc, palenlist, flags); +} + +void +xtalk_dmamap_drain(xtalk_dmamap_t map) +{ + DMAMAP_FUNC(map, dmamap_drain) + (CAST_DMAMAP(map)); +} + +void +xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size) +{ + DEV_FUNC(dev, dmaaddr_drain) + (dev, addr, size); +} + +void +xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list) +{ + DEV_FUNC(dev, dmalist_drain) + (dev, list); +} + +/* ===================================================================== + * INTERRUPT MANAGEMENT + * + * Allow crosstalk devices to establish interrupts + */ + +/* + * Allocate resources required for an interrupt as specified in intr_desc. + * Return resource handle in intr_hdl. + */ +xtalk_intr_t +xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ + device_desc_t dev_desc, /* device descriptor */ + devfs_handle_t owner_dev) +{ /* owner of this interrupt */ + return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc) + (dev, dev_desc, owner_dev); +} + + +/* + * Free resources consumed by intr_alloc. + */ +void +xtalk_intr_free(xtalk_intr_t intr_hdl) +{ + INTR_FUNC(intr_hdl, intr_free) + (CAST_INTR(intr_hdl)); +} + + +/* + * Associate resources allocated with a previous xtalk_intr_alloc call with the + * described handler, arg, name, etc. + * + * Returns 0 on success, returns <0 on failure. + */ +int +xtalk_intr_connect(xtalk_intr_t intr_hdl, /* xtalk intr resource handle */ + intr_func_t intr_func, /* xtalk intr handler */ + intr_arg_t intr_arg, /* arg to intr handler */ + xtalk_intr_setfunc_t setfunc, /* func to set intr hw */ + void *setfunc_arg, /* arg to setfunc */ + void *thread) +{ /* intr thread to use */ + return INTR_FUNC(intr_hdl, intr_connect) + (CAST_INTR(intr_hdl), intr_func, intr_arg, setfunc, setfunc_arg, thread); +} + + +/* + * Disassociate handler with the specified interrupt. + */ +void +xtalk_intr_disconnect(xtalk_intr_t intr_hdl) +{ + INTR_FUNC(intr_hdl, intr_disconnect) + (CAST_INTR(intr_hdl)); +} + + +/* + * Return a hwgraph vertex that represents the CPU currently + * targeted by an interrupt. + */ +devfs_handle_t +xtalk_intr_cpu_get(xtalk_intr_t intr_hdl) +{ + return INTR_FUNC(intr_hdl, intr_cpu_get) + (CAST_INTR(intr_hdl)); +} + + +/* + * ===================================================================== + * ERROR MANAGEMENT + */ + +/* + * xtalk_error_handler: + * pass this error on to the handler registered + * at the specified xtalk connecdtion point, + * or complain about it here if there is no handler. + * + * This routine plays two roles during error delivery + * to most widgets: first, the external agent (heart, + * hub, or whatever) calls in with the error and the + * connect point representing the crosstalk switch, + * or whatever crosstalk device is directly connected + * to the agent. + * + * If there is a switch, it will generally look at the + * widget number stashed in the ioerror structure; and, + * if the error came from some widget other than the + * switch, it will call back into xtalk_error_handler + * with the connection point of the offending port. + */ +int +xtalk_error_handler( + devfs_handle_t xconn, + int error_code, + ioerror_mode_t mode, + ioerror_t *ioerror) +{ + xwidget_info_t xwidget_info; + +#if DEBUG && ERROR_DEBUG + cmn_err(CE_CONT, "%v: xtalk_error_handler\n", xconn); +#endif + + xwidget_info = xwidget_info_get(xconn); + /* Make sure that xwidget_info is a valid pointer before derefencing it. + * We could come in here during very early initialization. + */ + if (xwidget_info && xwidget_info->w_efunc) + return xwidget_info->w_efunc + (xwidget_info->w_einfo, + error_code, mode, ioerror); + /* + * no error handler registered for + * the offending port. it's not clear + * what needs to be done, but reporting + * it would be a good thing, unless it + * is a mode that requires nothing. + */ + if ((mode == MODE_DEVPROBE) || (mode == MODE_DEVUSERERROR) || + (mode == MODE_DEVREENABLE)) + return IOERROR_HANDLED; + +#ifdef IRIX + cmn_err(CE_WARN, "Xbow at %v encountered Fatal error", xconn); +#endif + ioerror_dump("xtalk", error_code, mode, ioerror); + + return IOERROR_UNHANDLED; +} + +int +xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code) +{ + return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code); +} + + +/* ===================================================================== + * CONFIGURATION MANAGEMENT + */ + +/* + * Startup a crosstalk provider + */ +void +xtalk_provider_startup(devfs_handle_t xtalk_provider) +{ + DEV_FUNC(xtalk_provider, provider_startup) + (xtalk_provider); +} + + +/* + * Shutdown a crosstalk provider + */ +void +xtalk_provider_shutdown(devfs_handle_t xtalk_provider) +{ + DEV_FUNC(xtalk_provider, provider_shutdown) + (xtalk_provider); +} + +/* + * Enable a device on a xtalk widget + */ +void +xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum) +{ + DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum); +} + +/* + * Shutdown a device on a xtalk widget + */ +void +xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum) +{ + DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum); +} + +int +xtalk_dma_enabled(devfs_handle_t xconn_vhdl) +{ + return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl); +} +/* + * Generic crosstalk functions, for use with all crosstalk providers + * and all crosstalk devices. + */ + +/****** Generic crosstalk interrupt interfaces ******/ +devfs_handle_t +xtalk_intr_dev_get(xtalk_intr_t xtalk_intr) +{ + return (xtalk_intr->xi_dev); +} + +xwidgetnum_t +xtalk_intr_target_get(xtalk_intr_t xtalk_intr) +{ + return (xtalk_intr->xi_target); +} + +xtalk_intr_vector_t +xtalk_intr_vector_get(xtalk_intr_t xtalk_intr) +{ + return (xtalk_intr->xi_vector); +} + +iopaddr_t +xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr) +{ + return (xtalk_intr->xi_addr); +} + +void * +xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr) +{ + return (xtalk_intr->xi_sfarg); +} + + +int +xtalk_intr_flags_get(xtalk_intr_t xtalk_intr) +{ + return(xtalk_intr->xi_flags); +} + +/****** Generic crosstalk pio interfaces ******/ +devfs_handle_t +xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap) +{ + return (xtalk_piomap->xp_dev); +} + +xwidgetnum_t +xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap) +{ + return (xtalk_piomap->xp_target); +} + +iopaddr_t +xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap) +{ + return (xtalk_piomap->xp_xtalk_addr); +} + +ulong +xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap) +{ + return (xtalk_piomap->xp_mapsz); +} + +caddr_t +xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap) +{ + return (xtalk_piomap->xp_kvaddr); +} + + +/****** Generic crosstalk dma interfaces ******/ +devfs_handle_t +xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap) +{ + return (xtalk_dmamap->xd_dev); +} + +xwidgetnum_t +xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap) +{ + return (xtalk_dmamap->xd_target); +} + + +/****** Generic crosstalk widget information interfaces ******/ + +/* xwidget_info_chk: + * check to see if this vertex is a widget; + * if so, return its widget_info (if any). + * if not, return NULL. + */ +xwidget_info_t +xwidget_info_chk(devfs_handle_t xwidget) +{ + arbitrary_info_t ainfo = 0; + + hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo); + return (xwidget_info_t) ainfo; +} + + +xwidget_info_t +xwidget_info_get(devfs_handle_t xwidget) +{ + xwidget_info_t widget_info; + + widget_info = (xwidget_info_t) + hwgraph_fastinfo_get(xwidget); + +#ifdef IRIX + if ((widget_info != NULL) && + (widget_info->w_fingerprint != widget_info_fingerprint)) + cmn_err(CE_PANIC, "%v bad xwidget_info", xwidget); +#endif + + return (widget_info); +} + +void +xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info) +{ + if (widget_info != NULL) + widget_info->w_fingerprint = widget_info_fingerprint; + + hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info); + + /* Also, mark this vertex as an xwidget, + * and use the widget_info, so xwidget_info_chk + * can work (and be fairly efficient). + */ + hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET, + (arbitrary_info_t) widget_info); +} + +devfs_handle_t +xwidget_info_dev_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget_info"); + return (xwidget_info->w_vertex); +} + +xwidgetnum_t +xwidget_info_id_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget_info"); + return (xwidget_info->w_id); +} + + +devfs_handle_t +xwidget_info_master_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget_info"); + return (xwidget_info->w_master); +} + +xwidgetnum_t +xwidget_info_masterid_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget_info"); + return (xwidget_info->w_masterid); +} + +xwidget_part_num_t +xwidget_info_part_num_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget_info"); + return (xwidget_info->w_hwid.part_num); +} + +xwidget_mfg_num_t +xwidget_info_mfg_num_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget_info"); + return (xwidget_info->w_hwid.mfg_num); +} +/* Extract the widget name from the widget information + * for the xtalk widget. + */ +char * +xwidget_info_name_get(xwidget_info_t xwidget_info) +{ + if (xwidget_info == NULL) + panic("null xwidget info"); + return(xwidget_info->w_name); +} +/****** Generic crosstalk initialization interfaces ******/ + +/* + * One-time initialization needed for systems that support crosstalk. + */ +void +xtalk_init(void) +{ + cdl_p cp; + +#if DEBUG && ATTACH_DEBUG + printf("xtalk_init\n"); +#endif + /* Allocate the registry. + * We might already have one. + * If we don't, go get one. + * MPness: someone might have + * set one up for us while we + * were not looking; use an atomic + * compare-and-swap to commit to + * using the new registry if and + * only if nobody else did first. + * If someone did get there first, + * toss the one we allocated back + * into the pool. + */ + if (xtalk_registry == NULL) { + cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr"); + if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) { + cdl_del(cp); + } + } + ASSERT(xtalk_registry != NULL); +} + +/* + * Associate a set of xtalk_provider functions with a vertex. + */ +void +xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns) +{ + hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns); +} + +/* + * Disassociate a set of xtalk_provider functions with a vertex. + */ +void +xtalk_provider_unregister(devfs_handle_t provider) +{ + hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL); +} + +/* + * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk + * provider. + */ +xtalk_provider_t * +xtalk_provider_fns_get(devfs_handle_t provider) +{ + return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider)); +} + +/* + * Announce a driver for a particular crosstalk part. + * Returns 0 on success or -1 on failure. Failure occurs if the + * specified hardware already has a driver. + */ +/*ARGSUSED4 */ +int +xwidget_driver_register(xwidget_part_num_t part_num, + xwidget_mfg_num_t mfg_num, + char *driver_prefix, + unsigned flags) +{ + /* a driver's init routine could call + * xwidget_driver_register before the + * system calls xtalk_init; so, we + * make the call here. + */ + if (xtalk_registry == NULL) + xtalk_init(); + + return cdl_add_driver(xtalk_registry, + part_num, mfg_num, + driver_prefix, flags); +} + +/* + * Inform xtalk infrastructure that a driver is no longer available for + * handling any widgets. + */ +void +xwidget_driver_unregister(char *driver_prefix) +{ + /* before a driver calls unregister, + * it must have called registger; so we + * can assume we have a registry here. + */ + ASSERT(xtalk_registry != NULL); + + cdl_del_driver(xtalk_registry, driver_prefix); +} + +/* + * Call some function with each vertex that + * might be one of this driver's attach points. + */ +void +xtalk_iterate(char *driver_prefix, + xtalk_iter_f *func) +{ + ASSERT(xtalk_registry != NULL); + + cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func); +} + +/* + * xwidget_register: + * Register a xtalk device (xwidget) by doing the following. + * -allocate and initialize xwidget_info data + * -allocate a hwgraph vertex with name based on widget number (id) + * -look up the widget's initialization function and call it, + * or remember the vertex for later initialization. + * + */ +int +xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */ + devfs_handle_t widget, /* widget to initialize */ + xwidgetnum_t id, /* widget's target id (0..f) */ + devfs_handle_t master, /* widget's master vertex */ + xwidgetnum_t targetid, /* master's target id (9/a) */ + async_attach_t aa) +{ + xwidget_info_t widget_info; + char *s,devnm[MAXDEVNAME]; + + /* Allocate widget_info and associate it with widget vertex */ + NEW(widget_info); + + /* Initialize widget_info */ + widget_info->w_vertex = widget; + widget_info->w_id = id; + widget_info->w_master = master; + widget_info->w_masterid = targetid; + widget_info->w_hwid = *hwid; /* structure copy */ + widget_info->w_efunc = 0; + widget_info->w_einfo = 0; + /* + * get the name of this xwidget vertex and keep the info. + * This is needed during errors and interupts, but as + * long as we have it, we can use it elsewhere. + */ + s = dev_to_name(widget,devnm,MAXDEVNAME); + printk("xwidget_register: dev_to_name widget id 0x%p, s = %s\n", widget, s); + widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL); + strcpy(widget_info->w_name,s); + + xwidget_info_set(widget, widget_info); + + device_master_set(widget, master); + + /* All the driver init routines (including + * xtalk_init) are called before we get into + * attaching devices, so we can assume we + * have a registry here. + */ + ASSERT(xtalk_registry != NULL); + + /* + * Add pointer to async attach info -- tear down will be done when + * the particular descendant is done with the info. + */ + if (aa) + async_attach_add_info(widget, aa); + + return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, widget); +} + +/* + * xwidget_unregister : + * Unregister the xtalk device and detach all its hwgraph namespace. + */ +int +xwidget_unregister(devfs_handle_t widget) +{ + xwidget_info_t widget_info; + xwidget_hwid_t hwid; + + /* Make sure that we have valid widget information initialized */ + if (!(widget_info = xwidget_info_get(widget))) + return(1); + + /* Remove the inventory information associated + * with the widget. + */ + hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1); + + hwid = &(widget_info->w_hwid); + + cdl_del_connpt(xtalk_registry, hwid->part_num, + hwid->mfg_num, widget); + + /* Clean out the xwidget information */ + (void)kfree(widget_info->w_name); + BZERO((void *)widget_info, sizeof(widget_info)); + DEL(widget_info); + + return(0); +} + +void +xwidget_error_register(devfs_handle_t xwidget, + error_handler_f *efunc, + error_handler_arg_t einfo) +{ + xwidget_info_t xwidget_info; + + xwidget_info = xwidget_info_get(xwidget); + ASSERT(xwidget_info != NULL); + xwidget_info->w_efunc = efunc; + xwidget_info->w_einfo = einfo; +} + +/* + * Issue a link reset to a widget. + */ +void +xwidget_reset(devfs_handle_t xwidget) +{ + xswitch_reset_link(xwidget); + +} + + +void +xwidget_gfx_reset(devfs_handle_t xwidget) +{ + xwidget_info_t info; + + xswitch_reset_link(xwidget); + info = xwidget_info_get(xwidget); +#ifdef IRIX + ASSERT_ALWAYS(info != NULL); +#endif + + /* + * Enable this for other architectures once we add widget_reset to the + * xtalk provider interface. + */ + DEV_FUNC(xtalk_provider, widget_reset) + (xwidget_info_master_get(info), xwidget_info_id_get(info)); +} + +#define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */ + +/* Get the canonical hwgraph name of xtalk widget */ +char * +xwidget_name_get(devfs_handle_t xwidget_vhdl) +{ + xwidget_info_t info; + + /* If we have a bogus widget handle then return + * a default anonymous widget name. + */ + if (xwidget_vhdl == GRAPH_VERTEX_NONE) + return(ANON_XWIDGET_NAME); + /* Read the widget name stored in the widget info + * for the widget setup during widget initialization. + */ + info = xwidget_info_get(xwidget_vhdl); + ASSERT(info != NULL); + return(xwidget_info_name_get(info)); +} +/* + * xtalk_device_powerup + * Reset and initialize the specified xtalk widget + */ +int +xtalk_device_powerup(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) +{ +#ifndef CONFIG_IA64_SGI_IO + extern void io_xswitch_widget_init(devfs_handle_t, + devfs_handle_t, + xwidgetnum_t, + async_attach_t); + io_xswitch_widget_init(xbus_vhdl, + hwgraph_connectpt_get(xbus_vhdl), + widget, + NULL); +#endif /* CONFIG_IA64_SGI_IO */ + + return(0); +} +/* + * xtalk_device_shutdown + * Disable the specified xtalk widget and clean out all the software + * state associated with it. + */ +int +xtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) +{ + devfs_handle_t widget_vhdl; + char edge_name[8]; + + sprintf(edge_name, "%d", widget); + if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl) + != GRAPH_SUCCESS) + return(1); + + xwidget_unregister(widget_vhdl); + + return(0); +} +/* + * xtalk_device_inquiry + * Find out hardware information about the xtalk widget. + */ +int +xtalk_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget) +{ + + extern void hub_device_inquiry(devfs_handle_t, xwidgetnum_t); + hub_device_inquiry(xbus_vhdl, widget); + return(0); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/Makefile linux-2.4.0-test12-lia/arch/ia64/sn/sn1/Makefile --- linux-2.4.0-test12/arch/ia64/sn/sn1/Makefile Thu Mar 30 16:56:04 2000 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/Makefile Wed Dec 6 21:54:10 2000 @@ -5,20 +5,27 @@ # Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com) # -CFLAGS := $(CFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSN -DSOFTSDV \ - -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -AFLAGS := $(AFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSOFTSDV +EXTRA_CFLAGS := -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \ + -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \ + -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \ + -DNEW_INTERRUPTS -DCONFIG_IA64_SGI_IO .S.s: - $(CPP) $(AFLAGS) -o $*.s $< + $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $< .S.o: - $(CC) $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< all: sn1.a O_TARGET = sn1.a O_HEADERS = -O_OBJS = irq.o setup.o +O_OBJS = irq.o setup.o iomv.o mm.o smp.o synergy.o sn1_asm.o \ + discontig.o + +ifeq ($(CONFIG_IA64_SGI_AUTOTEST),y) +O_OBJS += llsc4.o +endif + ifeq ($(CONFIG_IA64_GENERIC),y) O_OBJS += machvec.o diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/discontig.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/discontig.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/discontig.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/discontig.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,187 @@ +/* + * Copyright 2000, Silicon Graphics, sprasad@engr.sgi.com + * Copyright 2000, Kanoj Sarcar, kanoj@sgi.com + */ + +/* + * Contains common definitions and globals for NUMA platform + * support. For now, SN-IA64 and SN-MIPS are the NUMA platforms. + */ + +#include +#include +#include +#include +#include + +extern int numnodes ; + +plat_pg_data_t plat_node_data[MAXNODES]; +bootmem_data_t bdata[MAXNODES]; +int chunktonid[MAXCHUNKS]; +int nasid_map[MAXNASIDS]; + +void __init +init_chunktonid(void) +{ + memset(chunktonid, -1, sizeof(chunktonid)) ; +} + +void __init +init_nodeidmap(void) +{ + memset(nasid_map, -1, sizeof(nasid_map)) ; +} + +int cnodeid_map[MAXNODES] ; +void __init +init_cnodeidmap(void) +{ + memset(cnodeid_map, -1, sizeof(cnodeid_map)) ; +} + +int +numa_debug(void) +{ + panic("NUMA debug\n"); + return(0); +} + +int __init +build_cnodeid_map(void) +{ + int i,j ; + + for (i=0,j=0;i= 0) + cnodeid_map[j++] = i ; + } + return j ; +} + +/* + * Since efi_memmap_walk merges contiguous banks, this code will need + * to find all the nasids covered by the input memory descriptor. + */ +static int __init +build_nasid_map(unsigned long start, unsigned long end, void *arg) +{ + unsigned long vaddr = start; + int nasid = GetNasId(__pa(vaddr)); + + while (vaddr < end) { + if (nasid < MAXNASIDS) + nasid_map[nasid] = 0; + else + panic("build_nasid_map"); + vaddr = (unsigned long)__va((unsigned long)(++nasid) << + SN1_NODE_ADDR_SHIFT); + } + return 0; +} + +void __init +fix_nasid_map(void) +{ + int i ; + int j ; + + /* For every nasid */ + for (j=0;jbdata ; + printk("%d 0x%016lx 0x%016lx 0x%016lx\n", i, + bdata->node_boot_start, bdata->node_low_pfn, + (unsigned long)bdata->node_bootmem_map) ; + } +} + +void __init +discontig_mem_init(void) +{ + extern void setup_sn1_bootmem(int); + int maxnodes ; + + init_chunktonid() ; + init_nodeidmap() ; + init_cnodeidmap() ; + efi_memmap_walk(build_nasid_map, 0) ; + maxnodes = build_cnodeid_map() ; + fix_nasid_map() ; +#ifdef CONFIG_DISCONTIGMEM + setup_sn1_bootmem(maxnodes) ; +#endif + numnodes = maxnodes; + dump_bootmem_info() ; +} + +void __init +discontig_paging_init(void) +{ + int i; + unsigned long max_dma, zones_size[MAX_NR_ZONES]; + void dump_node_data(void); + + max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; + for (i = 0; i < numnodes; i++) { + extern void free_unused_memmap_node(int); + unsigned long startpfn = __pa((void *)NODE_START(i)) >> PAGE_SHIFT; + unsigned long numpfn = NODE_SIZE(i) >> PAGE_SHIFT; + memset(zones_size, 0, sizeof(zones_size)); + + if ((startpfn + numpfn) < max_dma) { + zones_size[ZONE_DMA] = numpfn; + } else if (startpfn > max_dma) { + zones_size[ZONE_NORMAL] = numpfn; + } else { + zones_size[ZONE_DMA] = (max_dma - startpfn); + zones_size[ZONE_NORMAL] = numpfn - zones_size[ZONE_DMA]; + } + free_area_init_node(i, NODE_DATA(i), NULL, zones_size, startpfn<valid_addr_bitmap, + NODE_DATA(i)->node_start_paddr, + NODE_DATA(i)->node_start_mapnr, + NODE_DATA(i)->node_size, + NODE_DATA(i)->node_id) ; + } +} + diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/iomv.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/iomv.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/iomv.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/iomv.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,100 @@ +/* + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) + */ + +#include +#include + +static inline void * +sn1_io_addr(unsigned long port) +{ + if (!IS_RUNNING_ON_SIMULATOR()) { + return( (void *) (port | __IA64_UNCACHED_OFFSET)); + } else { + unsigned long io_base; + unsigned long addr; + + /* + * word align port, but need more than 10 bits + * for accessing registers in bedrock local block + * (so we don't do port&0xfff) + */ + if (port == 0x1f6 || port == 0x1f7 + || port == 0x3f6 || port == 0x3f7 + || port == 0x1f0 || port == 0x1f1 + || port == 0x1f3 || port == 0x1f4 + || port == 0x1f2 || port == 0x1f5) { + io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000; + addr = io_base | ((port >> 2) << 12) | (port & 0xfff); + } else { + addr = __ia64_get_io_port_base() | ((port >> 2) << 2); + } + return(void *) addr; + } +} + +unsigned int +sn1_inb (unsigned long port) +{ + volatile unsigned char *addr = sn1_io_addr(port); + unsigned char ret; + + ret = *addr; + __ia64_mf_a(); + return ret; +} + +unsigned int +sn1_inw (unsigned long port) +{ + volatile unsigned short *addr = sn1_io_addr(port); + unsigned short ret; + + ret = *addr; + __ia64_mf_a(); + return ret; +} + +unsigned int +sn1_inl (unsigned long port) +{ + volatile unsigned int *addr = sn1_io_addr(port); + unsigned int ret; + + ret = *addr; + __ia64_mf_a(); + return ret; +} + +void +sn1_outb (unsigned char val, unsigned long port) +{ + volatile unsigned char *addr = sn1_io_addr(port); + + *addr = val; + __ia64_mf_a(); +} + +void +sn1_outw (unsigned short val, unsigned long port) +{ + volatile unsigned short *addr = sn1_io_addr(port); + + *addr = val; + __ia64_mf_a(); +} + +void +sn1_outl (unsigned int val, unsigned long port) +{ + volatile unsigned int *addr = sn1_io_addr(port); + + *addr = val; + __ia64_mf_a(); +} diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/irq.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/irq.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/irq.c Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/irq.c Wed Dec 6 21:54:10 2000 @@ -1,8 +1,56 @@ -#include +/* + * Platform dependent support for SGI SN1 + * + * Copyright (C) 2000 Silicon Graphics + * Copyright (C) 2000 Jack Steiner (steiner@sgi.com) + * Copyright (C) 2000 Alan Mayer (ajm@sgi.com) + */ + +#include #include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int bit_pos_to_irq(int bit); +int irq_to_bit_pos(int irq); +void add_interrupt_randomness(int irq); +void * kmalloc(size_t size, int flags); +void kfree(const void *); +int sgi_pci_intr_support (unsigned int, device_desc_t *, devfs_handle_t *, pciio_intr_line_t *, devfs_handle_t *); +pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t); +int request_irq(unsigned int, void (*)(int, void *, struct pt_regs *), unsigned long, const char *, void *); + +/* This should be dynamically allocated, at least part of it. */ +/* For the time being, though, we'll statically allocate it */ +/* because kmalloc hasn't been initiallized at the time this */ +/* array is initiallized. One way to do it would be to statically */ +/* allocate the data for node 0, then let other nodes, as they */ +/* need it, dynamically allocate their own data space. */ -#include +struct sn1_cnode_action_list *sn1_node_actions[MAX_COMPACT_NODES]; +struct sn1_cnode_action_list sn1_actions[MAX_COMPACT_NODES][256]; + + +extern int numnodes; static unsigned int sn1_startup_irq(unsigned int irq) @@ -25,20 +73,192 @@ { } +static void +sn1_ack_irq(unsigned int irq) +{ +} + +static void +sn1_end_irq(unsigned int irq) +{ +} + +static void +sn1_set_affinity_irq(unsigned int irq, unsigned long mask) +{ +} + + +static void +sn1_handle_irq(int irq, void *dummy, struct pt_regs *regs) +{ + int bit, cnode; + struct sn1_cnode_action_list *alp; + struct sn1_intr_action *ap; + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags = 0; + int cpuid = smp_processor_id(); + + + bit = irq_to_bit_pos(irq); + LOCAL_HUB_CLR_INTR(bit); + cnode = cpuid_to_cnodeid(cpuid); + alp = sn1_node_actions[cnode]; + ap = alp[irq].action_list; + if (ap == NULL) { + return; + } + while (ap) { + flags |= ap->flags; + handler = ap->handler; + (*handler)(irq,ap->intr_arg,regs); + ap = ap->next; + } + if ((flags & SA_SAMPLE_RANDOM) != 0) + add_interrupt_randomness(irq); + + return; +} + struct hw_interrupt_type irq_type_sn1 = { "sn1_irq", sn1_startup_irq, sn1_shutdown_irq, sn1_enable_irq, - sn1_disable_irq + sn1_disable_irq, + sn1_ack_irq, + sn1_end_irq, + sn1_set_affinity_irq +}; + +struct irqaction sn1_irqaction = { + sn1_handle_irq, + 0, + 0, + NULL, + NULL, + NULL, }; void sn1_irq_init (void) { - int i; + int i,j; + + for (i = 0; i <= NR_IRQS; ++i) { + if (irq_desc[i].handler == &no_irq_type) { + irq_desc[i].handler = &irq_type_sn1; + if (i >=71 && i <= 181) { + irq_desc[i].action = &sn1_irqaction; + } + } + } + + for (i = 0; i < numnodes; i++) { + sn1_node_actions[i] = sn1_actions[i]; + memset(sn1_node_actions[i], 0, + sizeof(struct sn1_cnode_action_list) * + (IA64_MAX_VECTORED_IRQ + 1)); + for (j=0; jpi_irq; + cpuid = intr_handle->pi_cpu; + irq = bit_pos_to_irq(bit); + cnode = cpuid_to_cnodeid(cpuid); + new_ap = (struct sn1_intr_action *)kmalloc( + sizeof(struct sn1_intr_action), GFP_KERNEL); + irq_desc[irq].status = 0; + new_ap->handler = handler; + new_ap->intr_arg = dev_id; + new_ap->flags = irqflags; + new_ap->next = NULL; + alp = sn1_node_actions[cnode]; + + spin_lock(&alp[irq].action_list_lock); + ap = alp[irq].action_list; + /* check action list for "share" consistency */ + while (ap){ + if (!(ap->flags & irqflags & SA_SHIRQ) ) { + return(-EBUSY); + spin_unlock(&alp[irq].action_list_lock); + } + ap = ap->next; + } + ap = alp[irq].action_list; + if (ap) { + while (ap->next) { + ap = ap->next; + } + ap->next = new_ap; + } else { + alp[irq].action_list = new_ap; + } + ret = pciio_intr_connect(intr_handle, (intr_func_t)handler, dev_id, NULL); + if (ret) { /* connect failed, undo what we did. */ + new_ap = alp[irq].action_list; + if (new_ap == ap) { + alp[irq].action_list = NULL; + kfree(ap); + } else { + while (new_ap->next && new_ap->next != ap) { + new_ap = new_ap->next; + } + if (new_ap->next == ap) { + new_ap->next = ap->next; + kfree(ap); + } + } + } + + spin_unlock(&alp[irq].action_list_lock); + return(ret); + } else { + return(request_irq(requested_irq, handler, irqflags, devname, dev_id)); } +} + +#if !defined(CONFIG_IA64_SGI_IO) +void +sn1_pci_fixup(int arg) +{ +} +#endif + +int +bit_pos_to_irq(int bit) { +#define BIT_TO_IRQ 64 + + return bit + BIT_TO_IRQ; +} + +int +irq_to_bit_pos(int irq) { +#define IRQ_TO_BIT 64 + + return irq - IRQ_TO_BIT; } diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/llsc4.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/llsc4.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/llsc4.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/llsc4.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,943 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void bringup_set_led_bits(u8 bits, u8 mask); + +#include "llsc4.h" + + +#ifdef STANDALONE +#include "lock.h" +#endif + +#ifdef INTTEST +static int inttest=0; +#endif + + +/* + * Test parameter table for AUTOTEST + */ +typedef struct { + int passes; + int linecount; + int linepad; +} autotest_table_t; + +autotest_table_t autotest_table[] = { + {1000000, 2, 0x2b4 }, + {1000000, 16, 0, }, + {1000000, 16, 4, }, + {1000000, 128, 0x44 }, + {1000000, 128, 0x84 }, + {1000000, 128, 0x200 }, + {1000000, 128, 0x204 }, + {1000000, 128, 0x2b4 }, + {1000000, 2, 8*MB+0x2b4 }, + {1000000, 16, 8*MB+0 }, + {1000000, 16, 8*MB+4 }, + {1000000, 128, 8*MB+0x44 }, + {1000000, 128, 8*MB+0x84 }, + {1000000, 128, 8*MB+0x200 }, + {1000000, 128, 8*MB+0x204 }, + {1000000, 128, 8*MB+0x2b4 }, + {0}}; + +/* + * Array of virtual addresses available for test purposes. + */ + +typedef struct { + long vstart; + long vend; + long nextaddr; + int wrapcount; +} memmap_t; + +memmap_t memmap[MAXCHUNKS]; +int memmapx=0; + +typedef struct { + void *addr; + long data[16]; + long data_fc[16]; +} capture_line_t; + +typedef struct { + int size; + void *blockaddr; + void *shadaddr; + long blockdata[16]; + long shaddata[16]; + long blockdata_fc[16]; + long shaddata_fc[16]; + long synerr; +} capture_t; + +/* + * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and + * the rest of the tables have to start at 1MB to skip PROM tables. + */ +#define THREADPRIVATE(t) ((threadprivate_t*)(((long)mbase)+1024*1024+t*((sizeof(threadprivate_t)+511)/512*512))) + +#define k_capture mbase->sk_capture +#define k_go mbase->sk_go +#define k_linecount mbase->sk_linecount +#define k_passes mbase->sk_passes +#define k_napticks mbase->sk_napticks +#define k_stop_on_error mbase->sk_stop_on_error +#define k_verbose mbase->sk_verbose +#define k_threadprivate mbase->sk_threadprivate +#define k_blocks mbase->sk_blocks +#define k_iter_msg mbase->sk_iter_msg +#define k_vv mbase->sk_vv +#define k_linepad mbase->sk_linepad +#define k_options mbase->sk_options +#define k_testnumber mbase->sk_testnumber +#define k_currentpass mbase->sk_currentpass + +static long blocks[MAX_LINECOUNT]; /* addresses of data blocks */ +static control_t *mbase; +static vint initialized=0; + +static unsigned int ran_conf_llsc(int); +static int rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int); +static void dumpline(void *, char *, char *, void *, void *, int); +static int checkstop(int, int, uint); +static void spin(int); +static void capturedata(capture_t *, uint, void *, void *, int); +static int randn(uint max, uint *seed); +static uint zrandom (uint *zranseed); +static int set_lock(uint *, uint); +static int clr_lock(uint *, uint); +static void Speedo(void); + +int autotest_enabled=0; +static int autotest_explicit_flush=0; +static int llsctest_number=-1; +static int errstop_enabled=0; +static int fail_enabled=0; +static int selective_trigger=0; + +static int __init autotest_enable(char *str) +{ + autotest_enabled = 1; + return 1; +} +static int __init set_llscxflush(char *str) +{ + autotest_explicit_flush = 1; + return 1; +} +static int __init set_llscselt(char *str) +{ + selective_trigger = 1; + return 1; +} +static int __init set_llsctest(char *str) +{ + llsctest_number = simple_strtol(str, &str, 10); + if (llsctest_number < 0 || llsctest_number > 15) + llsctest_number = -1; + return 1; +} +static int __init set_llscerrstop(char *str) +{ + errstop_enabled = 1; + return 1; +} +static int __init set_llscfail(char *str) +{ + fail_enabled = 8; + return 1; +} + +static void print_params(void) +{ + printk ("********* Enter AUTOTEST facility on master cpu *************\n"); + printk (" Test options:\n"); + printk (" llsctest=\t%d\tTest number to run (all = -1)\n", llsctest_number); + printk (" llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off"); + printk (" llscxflush \t%s\tEnable explicit FC in test\n", autotest_explicit_flush ? "on" : "off"); + printk (" llscfail \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off"); + printk (" llscselt \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off"); + printk ("\n"); +} +__setup("autotest", autotest_enable); +__setup("llsctest=", set_llsctest); +__setup("llscerrstop", set_llscerrstop); +__setup("llscxflush", set_llscxflush); +__setup("llscfail", set_llscfail); +__setup("llscselt", set_llscselt); + + +extern inline void +flush_buddy(void *p) +{ + long lp; + + if (autotest_explicit_flush) { + lp = (long)p; + lp ^= 0x40; + asm volatile ("fc %0" :: "r"(lp) : "memory"); + ia64_sync_i(); + ia64_srlz_d(); + } +} + +static int +set_lock(uint *lock, uint id) +{ + uint old; + flush_buddy(lock); + old = cmpxchg_acq(lock, 0, id); + return (old == 0); +} + +static int +clr_lock(uint *lock, uint id) +{ + uint old; + flush_buddy(lock); + old = cmpxchg_rel(lock, id, 0); + return (old == id); +} + +static void +zero_lock(uint *lock) +{ + flush_buddy(lock); + *lock = 0; +} + +/*------------------------------------------------------------------------+ +| Routine : ran_conf_llsc - ll/sc shared data test | +| Description: This test checks the coherency of shared data | ++------------------------------------------------------------------------*/ +static unsigned int +ran_conf_llsc(int thread) +{ + private_t pval; + share_t sval, sval2; + uint vv, linei, slinei, sharei, pass; + long t; + lock_t lockpat; + share_t *sharecopy; + long verbose, napticks, passes, linecount, lcount; + dataline_t *linep, *slinep; + int s, seed; + threadprivate_t *tp; + uint iter_msg, iter_msg_i=0; + int vv_mask; + int correct_errors; + int errs=0; + int stillbad; + capture_t capdata; + private_t *privp; + share_t *sharep; + + + linecount = k_linecount; + napticks = k_napticks; + verbose = k_verbose; + passes = k_passes; + iter_msg = k_iter_msg; + seed = (thread + 1) * 647; + tp = THREADPRIVATE(thread); + vv_mask = (k_vv>>((thread%16)*4)) & 0xf; + correct_errors = k_options&0xff; + + memset (&tp->private, 0, sizeof(tp->private)); + memset (&capdata, 0, sizeof(capdata)); + + for (pass = 1; passes == 0 || pass < passes; pass++) { + lockpat = (pass & 0x0fffffff) + (thread <<28); + tp->threadpasses = pass; + if (checkstop(thread, pass, lockpat)) + return 0; + iter_msg_i++; + if (iter_msg && iter_msg_i > iter_msg) { + printk("Thread %d, Pass %d\n", thread, pass); + iter_msg_i = 0; + } + lcount = 0; + + /* + * Select line to perform operations on. + */ + linei = randn(linecount, &seed); + sharei = randn(2, &seed); + slinei = (linei + (linecount/2))%linecount; /* I dont like this - fix later */ + + linep = (dataline_t *)blocks[linei]; + slinep = (dataline_t *)blocks[slinei]; + if (sharei == 0) + sharecopy = &slinep->share0; + else + sharecopy = &slinep->share1; + + + vv = randn(4, &seed); + if ((vv_mask & (1<private[thread]; + sharep = &linep->share[sharei]; + + switch(vv) { + case 0: + /* Read and verify private count on line. */ + pval = *privp; + if (verbose) + printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]); + if (pval != tp->private[linei]) { + capturedata(&capdata, pass, privp, NULL, sizeof(*privp)); + stillbad = (*privp != tp->private[linei]); + if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) { + return 1; + } + if (correct_errors) { + flush_buddy(privp); + tp->private[linei] = *privp; + } + errs++; + } + break; + + case 1: + /* Read, verify, and increment private count on line. */ + pval = *privp; + if (verbose) + printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]); + if (pval != tp->private[linei]) { + capturedata(&capdata, pass, privp, NULL, sizeof(*privp)); + stillbad = (*privp != tp->private[linei]); + if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) { + return 1; + } + errs++; + } + pval++; + flush_buddy(privp); + *privp = pval; + tp->private[linei] = pval; + break; + + case 2: + /* Lock line, read and verify shared data. */ + if (verbose) + printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy); + lcount = 0; + while (LOCK(sharei) != 1) { + if (checkstop(thread, pass, lockpat)) + return 0; + if (lcount++>1000000) { + capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t)); + stillbad = (GETLOCK(sharei) != 0); + rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad); + return 1; + } + if ((lcount&0x3fff) == 0) + udelay(1000); + } + + sval = *sharep; + sval2 = *sharecopy; + if (pass > 12 && thread == 0 && fail_enabled == 1) + sval++; + if (sval != sval2) { + capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy)); + stillbad = (*sharep != *sharecopy); + if (!stillbad && *sharep != sval && *sharecopy == sval2) + stillbad = 2; + if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) { + return 1; + } + if (correct_errors) + *sharep = *sharecopy; + errs++; + } + + + if ( (s=UNLOCK(sharei)) != 1) { + capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4); + stillbad = (GETLOCK(sharei) != lockpat); + if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad)) + return 1; + if (correct_errors) + ZEROLOCK(sharei); + errs++; + } + break; + + case 3: + /* Lock line, read and verify shared data, modify shared data. */ + if (verbose) + printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy); + lcount = 0; + while (LOCK(sharei) != 1) { + if (checkstop(thread, pass, lockpat)) + return 0; + if (lcount++>1000000) { + capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t)); + stillbad = (GETLOCK(sharei) != 0); + rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad); + return 1; + } + if ((lcount&0x3fff) == 0) + udelay(1000); + } + sval = *sharep; + sval2 = *sharecopy; + if (sval != sval2) { + capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy)); + stillbad = (*sharep != *sharecopy); + if (!stillbad && *sharep != sval && *sharecopy == sval2) + stillbad = 2; + if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) { + return 1; + } + errs++; + } + + flush_buddy(sharep); + *sharep = lockpat; + flush_buddy(sharecopy); + *sharecopy = lockpat; + + + if ( (s=UNLOCK(sharei)) != 1) { + capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4); + stillbad = (GETLOCK(sharei) != lockpat); + if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad)) + return 1; + if (correct_errors) + ZEROLOCK(sharei); + errs++; + } + break; + } + } + + return (errs > 0); +} + +static void +trigger_la(long val) +{ + long *p; + + p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */ + *p = val; +} + +static long +getsynerr(void) +{ + long err, *errp; + + errp = (long*)0xc0000e0000000340L; /* SYN_ERR */ + err = *errp; + if (err) + *errp = -1L; + return (err & ~0x60); +} + +static int +rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int linei, int exp, int found, int stillbad) +{ + int cpu; + long synerr; + int selt; + + + selt = selective_trigger && stillbad > 1 && + memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 && + memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0; + if (selt) { + trigger_la(pass); + } else if (selective_trigger) { + k_go = ST_STOP; + return k_stop_on_error;; + } + + spin(1); + printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n", + msg, k_testnumber, thread, linei, pass, pass, jiffies, exp, found); + + dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size); + if (memcmp(cap->blockdata, cap->blockdata_fc, 128)) + dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size); + + if (cap->shadaddr) { + dumpline (slp, "Shadow data", "S ", cap->shadaddr, cap->shaddata, cap->size); + if (memcmp(cap->shaddata, cap->shaddata_fc, 128)) + dumpline (slp, "Shadow data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size); + } + + printk("Threadpasses: "); + for (cpu=0; cputhreadpasses) + printk(" %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses); + + + printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " ")); + synerr = getsynerr(); + if (synerr) + printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr); + spin(2); + printk("\n\n"); + + if (errstop_enabled) { + local_irq_disable(); + while(1); + } + return k_stop_on_error; +} + + +static void +dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size) +{ + long *p; + int i, off; + + printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp); + p = (long*) data; + for (i=0; i<16; i++, p++) { + if (i==0) printk("%2s", str2); + if (i==8) printk(" "); + printk(" %016lx", *p); + if ((i&7)==7) printk("\n"); + } + printk(" "); + off = (((long)addr) ^ size) & 63L; + for (i=0; i=off) ? "--" : " "); + if ((i%8) == 7) + printk(" "); + } + + off = ((long)addr) & 127; + printk(" (line %d)\n", off/64+1); +} + + +static int +randn(uint max, uint *seedp) +{ + if (max == 1) + return(0); + else + return((int)(zrandom(seedp)>>10) % max); +} + + +static int +checkstop(int thread, int pass, uint lockpat) +{ + long synerr; + + if (k_go == ST_RUN) + return 0; + if (k_go == ST_STOP) + return 1; + + if (errstop_enabled) { + local_irq_disable(); + while(1); + } + synerr = getsynerr(); + spin(2); + if (k_go == ST_STOP) + return 1; + if (synerr) + printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr); + return 1; +} + + +static void +spin(int j) +{ + udelay(j * 500000); +} + +static void +capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size) +{ + + if (!selective_trigger) + trigger_la (pass); + + memcpy (cap->blockdata, CACHEALIGN(blockaddr), 128); + if (shadaddr) + memcpy (cap->shaddata, CACHEALIGN(shadaddr), 128); + + if (k_stop_on_error) { + k_go = ST_ERRSTOP; + } + + cap->size = size; + cap->blockaddr = blockaddr; + cap->shadaddr = shadaddr; + + asm volatile ("fc %0" :: "r"(blockaddr) : "memory"); + ia64_sync_i(); + ia64_srlz_d(); + memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr), 128); + + if (shadaddr) { + asm volatile ("fc %0" :: "r"(shadaddr) : "memory"); + ia64_sync_i(); + ia64_srlz_d(); + memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr), 128); + } +} + +int zranmult = 0x48c27395; + +static uint +zrandom (uint *seedp) +{ + *seedp = (*seedp * zranmult) & 0x7fffffff; + return (*seedp); +} + + +void +set_autotest_params(void) +{ + static int testnumber=-1; + + if (llsctest_number >= 0) { + testnumber = llsctest_number; + } else { + testnumber++; + if (autotest_table[testnumber].passes == 0) + testnumber = 0; + } + k_passes = autotest_table[testnumber].passes; + k_linepad = autotest_table[testnumber].linepad; + k_linecount = autotest_table[testnumber].linecount; + k_testnumber = testnumber; + + if (IS_RUNNING_ON_SIMULATOR()) { + printk ("llsc start test %ld\n", k_testnumber); + k_passes = 1000; + } +} + + +static void +set_leds(int errs) +{ + unsigned char leds=0; + + /* + * Leds are: + * ppppeee- + * where + * pppp = test number + * eee = error count but top bit is stick + */ + + leds = ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0); + bringup_set_led_bits(leds, 0xfe); +} + +static void +setup_block_addresses(void) +{ + int i, stride, memmapi; + + stride = LINESTRIDE; + memmapi = 0; + for (i=0; i= memmap[memmapi].vend) { + memmap[memmapi].wrapcount++; + memmap[memmapi].nextaddr = memmap[memmapi].vstart + + memmap[memmapi].wrapcount * sizeof(dataline_t); + } + + memset((void*)blocks[i], 0, sizeof(dataline_t)); + + if (stride > 16384) { + memmapi++; + if (memmapi == memmapx) + memmapi = 0; + } + } + +} + +static void +set_thread_state(int cpuid, int state) +{ + if (k_threadprivate[cpuid]->threadstate == TS_KILLED) { + bringup_set_led_bits(0xfe, 0xfe); + while(1); + } + k_threadprivate[cpuid]->threadstate = state; +} + +static int +build_mem_map(unsigned long start, unsigned long end, void *arg) +{ + long lstart; + /* + * HACK - skip the kernel on the first node + */ + + printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", + start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE)); + + while (end > start && (PageReserved(virt_to_page(end-PAGE_SIZE)) || virt_to_page(end-PAGE_SIZE)->count.counter > 0)) + end -= PAGE_SIZE; + + lstart = end; + while (lstart > start && (!PageReserved(virt_to_page(lstart-PAGE_SIZE)) && virt_to_page(lstart-PAGE_SIZE)->count.counter == 0)) + lstart -= PAGE_SIZE; + + printk (" memmap: start 0x%lx, end 0x%lx\n", lstart, end); + if (lstart >= end) + return 0; + + memmap[memmapx].vstart = lstart; + memmap[memmapx].vend = end; + memmapx++; + return 0; +} + +void int_test(void); + +int +llsc_main (int cpuid, long mbasex) +{ + int i, cpu, is_master, repeatcnt=0; + unsigned int preverr=0, errs=0, pass=0; + int automode=0; + +#ifdef INTTEST + if (inttest) + int_test(); +#endif + + if (!autotest_enabled) + return 0; + +#ifdef CONFIG_SMP + is_master = !smp_processor_id(); +#else + is_master = 1; +#endif + + + if (is_master) { + print_params(); + if(!IS_RUNNING_ON_SIMULATOR()) + spin(10); + mbase = (control_t*)mbasex; + k_currentpass = 0; + k_go = ST_IDLE; + k_passes = DEF_PASSES; + k_napticks = DEF_NAPTICKS; + k_stop_on_error = DEF_STOP_ON_ERROR; + k_verbose = DEF_VERBOSE; + k_linecount = DEF_LINECOUNT; + k_iter_msg = DEF_ITER_MSG; + k_vv = DEF_VV; + k_linepad = DEF_LINEPAD; + k_blocks = (void*)blocks; + efi_memmap_walk(build_mem_map, 0); + +#ifdef CONFIG_IA64_SGI_AUTOTEST + automode = 1; +#endif + + for (i=0; i 5) { + set_autotest_params(); + repeatcnt = 0; + } + } else { + while (k_go == ST_IDLE); + } + + k_go = ST_INIT; + if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT; + k_linecount = k_linecount & ~1; + setup_block_addresses(); + + k_currentpass = pass++; + k_go = ST_RUN; + if (fail_enabled) + fail_enabled--; + + } else { + while (k_go != ST_RUN || k_currentpass != pass); + pass++; + } + + + set_leds(errs); + set_thread_state(cpuid, TS_RUNNING); + + errs += ran_conf_llsc(cpuid); + preverr = (k_go == ST_ERRSTOP); + + set_leds(errs); + set_thread_state(cpuid, TS_STOPPED); + + if (is_master) { + Speedo(); + for (i=0, cpu=0; cputhreadstate == TS_RUNNING) { + i++; + if (i == 10000) { + k_go = ST_STOP; + printk (" llsc master stopping test number %ld\n", k_testnumber); + } + if (i > 100000) { + k_threadprivate[cpu]->threadstate = TS_KILLED; + printk (" llsc: master killing cpuid %d, running test number %ld\n", + cpu, k_testnumber); + } + udelay(1000); + } + } + } + + goto loop; +} + + +static void +Speedo(void) +{ + static int i = 0; + + switch (++i%4) { + case 0: + printk("|\b"); + break; + case 1: + printk("\\\b"); + break; + case 2: + printk("-\b"); + break; + case 3: + printk("/\b"); + break; + } +} + +#ifdef INTTEST + +/* ======================================================================================================== + * + * Some test code to verify that interrupts work + * + * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback" + * if (zzzprint_resched) printk(" cpu %d got interrupt\n", smp_processor_id()); + * + * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs. + * + */ + +static int __init set_inttest(char *str) +{ + inttest = 1; + autotest_enabled = 1; + + return 1; +} + +__setup("inttest=", set_inttest); + +int zzzprint_resched=0; + +void +int_test() { + int mycpu, cpu; + static volatile int control_cpu=0; + + mycpu = smp_processor_id(); + zzzprint_resched = 2; + + printk("Testing cross interrupts\n"); + + while (control_cpu != smp_num_cpus) { + if (mycpu == cpu_logical_map(control_cpu)) { + for (cpu=0; cpulock[(i)] +#define LOCK(i) set_lock(LOCKADDR(i), lockpat) +#define UNLOCK(i) clr_lock(LOCKADDR(i), lockpat) +#define GETLOCK(i) *LOCKADDR(i) +#define ZEROLOCK(i) zero_lock(LOCKADDR(i)) + +#define CACHEALIGN(a) ((void*)((long)(a) & ~127L)) + +typedef uint lock_t; +typedef uint share_t; +typedef uint private_t; + +typedef struct { + lock_t lock[2]; + share_t share[2]; + private_t private[MAXCPUS]; + share_t share0; + share_t share1; +} dataline_t ; + + +#define LINEPAD k_linepad +#define LINESTRIDE (((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD) + + +typedef struct { + vint threadstate; + uint threadpasses; + private_t private[MAX_LINECOUNT]; +} threadprivate_t; + +typedef struct { + vlong sk_go; /* 0=idle, 1=init, 2=run */ + long sk_linecount; + long sk_passes; + long sk_napticks; + long sk_stop_on_error; + long sk_verbose; + long sk_iter_msg; + long sk_vv; + long sk_linepad; + long sk_options; + long sk_testnumber; + vlong sk_currentpass; + void *sk_blocks; + threadprivate_t *sk_threadprivate[MAXCPUS]; +} control_t; + +/* Run state (k_go) constants */ +#define ST_IDLE 0 +#define ST_INIT 1 +#define ST_RUN 2 +#define ST_STOP 3 +#define ST_ERRSTOP 4 + + +/* Threadstate constants */ +#define TS_STOPPED 0 +#define TS_RUNNING 1 +#define TS_KILLED 2 + + + +int llsc_main (int cpuid, long mbasex); + diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/mm.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/mm.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/mm.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/mm.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,398 @@ +/* + * Copyright, 2000, Silicon Graphics. + * Copyright Srinivasa Thirumalachar (sprasad@engr.sgi.com) + * Copyright 2000 Kanoj Sarcar (kanoj@sgi.com) + */ + +#include +#include +#include +#include +#include + +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +# define MAX(a,b) ((a) > (b) ? (a) : (b)) + +/* + * Note that the nodemem[] data structure does not support arbitrary + * memory types and memory descriptors inside the node. For example, + * you can not have multiple efi-mem-type segments in the node and + * expect the OS not to use specific mem-types. Currently, the + * assumption is that "start" is the start of virtual/physical memory + * on the node. PROM can reserve some memory _only_ at the beginning. + * This is tracked via the "usable" field, that maintains where the + * os can start using memory from on a node (ie end of PROM memory). + * setup_node_bootmem() is passed the above "usable" value, and is + * expected to make bootmem calls that ensure lower memory is not used. + * Note that the bootmem for a node is initialized on the entire node, + * without regards to any holes - then we reserve the holes in + * setup_sn1_bootmem(), to make sure the holes are not handed out by + * alloc_bootmem, as well as the corresponding mem_map entries are not + * considered allocatable by the page_alloc routines. + */ +struct nodemem_s { + u64 start ; + u64 end ; + u64 hole[SN1_MAX_BANK_PER_NODE] ; + u64 usable; +} nodemem[MAXNODES] ; +static int nodemem_valid = 0; + +static int __init +free_unused_memmap_hole(int nid, unsigned long start, unsigned long end) +{ + struct page * page, *pageend; + unsigned long count = 0; + + if (start >= end) + return 0 ; + + /* + * Get the memmap ptrs to the start and end of the holes. + * virt_to_page(start) will panic, if start is in hole. + * Can we do virt_to_page(end), if end is on the next node? + */ + + page = virt_to_page(start-1); + page++ ; + pageend = virt_to_page(end) ; + + printk("hpage=0x%lx, hpageend=0x%lx\n", (u64)page, (u64)pageend) ; + free_bootmem_node(NODE_DATA(nid), __pa(page), (u64)pageend - (u64)page); + + return count ; +} + +void +free_unused_memmap_node(int nid) +{ + u64 i = 0 ; + u64 holestart = -1 ; + + do { + holestart = nodemem[nid].hole[i] ; + i++ ; + while ((i < SN1_MAX_BANK_PER_NODE) && + (nodemem[nid].hole[i] == (u64)-1)) + i++ ; + if (i < SN1_MAX_BANK_PER_NODE) + free_unused_memmap_hole(nid, holestart, + nodemem[nid].start + (i<> PAGE_SHIFT; + + bank0size = nodemem[nid].hole[0] - nodemem[nid].start ; + /* If nid == master node && no kernel text replication */ + bank0size -= 0xA00000 ; /* Kernel text + stuff */ + bank0size -= ((numpfn + 7) >> 3); + + if ((numpfn * sizeof(mem_map_t)) > bank0size) { + printk("nid = %d, ns=0x%lx, npfn=0x%lx, bank0size=0x%lx\n", + nid, nodesize, numpfn, bank0size) ; + return 0 ; + } + + return 1 ; +} + +static void __init +check_pgtbl_size(int nid) +{ + int bank = SN1_MAX_BANK_PER_NODE - 1 ; + + /* Find highest bank with valid memory */ + while ((nodemem[nid].hole[bank] == -1) && (bank)) + bank-- ; + + while (!pgtbl_size_ok(nid)) { + /* Remove that bank of memory */ + /* Collect some numbers later */ + printk("Ignoring node %d bank %d\n", nid, bank) ; + nodemem[nid].hole[bank--] = -1 ; + /* Get to the next populated bank */ + while ((nodemem[nid].hole[bank] == -1) && (bank)) + bank-- ; + printk("Using only upto bank %d on node %d\n", bank,nid) ; + nodemem[nid].end = nodemem[nid].hole[bank] ; + if (!bank) break ; + } +} + +void dump_nodemem_map(int) ; + +#ifdef CONFIG_DISCONTIGMEM + +extern bootmem_data_t bdata[] ; +static int curnodeid ; + +static int __init +setup_node_bootmem(unsigned long start, unsigned long end, unsigned long nodefree) +{ + extern char _end; + int i; + unsigned long kernelend = PAGE_ALIGN((unsigned long)(&_end)); + unsigned long pkernelend = __pa(kernelend); + unsigned long bootmap_start, bootmap_size; + unsigned long pstart, pend; + + pstart = __pa(start) ; + pend = __pa(end) ; + + /* If we are past a node mem boundary, on simulated dig numa + * increment current node id. */ + + curnodeid = NASID_TO_CNODEID(GetNasId(pstart)) ; + + /* + * Make sure we are being passed page aligned addresses. + */ + if ((start & (PAGE_SIZE - 1)) || (end & (PAGE_SIZE - 1))) + panic("setup_node_bootmem:align"); + + + /* For now, just go to the lower CHUNK alignment so that + * chunktonid of 0-8MB and other lower mem pages get initted. */ + + pstart &= CHUNKMASK ; + pend = (pend+CHUNKSZ-1) & CHUNKMASK; + + /* If pend == 0, both addrs below 8 MB, special case it + * FIX: CHUNKNUM(pend-1) broken if pend == 0 + * both addrs within 8MB */ + + if (pend == 0) { + chunktonid[0] = 0; + return 0; + } + + /* Fill up the chunktonid array first. */ + + for (i = PCHUNKNUM(pstart); i <= PCHUNKNUM(pend-1); i++) + chunktonid[i] = curnodeid; + + /* This check is bogus for now till MAXCHUNKS is properly + * defined to say if it includes holes or not. */ + + if ((CHUNKTONID(PCHUNKNUM(pend)) > MAXCHUNKS) || + (PCHUNKNUM(pstart) >= PCHUNKNUM(pend))) { + printk("Ign 0x%lx-0x%lx, ", __pa(start), __pa(end)); + return(0); + } + + /* This routine gets called many times in node 0. + * The first one to reach here would be the one after + * kernelend to end of first node. */ + + NODE_DATA(curnodeid)->bdata = &(bdata[curnodeid]); + + if (curnodeid == 0) { + /* for master node, forcibly assign these values + * This gets called many times on dig but we + * want these exact values + * Also on softsdv, the memdesc for 0 is missing */ + NODE_START(curnodeid) = PAGE_OFFSET; + NODE_SIZE(curnodeid) = (end - PAGE_OFFSET); + } else { + /* This gets called only once for non zero nodes + * If it does not, then NODE_STARt should be + * LOCAL_BASE(nid) */ + + NODE_START(curnodeid) = start; + NODE_SIZE(curnodeid) = (end - start); + } + + /* if end < kernelend do not do anything below this */ + if (pend < pkernelend) + return 0 ; + + /* + * Handle the node that contains kernel text/data. It would + * be nice if the loader loads the kernel at a "chunk", ie + * not in memory that the kernel will ignore (else free_initmem + * has to worry about not freeing memory that the kernel ignores). + * Note that we assume the space from the node start to + * KERNEL_START can not hold all the bootmem data, but from kernel + * end to node end can. + */ + + /* TBD: This may be bogus in light of the above check. */ + + if ((pstart < pkernelend) && (pend >= pkernelend)) { + bootmap_start = pkernelend; + } else { + bootmap_start = __pa(start); /* chunk & page aligned */ + } + + /* + * Low memory is reserved for PROM use on SN1. The current node + * memory model is [PROM mem ... kernel ... free], where the + * first two components are optional on a node. + */ + if (bootmap_start < __pa(nodefree)) + bootmap_start = __pa(nodefree); + +/* XXX TBD */ +/* For curnodeid of 0, this gets called many times because of many + * < 8MB segments. start gets bumped each time. We want to fix it + * to 0 now. + */ + if (curnodeid == 0) + start=PAGE_OFFSET; +/* + * This makes sure that in free_area_init_core - paging_init + * idx is the entire node page range and for loop goes thro + * all pages. test_bit for kernel pages should remain reserved + * because free available mem takes care of kernel_start and end + */ + + bootmap_size = init_bootmem_node(NODE_DATA(curnodeid), + (bootmap_start >> PAGE_SHIFT), + (__pa(start) >> PAGE_SHIFT), (__pa(end) >> PAGE_SHIFT)); + + free_bootmem_node(NODE_DATA(curnodeid), bootmap_start + bootmap_size, + __pa(end) - (bootmap_start + bootmap_size)); + + return(0); +} + +void +setup_sn1_bootmem(int maxnodes) +{ + int i; + + for (i=0;i> SN1_NODE_ADDR_SHIFT) << + SN1_NODE_ADDR_SHIFT); + nodemem_valid = 1 ; + + /* After building the nodemem map, check if the page table + * will fit in the first bank of each node. If not change + * the node end addr till it fits. We dont want to do this + * in mm/page_alloc.c + */ + + for (i=0;i ") ; + for (j=0;j #include #include +#include +#include #include #include #include #include - /* * The format of "screen_info" is strange, and due to early i386-setup * code. This is just enough to make the console code think we're on a @@ -50,29 +51,48 @@ unsigned long sn1_map_nr (unsigned long addr) { +#ifdef CONFIG_DISCONTIGMEM return MAP_NR_SN1(addr); +#else + return MAP_NR_DENSE(addr); +#endif } -void +void __init sn1_setup(char **cmdline_p) { - + extern void init_sn1_smp_config(void); ROOT_DEV = to_kdev_t(0x0301); /* default to first IDE drive */ + init_sn1_smp_config(); +#ifdef ZZZ #if !defined (CONFIG_IA64_SOFTSDV_HACKS) - /* - * Program the timer to deliver timer ticks. 0x40 is the I/O port - * address of PIT counter 0, 0x43 is the I/O port address of the - * PIT control word. - */ - request_region(0x40,0x20,"timer"); - outb(0x34, 0x43); /* Control word */ - outb(LATCH & 0xff , 0x40); /* LSB */ - outb(LATCH >> 8, 0x40); /* MSB */ - printk("PIT: LATCH at 0x%x%x for %d HZ\n", LATCH >> 8, LATCH & 0xff, HZ); + /* + * Program the timer to deliver timer ticks. 0x40 is the I/O port + * address of PIT counter 0, 0x43 is the I/O port address of the + * PIT control word. + */ + request_region(0x40,0x20,"timer"); + outb(0x34, 0x43); /* Control word */ + outb(LATCH & 0xff , 0x40); /* LSB */ + outb(LATCH >> 8, 0x40); /* MSB */ + printk("PIT: LATCH at 0x%x%x for %d HZ\n", LATCH >> 8, LATCH & 0xff, HZ); +#endif #endif #ifdef CONFIG_SMP init_smp_config(); #endif screen_info = sn1_screen_info; +} + +int +IS_RUNNING_ON_SIMULATOR(void) +{ +#ifdef CONFIG_IA64_SGI_SN1_SIM + long sn; + asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); + return(sn == SNMAGIC); +#else + return(0); +#endif } diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/smp.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/smp.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/smp.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/smp.c Wed Nov 15 19:11:35 2000 @@ -0,0 +1,186 @@ +/* + * SN1 Platform specific SMP Support + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 Jack Steiner + */ + + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + + + +/* + * The following structure is used to pass params thru smp_call_function + * to other cpus for flushing TLB ranges. + */ +typedef struct { + unsigned long start; + unsigned long end; + unsigned long nbits; +} ptc_params_t; + + +/* + * The following table/struct is for remembering PTC coherency domains. It + * is also used to translate sapicid into cpuids. We dont want to start + * cpus unless we know their cache domain. + */ +#ifdef PTC_NOTYET +sn_sapicid_info_t sn_sapicid_info[NR_CPUS]; +#endif + + + +#ifdef PTC_NOTYET +/* + * NOTE: This is probably not good enough, but I dont want to try to make + * it better until I get some statistics on a running system. + * At a minimum, we should only send IPIs to 1 processor in each TLB domain + * & have it issue a ptc.g on it's own FSB. Also, serialize per FSB, not + * globally. + * + * More likely, we will have to do some work to reduce the frequency of calls to + * this routine. + */ + +static void +sn1_ptc_local(void *arg) +{ + ptc_params_t *params = arg; + unsigned long start, end, nbits; + + start = params->start; + end = params->end; + nbits = params->nbits; + + do { + __asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory"); + start += (1UL << nbits); + } while (start < end); +} + + +void +sn1_ptc_global (unsigned long start, unsigned long end, unsigned long nbits) +{ + ptc_params_t params; + + params.start = start; + params.end = end; + params.nbits = nbits; + + if (smp_call_function(sn1_ptc_local, ¶ms, 1, 0) != 0) + panic("Unable to do ptc_global - timed out"); + + sn1_ptc_local(¶ms); +} +#endif + + + + +void +sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect) +{ + long *p, nasid, slice; + static int off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088}; + + /* + * ZZZ - Replace with standard macros when available. + */ + nasid = cpuid_to_nasid(cpuid); + slice = cpuid_to_slice(cpuid); + p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]); + +#if defined(ZZZBRINGUP) + { + static int count=0; + if (count++ < 10) printk("ZZ sendIPI 0x%x->0x%x, vec %d, nasid 0x%lx, slice %ld, adr 0x%lx\n", + smp_processor_id(), cpuid, vector, nasid, slice, (long)p); + } +#endif + mb(); + *p = (delivery_mode << 8) | (vector & 0xff); + +} + + +#ifdef CONFIG_SMP + +static void __init +process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain) +{ +#ifdef PTC_NOTYET + ia64_sal_ptc_domain_proc_entry_t *pe; + int i, sapicid, cpuid; + + pe = __va(di->proc_list); + for (i=0; iproc_count; i++, pe++) { + sapicid = id_eid_to_sapicid(pe->id, pe->eid); + cpuid = cpu_logical_id(sapicid); + sn_sapicid_info[cpuid].domain = domain; + sn_sapicid_info[cpuid].sapicid = sapicid; + } +#endif +} + + +static void __init +process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc) +{ + ia64_sal_ptc_domain_info_t *di; + int i; + + di = __va(ptc->domain_info); + for (i=0; inum_domains; i++, di++) { + process_sal_ptc_domain_info(di, i); + } +} + + +void __init +init_sn1_smp_config(void) +{ + + if (!ia64_ptc_domain_info) { + printk("SMP: Can't find PTC domain info. Forcing UP mode\n"); + smp_num_cpus = 1; + return; + } + +#ifdef PTC_NOTYET + memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info)); + process_sal_desc_ptc(ia64_ptc_domain_info); +#endif + +} + +#else /* CONFIG_SMP */ + +void __init +init_sn1_smp_config(void) +{ + +#ifdef PTC_NOTYET + sn_sapicid_info[0].sapicid = hard_processor_sapicid(); +#endif +} + +#endif /* CONFIG_SMP */ diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/sn1_asm.S linux-2.4.0-test12-lia/arch/ia64/sn/sn1/sn1_asm.S --- linux-2.4.0-test12/arch/ia64/sn/sn1/sn1_asm.S Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/sn1_asm.S Wed Dec 13 18:59:33 2000 @@ -0,0 +1,8 @@ + +/* + * Copyright (C) 2000 Silicon Graphics + * Copyright (C) 2000 Jack Steiner (steiner@sgi.com) + */ + +#include + diff -urN linux-2.4.0-test12/arch/ia64/sn/sn1/synergy.c linux-2.4.0-test12-lia/arch/ia64/sn/sn1/synergy.c --- linux-2.4.0-test12/arch/ia64/sn/sn1/synergy.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/sn1/synergy.c Wed Dec 6 21:54:10 2000 @@ -0,0 +1,205 @@ + +/* + * SN1 Platform specific synergy Support + * + * Copyright (C) 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 Alan Mayer (ajm@sgi.com) + */ + + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int bit_pos_to_irq(int bit); +void setclear_mask_b(int irq, int cpuid, int set); +void setclear_mask_a(int irq, int cpuid, int set); +void * kmalloc(size_t size, int flags); + +extern struct sn1_cnode_action_list *sn1_node_actions[]; + + +void +synergy_intr_alloc(int bit, int cpuid) { + return; +} + +int +synergy_intr_connect(int bit, + int cpuid) +{ + int irq; + unsigned is_b; +int nasid; + +nasid = cpuid_to_nasid(cpuid); + irq = bit_pos_to_irq(bit); + + is_b = (cpuid_to_slice(cpuid)) & 1; + if (is_b) { + setclear_mask_b(irq,cpuid,1); + setclear_mask_a(irq,cpuid, 0); + } else { + setclear_mask_a(irq, cpuid, 1); + setclear_mask_b(irq, cpuid, 0); + } + return 0; +} +void +setclear_mask_a(int irq, int cpuid, int set) +{ + int synergy; + int nasid; + int reg_num; + unsigned long mask; + unsigned long addr; + unsigned long reg; + unsigned long val; + int my_cnode, my_synergy; + int target_cnode, target_synergy; + + /* + * Perform some idiot checks .. + */ + if ( (irq < 0) || (irq > 255) || + (cpuid < 0) || (cpuid > 512) ) { + printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid); + return; + } + + target_cnode = cpuid_to_cnodeid(cpuid); + target_synergy = cpuid_to_synergy(cpuid); + my_cnode = cpuid_to_cnodeid(smp_processor_id()); + my_synergy = cpuid_to_synergy(smp_processor_id()); + + reg_num = irq / 64; + mask = 1; + mask <<= (irq % 64); + switch (reg_num) { + case 0: + reg = VEC_MASK0A; + addr = VEC_MASK0A_ADDR; + break; + case 1: + reg = VEC_MASK1A; + addr = VEC_MASK1A_ADDR; + break; + case 2: + reg = VEC_MASK2A; + addr = VEC_MASK2A_ADDR; + break; + case 3: + reg = VEC_MASK3A; + addr = VEC_MASK3A_ADDR; + break; + default: + reg = addr = 0; + break; + } + if (my_cnode == target_cnode && my_synergy == target_synergy) { + // local synergy + val = READ_LOCAL_SYNERGY_REG(addr); + if (set) { + val |= mask; + } else { + val &= ~mask; + } + WRITE_LOCAL_SYNERGY_REG(addr, val); + val = READ_LOCAL_SYNERGY_REG(addr); + } else { /* remote synergy */ + synergy = cpuid_to_synergy(cpuid); + nasid = cpuid_to_nasid(cpuid); + val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg); + if (set) { + val |= mask; + } else { + val &= ~mask; + } + REMOTE_SYNERGY_STORE(nasid, synergy, reg, val); + } +} + +void +setclear_mask_b(int irq, int cpuid, int set) +{ + int synergy; + int nasid; + int reg_num; + unsigned long mask; + unsigned long addr; + unsigned long reg; + unsigned long val; + int my_cnode, my_synergy; + int target_cnode, target_synergy; + + /* + * Perform some idiot checks .. + */ + if ( (irq < 0) || (irq > 255) || + (cpuid < 0) || (cpuid > 512) ) { + printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid); + return; + } + + target_cnode = cpuid_to_cnodeid(cpuid); + target_synergy = cpuid_to_synergy(cpuid); + my_cnode = cpuid_to_cnodeid(smp_processor_id()); + my_synergy = cpuid_to_synergy(smp_processor_id()); + + reg_num = irq / 64; + mask = 1; + mask <<= (irq % 64); + switch (reg_num) { + case 0: + reg = VEC_MASK0B; + addr = VEC_MASK0B_ADDR; + break; + case 1: + reg = VEC_MASK1B; + addr = VEC_MASK1B_ADDR; + break; + case 2: + reg = VEC_MASK2B; + addr = VEC_MASK2B_ADDR; + break; + case 3: + reg = VEC_MASK3B; + addr = VEC_MASK3B_ADDR; + break; + default: + reg = addr = 0; + break; + } + if (my_cnode == target_cnode && my_synergy == target_synergy) { + // local synergy + val = READ_LOCAL_SYNERGY_REG(addr); + if (set) { + val |= mask; + } else { + val &= ~mask; + } + WRITE_LOCAL_SYNERGY_REG(addr, val); + val = READ_LOCAL_SYNERGY_REG(addr); + } else { /* remote synergy */ + synergy = cpuid_to_synergy(cpuid); + nasid = cpuid_to_nasid(cpuid); + val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg); + if (set) { + val |= mask; + } else { + val &= ~mask; + } + REMOTE_SYNERGY_STORE(nasid, synergy, reg, val); + } +} diff -urN linux-2.4.0-test12/arch/ia64/sn/tools/make_textsym linux-2.4.0-test12-lia/arch/ia64/sn/tools/make_textsym --- linux-2.4.0-test12/arch/ia64/sn/tools/make_textsym Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/arch/ia64/sn/tools/make_textsym Wed Dec 6 21:54:10 2000 @@ -0,0 +1,138 @@ +#!/bin/sh +# Build a textsym file for use in the Arium ITP probe. + +help() { +cat < []] + 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` + +LINUX=${1:-vmlinux} +TEXTSYM=${2:-${LINUX}.sym} + +[ -f $VMLINUX ] || help + + +# pipe everything thru sort +echo "TEXTSYM V1.0" +(cat <&2 +echo " $LINUX --> $TEXTSYM" >&2 +echo " Found $N symbols" >&2 diff -urN linux-2.4.0-test12/arch/ia64/tools/print_offsets.c linux-2.4.0-test12-lia/arch/ia64/tools/print_offsets.c --- linux-2.4.0-test12/arch/ia64/tools/print_offsets.c Fri Jul 14 16:08:12 2000 +++ linux-2.4.0-test12-lia/arch/ia64/tools/print_offsets.c Wed Nov 15 18:10:14 2000 @@ -149,7 +149,7 @@ { "IA64_SWITCH_STACK_AR_UNAT_OFFSET", offsetof (struct switch_stack, ar_unat) }, { "IA64_SWITCH_STACK_AR_RNAT_OFFSET", offsetof (struct switch_stack, ar_rnat) }, { "IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET", offsetof (struct switch_stack, ar_bspstore) }, - { "IA64_SWITCH_STACK_PR_OFFSET", offsetof (struct switch_stack, b0) }, + { "IA64_SWITCH_STACK_PR_OFFSET", offsetof (struct switch_stack, pr) }, { "IA64_SIGCONTEXT_AR_BSP_OFFSET", offsetof (struct sigcontext, sc_ar_bsp) }, { "IA64_SIGCONTEXT_AR_RNAT_OFFSET", offsetof (struct sigcontext, sc_ar_rnat) }, { "IA64_SIGCONTEXT_FLAGS_OFFSET", offsetof (struct sigcontext, sc_flags) }, diff -urN linux-2.4.0-test12/drivers/acpi/Makefile linux-2.4.0-test12-lia/drivers/acpi/Makefile --- linux-2.4.0-test12/drivers/acpi/Makefile Fri Sep 15 18:21:43 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/Makefile Mon Nov 20 17:45:48 2000 @@ -12,22 +12,33 @@ M_OBJS := export ACPI_CFLAGS -ACPI_CFLAGS := -D_LINUX +ifdef CONFIG_ACPI_KERNEL_CONFIG + ACPI_CFLAGS := -D_LINUX -DCONFIG_ACPI_KERNEL_CONFIG_ONLY +else + ACPI_CFLAGS := -D_LINUX +endif EXTRA_CFLAGS += -I./include EXTRA_CFLAGS += $(ACPI_CFLAGS) # if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) SUB_DIRS += common dispatcher events hardware\ interpreter namespace parser resources tables ACPI_OBJS := $(patsubst %,%.o,$(SUB_DIRS)) - ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) +# ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) + +ifdef CONFIG_ACPI_KERNEL_CONFIG + ACPI_OBJS += acpiconf.o osconf.o os.o +else + ACPI_OBJS += driver.o cmbatt.o cpu.o ec.o ksyms.o os.o sys.o table.o +endif O_OBJS += $(ACPI_OBJS) + OX_OBJS = ksyms.o endif include $(TOPDIR)/Rules.make diff -urN linux-2.4.0-test12/drivers/acpi/acpiconf.c linux-2.4.0-test12-lia/drivers/acpi/acpiconf.c --- linux-2.4.0-test12/drivers/acpi/acpiconf.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/acpiconf.c Mon Nov 20 21:09:52 2000 @@ -0,0 +1,398 @@ +/* + * acpiconf.c - ACPI based kernel configuration + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + * + * revision history: + * 9/15/2000 J.I. + * Major revision: for new ACPI initialization requirements + * for ACPI CA label 915 + * 11/15/2000 J.I. + * Major revision: ACPI 2.0 tables support with ACPI CA label 1115 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include "acpi.h" +#include "osconf.h" +#include "acpiconf.h" + + +static int acpi_cf_initialized __initdata = 0; + +ACPI_STATUS __init +acpi_cf_init ( + void * rsdp + ) +{ + ACPI_STATUS status; + + acpi_os_bind_osd(ACPI_CF_PHASE_BOOTTIME); + + status = acpi_initialize_subsystem (); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:initialize_subsystem error=0x%x\n", status); + return status; + } + dprintk(("Acpi cfg:initializ_subsysteme pass\n")); + + status = acpi_load_tables ((u64)rsdp); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:load firmware tables error=0x%x\n", status); + acpi_terminate(); + return status; + } + dprintk(("Acpi cfg:load firmware tables pass\n")); + + status = acpi_enable_subsystem (ACPI_FULL_INITIALIZATION); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:enable_subsystem error=0x%x\n", status); + acpi_terminate(); + return status; + } + dprintk(("Acpi cfg:enable_subsystem pass\n")); + + acpi_cf_initialized++; + + return AE_OK; +} + + +ACPI_STATUS __init +acpi_cf_terminate ( void ) +{ + ACPI_STATUS status; + + if (! ACPI_CF_INITIALIZED()) + return AE_ERROR; + + status = acpi_disable (); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:disable fail=0x%x\n", status); + /* fall thru...*/ + } + + status = acpi_terminate (); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:acpi terminate error=0x%x\n", status); + /* fall thru...*/ + } + + acpi_cf_cleanup(); + acpi_os_bind_osd(ACPI_CF_PHASE_RUNTIME); + + acpi_cf_initialized--; + + return status; +} + + +ACPI_STATUS __init +acpi_cf_get_pci_vectors ( + struct pci_vector_struct **vectors, + int *num_pci_vectors + ) +{ + ACPI_STATUS status; + void *prts; + + if (! ACPI_CF_INITIALIZED()) { + status = acpi_cf_init((void *)efi.acpi); + if (ACPI_FAILURE (status)) + return status; + } + + *vectors = NULL; + *num_pci_vectors = 0; + + status = acpi_cf_get_prt (&prts); + if (ACPI_FAILURE (status)) { + printk("Acpi Cfg: get prt fail\n"); + return status; + } + + status = acpi_cf_convert_prt_to_vectors (prts, vectors, num_pci_vectors); +#ifdef CONFIG_ACPI_KERNEL_CONFIG_DEBUG + if (ACPI_SUCCESS(status)) { + acpi_cf_print_pci_vectors (*vectors, *num_pci_vectors); + } +#endif + printk("Acpi Cfg: get PRT %s\n", (ACPI_SUCCESS(status))?"pass":"fail"); + + return status; +} + + +static PCI_ROUTING_TABLE *pci_routing_tables[PCI_MAX_BUS] __initdata = {NULL}; +static struct pci_vector_struct *vectors_to_free __initdata = NULL; + + +static ACPI_STATUS __init +acpi_cf_get_prt ( + void **prts + ) +{ + ACPI_STATUS status; + + status = acpi_walk_namespace ( ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + acpi_cf_get_prt_callback, + NULL, + NULL ); + + if (ACPI_FAILURE(status)) { + printk("Acpi cfg:walk namespace error=0x%x\n", status); + } + + *prts = (void *)pci_routing_tables; + + return status; +} + + +static ACPI_STATUS __init +acpi_cf_get_prt_callback ( + ACPI_HANDLE handle, + UINT32 Level, + void *context, + void **retval + ) +{ + ACPI_BUFFER acpi_buffer; + PCI_ROUTING_TABLE *prt; + NATIVE_UINT busnum = 0; + static NATIVE_UINT next_busnum = 0; + ACPI_STATUS status; + + ACPI_BUFFER ret_buf; + ACPI_OBJECT *ext_obj; + UINT8 buf[PATHNAME_MAX]; + + + acpi_buffer.length = 0; + acpi_buffer.pointer = NULL; + + status = acpi_get_irq_routing_table (handle, &acpi_buffer); + + switch (status) { + case AE_BUFFER_OVERFLOW: + dprintk(("Acpi Cfg: _PRT found. Need %d bytes\n", acpi_buffer.length)); + break; /* found */ + case AE_NOT_FOUND: + return AE_OK; /* let acpi_walk_namespace continue. */ + default: + printk("Acpi cfg:get irq routing table fail=0x%x\n", status); + return AE_ERROR; + } + + prt = (PCI_ROUTING_TABLE *) acpi_os_callocate (acpi_buffer.length); + if (prt == NULL) { + printk("Acpi cfg:callocate %d bytes Fail\n", acpi_buffer.length); + return AE_ERROR; + } + acpi_buffer.pointer = (void *) prt; + + status = acpi_get_irq_routing_table (handle, &acpi_buffer); + if (ACPI_FAILURE(status)) { + printk("Acpi cfg:get irq routing table Fail=0x%x\n", status); + acpi_os_free(prt); + return AE_OK; + } + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_DEBUG + ret_buf.length = PATHNAME_MAX; + ret_buf.pointer = (void *) buf; + + status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); + if (ACPI_SUCCESS(status)) { + printk("Acpi cfg:path=[%s]\n", (char *)ret_buf.pointer); + } +#endif + + ret_buf.length = PATHNAME_MAX; + ret_buf.pointer = (void *) buf; + + status = acpi_evaluate_object(handle, METHOD_NAME__BBN, NULL, &ret_buf); + if (ACPI_FAILURE(status)) { + if (status == AE_NOT_FOUND) { + printk("Acpi cfg:_BBN not found for _PRT %ld: set busnum to %ld\n", next_busnum, next_busnum); + } else { + printk("Acpi cfg:_BBN fail=0x%x for _PRT %ld: set busnum to %ld\n", status, next_busnum, next_busnum); + } + if (next_busnum) + printk("Acpi cfg: Warning: Invalid or unimplemented _BBNs for PRTs may cause incorrect PCI vector configuration. Check AML\n"); + busnum = next_busnum++; + } else { + ext_obj = (ACPI_OBJECT *) ret_buf.pointer; + + switch (ext_obj->type) { + case ACPI_TYPE_NUMBER: + busnum = (NATIVE_UINT) ext_obj->number.value; + next_busnum = busnum + 1; + dprintk(("Acpi cfg:_BBN busnum is %ld\n ", busnum)); + break; + default: + printk("Acpi cfg:_BBN object type incorrect: set busnum to %ld\n ", next_busnum); + printk("Acpi cfg: Warning: Invalid _BBN for PRT may cause incorrect PCI vector configuration. Check AML\n"); + busnum = next_busnum++; + break; + } + + /* + * Placeholder for PCI SEG when PAL supports it, + * status = acpi_evaluate_object(handle, "_SEG", NULL, &ret_buf); + */ + } + + + ret_buf.length = PATHNAME_MAX; + ret_buf.pointer = (void *) buf; + + status = acpi_evaluate_object(handle, METHOD_NAME__STA, NULL, &ret_buf); + if (ACPI_FAILURE(status)) { + if (status == AE_NOT_FOUND) + dprintk(("Acpi cfg:no _STA: pci bus %ld exist\n", busnum)); + else + printk("Acpi cfg:_STA fail=0x%x: pci bus %ld exist. Check AML\n", status, busnum); + } else { + ext_obj = (ACPI_OBJECT *) ret_buf.pointer; + + switch (ext_obj->type) { + case ACPI_TYPE_NUMBER: + if((NATIVE_UINT) ext_obj->number.value & ACPI_STA_DEVICE_PRESENT) { + dprintk(("Acpi cfg:_STA: pci bus %ld exist\n", busnum)); + } else { + printk("Acpi cfg:_STA: pci bus %ld not exist. Discarding the _PRT\n", busnum); + next_busnum--; + acpi_os_free(prt); + return AE_OK; + } + break; + default: + printk("Acpi cfg:_STA object type incorrect: pci bus %ld exist. Check AML\n", busnum); + break; + } + } + + + acpi_cf_add_to_pci_routing_tables (busnum, prt); + + return AE_OK; +} + + +static void __init +acpi_cf_add_to_pci_routing_tables ( + NATIVE_UINT busnum, + PCI_ROUTING_TABLE *prt + ) +{ + if ( busnum >= PCI_MAX_BUS ) { + printk("Acpi cfg:invalid pci bus number %ld\n", busnum); + acpi_os_free(prt); + return; + } + + if (pci_routing_tables[busnum]) { + printk("Acpi cfg:duplicate PRT for pci bus %ld. overiding...\n", busnum); + acpi_os_free(pci_routing_tables[busnum]); + /* override... */ + } + + pci_routing_tables[busnum] = prt; +} + + +#define DUMPVECTOR(pv) printk("PCI bus=0x%x id=0x%x pin=0x%x irq=0x%x\n", pv->bus, pv->pci_id, pv->pin, pv->irq); + +static ACPI_STATUS __init +acpi_cf_convert_prt_to_vectors ( + void *prts, + struct pci_vector_struct **vectors, + int *num_pci_vectors + ) +{ + struct pci_vector_struct *pvec; + PCI_ROUTING_TABLE **pprts, *prt, *prtf; + int nvec = 0; + int i; + + + pprts = (PCI_ROUTING_TABLE **)prts; + + for ( i = 0; i < PCI_MAX_BUS; i++) { + prt = *pprts++; + if (prt) { + for ( ; prt->length > 0; nvec++) { + prt = (PCI_ROUTING_TABLE *) ((NATIVE_UINT)prt + (NATIVE_UINT)prt->length); + //prt = ROUND_PTR_UP_TO_4(prt, PCI_ROUTING_TABLE); + } + } + } + + *num_pci_vectors = nvec; + *vectors = acpi_os_callocate (sizeof(struct pci_vector_struct) * nvec); + if (*vectors == NULL) { + printk("Acpi cfg:callocate error\n"); + return AE_NO_MEMORY; + } + + pvec = *vectors; + pprts = (PCI_ROUTING_TABLE **)prts; + + for ( i = 0; i < PCI_MAX_BUS; i++) { + prt = prtf = *pprts++; + if (prt) { + for ( ; prt->length > 0; pvec++) { + pvec->bus = (UINT16)i; + pvec->pci_id = prt->data.address; + pvec->pin = (UINT8)prt->data.pin; + pvec->irq = (UINT8)prt->data.source_index; + + prt = (PCI_ROUTING_TABLE *) ((NATIVE_UINT)prt + (NATIVE_UINT)prt->length); + //prt = ROUND_PTR_UP_TO_4(prt, PCI_ROUTING_TABLE); + } + acpi_os_free((void *)prtf); + } + } + + vectors_to_free = *vectors; + + return AE_OK; +} + + +void __init +acpi_cf_cleanup ( void ) +{ + /* nothing to free, pci_vectors are used by the kernel */ +} + + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_DEBUG +void __init +acpi_cf_print_pci_vectors ( + struct pci_vector_struct *vectors, + int num_pci_vectors + ) +{ + struct pci_vector_struct *pvec; + int i; + + printk("number of PCI interrupt vectors = %d\n", num_pci_vectors); + + pvec = vectors; + for (i = 0; i < num_pci_vectors; i++) { + DUMPVECTOR(pvec); + pvec++; + } +} +#endif diff -urN linux-2.4.0-test12/drivers/acpi/acpiconf.h linux-2.4.0-test12-lia/drivers/acpi/acpiconf.h --- linux-2.4.0-test12/drivers/acpi/acpiconf.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/acpiconf.h Wed Dec 6 17:20:11 2000 @@ -0,0 +1,63 @@ +/* + * acpiconf.h - ACPI based kernel configuration + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + */ + +#include + +#define PCI_MAX_BUS 0x100 +#define ACPI_STA_DEVICE_PRESENT 0x01 + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_DEBUG +#define ACPI_CF_INITIALIZED() (acpi_cf_initialized > 0) +#undef dprintk +#define dprintk(a) printk a +#else +#define ACPI_CF_INITIALIZED() 1 +#undef dprintk +#define dprintk(a) +#endif + + +extern +void __init +acpi_os_bind_osd(int acpi_phase); + + +static +ACPI_STATUS __init +acpi_cf_get_prt (void **prts); + + +static +ACPI_STATUS __init +acpi_cf_get_prt_callback ( + ACPI_HANDLE handle, + UINT32 level, + void *context, + void **retval + ); + + +static +void __init +acpi_cf_add_to_pci_routing_tables ( + NATIVE_UINT busnum, + PCI_ROUTING_TABLE *prt + ); + + +static +ACPI_STATUS __init +acpi_cf_convert_prt_to_vectors ( + void *prts, + struct pci_vector_struct **vectors, + int *num_pci_vectors + ); + + +void __init +acpi_cf_cleanup ( void ); + diff -urN linux-2.4.0-test12/drivers/acpi/cmbatt.c linux-2.4.0-test12-lia/drivers/acpi/cmbatt.c --- linux-2.4.0-test12/drivers/acpi/cmbatt.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/cmbatt.c Wed Nov 15 16:25:04 2000 @@ -0,0 +1,141 @@ +/* + * cmbatt.c - Control Method Battery driver + * + * Copyright (C) 2000 Andrew Grover + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +#define _COMPONENT OS_DEPENDENT + MODULE_NAME ("cmbatt") + +#define ACPI_CMBATT_HID "PNP0C0A" + +#define ACPI_BATT_PRESENT 0x10 + +#define ACPI_MAX_BATTERIES 0x8 + +struct cmbatt_context +{ + char UID[9]; + u8 is_present; + ACPI_HANDLE handle; +}; + +struct cmbatt_status +{ + u32 state; + u32 present_rate; + u32 remaining_capacity; + u32 present_voltage; +}; + +static u32 batt_count = 0; + +static struct cmbatt_context batt_list[ACPI_MAX_BATTERIES]; + +/* + * We found a device with the correct HID + */ +static ACPI_STATUS +acpi_found_cmbatt(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +{ + ACPI_DEVICE_INFO info; + + if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { + printk(KERN_ERR "Could not get battery object info\n"); + return (AE_OK); + } + + if (info.valid & ACPI_VALID_UID) { + strncpy(batt_list[batt_count].UID, info.unique_id, 9); + } + else if (batt_count > 1) { + printk(KERN_WARNING "ACPI: No UID but more than 1 battery\n"); + } + + if ((info.valid & ACPI_VALID_STA) && + (info.current_status & ACPI_BATT_PRESENT)) { + + ACPI_BUFFER buf; + + printk("ACPI: Found a battery\n"); + batt_list[batt_count].is_present = TRUE; + + buf.length = 0; + buf.pointer = NULL; + + /* determine buffer length needed */ + if (acpi_evaluate_object(handle, "_BST", NULL, &buf) != AE_BUFFER_OVERFLOW) + return AE_OK; + + buf.pointer = kmalloc(buf.length, GFP_KERNEL); + + if (!buf.pointer) + return AE_NO_MEMORY; + + /* get the data */ + if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_BST", NULL, &buf))) { + printk(KERN_ERR "Could not get battery status\n"); + kfree (buf.pointer); + return AE_OK; + } + + kfree(buf.pointer); + + /* TODO: parse the battery data */ + /* TODO: add proc interface */ + } + else { + printk("ACPI: Found an empty battery socket\n"); + batt_list[batt_count].is_present = FALSE; + } + + batt_list[batt_count].handle = handle; + + batt_count++; + + return (AE_OK); +} + +int +acpi_cmbatt_init(void) +{ + acpi_get_devices(ACPI_CMBATT_HID, + acpi_found_cmbatt, + NULL, + NULL); + + return 0; +} + +int +acpi_cmbatt_terminate(void) +{ + /* TODO */ + /* walk list of batteries */ + /* free their context and release resources */ + return 0; +} diff -urN linux-2.4.0-test12/drivers/acpi/common/Makefile linux-2.4.0-test12-lia/drivers/acpi/common/Makefile --- linux-2.4.0-test12/drivers/acpi/common/Makefile Fri Sep 15 18:21:43 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/common/cmalloc.c linux-2.4.0-test12-lia/drivers/acpi/common/cmalloc.c --- linux-2.4.0-test12/drivers/acpi/common/cmalloc.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmalloc.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmalloc - local memory allocation routines - * $Revision: 73 $ + * $Revision: 78 $ * *****************************************************************************/ @@ -57,11 +57,15 @@ u32 line) { void *address = NULL; + DEBUG_ONLY_MEMBERS (\ + ACPI_STATUS status) + /* Check for an inadvertent size of zero bytes */ if (!size) { - REPORT_ERROR ("Cm_allocate: Attempt to allocate zero bytes"); + _REPORT_ERROR (module, line, component, + ("Cm_allocate: Attempt to allocate zero bytes\n")); size = 1; } @@ -70,7 +74,7 @@ /* Report allocation error */ _REPORT_ERROR (module, line, component, - "Cm_allocate: Memory allocation failure"); + ("Cm_allocate: Could not allocate size 0x%x\n", size)); return (NULL); } @@ -103,11 +107,15 @@ u32 line) { void *address = NULL; + DEBUG_ONLY_MEMBERS (\ + ACPI_STATUS status) + /* Check for an inadvertent size of zero bytes */ if (!size) { - REPORT_ERROR ("Cm_callocate: Attempt to allocate zero bytes"); + _REPORT_ERROR (module, line, component, + ("Cm_callocate: Attempt to allocate zero bytes\n")); return (NULL); } @@ -118,8 +126,7 @@ /* Report allocation error */ _REPORT_ERROR (module, line, component, - "Cm_callocate: Memory allocation failure"); - + ("Cm_callocate: Could not allocate size 0x%x\n", size)); return (NULL); } @@ -153,7 +160,7 @@ if (NULL == address) { _REPORT_ERROR (module, line, component, - "_Cm_free: Trying to delete a NULL address."); + ("_Cm_free: Trying to delete a NULL address\n")); return; } diff -urN linux-2.4.0-test12/drivers/acpi/common/cmclib.c linux-2.4.0-test12-lia/drivers/acpi/common/cmclib.c --- linux-2.4.0-test12/drivers/acpi/common/cmclib.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmclib.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmclib - Local implementation of C library functions - * $Revision: 24 $ + * $Revision: 28 $ * *****************************************************************************/ @@ -41,10 +41,6 @@ MODULE_NAME ("cmclib") -#ifdef _MSC_VER /* disable some level-4 warnings for VC++ */ -#pragma warning(disable:4706) /* warning C4706: assignment within conditional expression */ -#endif - #ifndef ACPI_USE_SYSTEM_CLIBRARY /******************************************************************************* @@ -371,146 +367,146 @@ #define POSITIVE 0 -#define _XA 0x00 /* extra alphabetic - not supported */ -#define _XS 0x40 /* extra space */ -#define _BB 0x00 /* BEL, BS, etc. - not supported */ -#define _CN 0x20 /* CR, FF, HT, NL, VT */ -#define _DI 0x04 /* '0'-'9' */ -#define _LO 0x02 /* 'a'-'z' */ -#define _PU 0x10 /* punctuation */ -#define _SP 0x08 /* space */ -#define _UP 0x01 /* 'A'-'Z' */ -#define _XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */ - -const u8 _ctype[257] = { - _CN, /* 0x0 0. */ - _CN, /* 0x1 1. */ - _CN, /* 0x2 2. */ - _CN, /* 0x3 3. */ - _CN, /* 0x4 4. */ - _CN, /* 0x5 5. */ - _CN, /* 0x6 6. */ - _CN, /* 0x7 7. */ - _CN, /* 0x8 8. */ - _CN|_SP, /* 0x9 9. */ - _CN|_SP, /* 0xA 10. */ - _CN|_SP, /* 0xB 11. */ - _CN|_SP, /* 0xC 12. */ - _CN|_SP, /* 0xD 13. */ - _CN, /* 0xE 14. */ - _CN, /* 0xF 15. */ - _CN, /* 0x10 16. */ - _CN, /* 0x11 17. */ - _CN, /* 0x12 18. */ - _CN, /* 0x13 19. */ - _CN, /* 0x14 20. */ - _CN, /* 0x15 21. */ - _CN, /* 0x16 22. */ - _CN, /* 0x17 23. */ - _CN, /* 0x18 24. */ - _CN, /* 0x19 25. */ - _CN, /* 0x1A 26. */ - _CN, /* 0x1B 27. */ - _CN, /* 0x1C 28. */ - _CN, /* 0x1D 29. */ - _CN, /* 0x1E 30. */ - _CN, /* 0x1F 31. */ - _XS|_SP, /* 0x20 32. ' ' */ - _PU, /* 0x21 33. '!' */ - _PU, /* 0x22 34. '"' */ - _PU, /* 0x23 35. '#' */ - _PU, /* 0x24 36. '$' */ - _PU, /* 0x25 37. '%' */ - _PU, /* 0x26 38. '&' */ - _PU, /* 0x27 39. ''' */ - _PU, /* 0x28 40. '(' */ - _PU, /* 0x29 41. ')' */ - _PU, /* 0x2A 42. '*' */ - _PU, /* 0x2B 43. '+' */ - _PU, /* 0x2C 44. ',' */ - _PU, /* 0x2D 45. '-' */ - _PU, /* 0x2E 46. '.' */ - _PU, /* 0x2F 47. '/' */ - _XD|_DI, /* 0x30 48. '0' */ - _XD|_DI, /* 0x31 49. '1' */ - _XD|_DI, /* 0x32 50. '2' */ - _XD|_DI, /* 0x33 51. '3' */ - _XD|_DI, /* 0x34 52. '4' */ - _XD|_DI, /* 0x35 53. '5' */ - _XD|_DI, /* 0x36 54. '6' */ - _XD|_DI, /* 0x37 55. '7' */ - _XD|_DI, /* 0x38 56. '8' */ - _XD|_DI, /* 0x39 57. '9' */ - _PU, /* 0x3A 58. ':' */ - _PU, /* 0x3B 59. ';' */ - _PU, /* 0x3C 60. '<' */ - _PU, /* 0x3D 61. '=' */ - _PU, /* 0x3E 62. '>' */ - _PU, /* 0x3F 63. '?' */ - _PU, /* 0x40 64. '@' */ - _XD|_UP, /* 0x41 65. 'A' */ - _XD|_UP, /* 0x42 66. 'B' */ - _XD|_UP, /* 0x43 67. 'C' */ - _XD|_UP, /* 0x44 68. 'D' */ - _XD|_UP, /* 0x45 69. 'E' */ - _XD|_UP, /* 0x46 70. 'F' */ - _UP, /* 0x47 71. 'G' */ - _UP, /* 0x48 72. 'H' */ - _UP, /* 0x49 73. 'I' */ - _UP, /* 0x4A 74. 'J' */ - _UP, /* 0x4B 75. 'K' */ - _UP, /* 0x4C 76. 'L' */ - _UP, /* 0x4D 77. 'M' */ - _UP, /* 0x4E 78. 'N' */ - _UP, /* 0x4F 79. 'O' */ - _UP, /* 0x50 80. 'P' */ - _UP, /* 0x51 81. 'Q' */ - _UP, /* 0x52 82. 'R' */ - _UP, /* 0x53 83. 'S' */ - _UP, /* 0x54 84. 'T' */ - _UP, /* 0x55 85. 'U' */ - _UP, /* 0x56 86. 'V' */ - _UP, /* 0x57 87. 'W' */ - _UP, /* 0x58 88. 'X' */ - _UP, /* 0x59 89. 'Y' */ - _UP, /* 0x5A 90. 'Z' */ - _PU, /* 0x5B 91. '[' */ - _PU, /* 0x5C 92. '\' */ - _PU, /* 0x5D 93. ']' */ - _PU, /* 0x5E 94. '^' */ - _PU, /* 0x5F 95. '_' */ - _PU, /* 0x60 96. '`' */ - _XD|_LO, /* 0x61 97. 'a' */ - _XD|_LO, /* 0x62 98. 'b' */ - _XD|_LO, /* 0x63 99. 'c' */ - _XD|_LO, /* 0x64 100. 'd' */ - _XD|_LO, /* 0x65 101. 'e' */ - _XD|_LO, /* 0x66 102. 'f' */ - _LO, /* 0x67 103. 'g' */ - _LO, /* 0x68 104. 'h' */ - _LO, /* 0x69 105. 'i' */ - _LO, /* 0x6A 106. 'j' */ - _LO, /* 0x6B 107. 'k' */ - _LO, /* 0x6C 108. 'l' */ - _LO, /* 0x6D 109. 'm' */ - _LO, /* 0x6E 110. 'n' */ - _LO, /* 0x6F 111. 'o' */ - _LO, /* 0x70 112. 'p' */ - _LO, /* 0x71 113. 'q' */ - _LO, /* 0x72 114. 'r' */ - _LO, /* 0x73 115. 's' */ - _LO, /* 0x74 116. 't' */ - _LO, /* 0x75 117. 'u' */ - _LO, /* 0x76 118. 'v' */ - _LO, /* 0x77 119. 'w' */ - _LO, /* 0x78 120. 'x' */ - _LO, /* 0x79 121. 'y' */ - _LO, /* 0x7A 122. 'z' */ - _PU, /* 0x7B 123. '{' */ - _PU, /* 0x7C 124. '|' */ - _PU, /* 0x7D 125. '}' */ - _PU, /* 0x7E 126. '~' */ - _CN, /* 0x7F 127. */ +#define _ACPI_XA 0x00 /* extra alphabetic - not supported */ +#define _ACPI_XS 0x40 /* extra space */ +#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */ +#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */ +#define _ACPI_DI 0x04 /* '0'-'9' */ +#define _ACPI_LO 0x02 /* 'a'-'z' */ +#define _ACPI_PU 0x10 /* punctuation */ +#define _ACPI_SP 0x08 /* space */ +#define _ACPI_UP 0x01 /* 'A'-'Z' */ +#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */ + +static const u8 _acpi_ctype[257] = { + _ACPI_CN, /* 0x0 0. */ + _ACPI_CN, /* 0x1 1. */ + _ACPI_CN, /* 0x2 2. */ + _ACPI_CN, /* 0x3 3. */ + _ACPI_CN, /* 0x4 4. */ + _ACPI_CN, /* 0x5 5. */ + _ACPI_CN, /* 0x6 6. */ + _ACPI_CN, /* 0x7 7. */ + _ACPI_CN, /* 0x8 8. */ + _ACPI_CN|_ACPI_SP, /* 0x9 9. */ + _ACPI_CN|_ACPI_SP, /* 0xA 10. */ + _ACPI_CN|_ACPI_SP, /* 0xB 11. */ + _ACPI_CN|_ACPI_SP, /* 0xC 12. */ + _ACPI_CN|_ACPI_SP, /* 0xD 13. */ + _ACPI_CN, /* 0xE 14. */ + _ACPI_CN, /* 0xF 15. */ + _ACPI_CN, /* 0x10 16. */ + _ACPI_CN, /* 0x11 17. */ + _ACPI_CN, /* 0x12 18. */ + _ACPI_CN, /* 0x13 19. */ + _ACPI_CN, /* 0x14 20. */ + _ACPI_CN, /* 0x15 21. */ + _ACPI_CN, /* 0x16 22. */ + _ACPI_CN, /* 0x17 23. */ + _ACPI_CN, /* 0x18 24. */ + _ACPI_CN, /* 0x19 25. */ + _ACPI_CN, /* 0x1A 26. */ + _ACPI_CN, /* 0x1B 27. */ + _ACPI_CN, /* 0x1C 28. */ + _ACPI_CN, /* 0x1D 29. */ + _ACPI_CN, /* 0x1E 30. */ + _ACPI_CN, /* 0x1F 31. */ + _ACPI_XS|_ACPI_SP, /* 0x20 32. ' ' */ + _ACPI_PU, /* 0x21 33. '!' */ + _ACPI_PU, /* 0x22 34. '"' */ + _ACPI_PU, /* 0x23 35. '#' */ + _ACPI_PU, /* 0x24 36. '$' */ + _ACPI_PU, /* 0x25 37. '%' */ + _ACPI_PU, /* 0x26 38. '&' */ + _ACPI_PU, /* 0x27 39. ''' */ + _ACPI_PU, /* 0x28 40. '(' */ + _ACPI_PU, /* 0x29 41. ')' */ + _ACPI_PU, /* 0x2A 42. '*' */ + _ACPI_PU, /* 0x2B 43. '+' */ + _ACPI_PU, /* 0x2C 44. ',' */ + _ACPI_PU, /* 0x2D 45. '-' */ + _ACPI_PU, /* 0x2E 46. '.' */ + _ACPI_PU, /* 0x2F 47. '/' */ + _ACPI_XD|_ACPI_DI, /* 0x30 48. '0' */ + _ACPI_XD|_ACPI_DI, /* 0x31 49. '1' */ + _ACPI_XD|_ACPI_DI, /* 0x32 50. '2' */ + _ACPI_XD|_ACPI_DI, /* 0x33 51. '3' */ + _ACPI_XD|_ACPI_DI, /* 0x34 52. '4' */ + _ACPI_XD|_ACPI_DI, /* 0x35 53. '5' */ + _ACPI_XD|_ACPI_DI, /* 0x36 54. '6' */ + _ACPI_XD|_ACPI_DI, /* 0x37 55. '7' */ + _ACPI_XD|_ACPI_DI, /* 0x38 56. '8' */ + _ACPI_XD|_ACPI_DI, /* 0x39 57. '9' */ + _ACPI_PU, /* 0x3A 58. ':' */ + _ACPI_PU, /* 0x3B 59. ';' */ + _ACPI_PU, /* 0x3C 60. '<' */ + _ACPI_PU, /* 0x3D 61. '=' */ + _ACPI_PU, /* 0x3E 62. '>' */ + _ACPI_PU, /* 0x3F 63. '?' */ + _ACPI_PU, /* 0x40 64. '@' */ + _ACPI_XD|_ACPI_UP, /* 0x41 65. 'A' */ + _ACPI_XD|_ACPI_UP, /* 0x42 66. 'B' */ + _ACPI_XD|_ACPI_UP, /* 0x43 67. 'C' */ + _ACPI_XD|_ACPI_UP, /* 0x44 68. 'D' */ + _ACPI_XD|_ACPI_UP, /* 0x45 69. 'E' */ + _ACPI_XD|_ACPI_UP, /* 0x46 70. 'F' */ + _ACPI_UP, /* 0x47 71. 'G' */ + _ACPI_UP, /* 0x48 72. 'H' */ + _ACPI_UP, /* 0x49 73. 'I' */ + _ACPI_UP, /* 0x4A 74. 'J' */ + _ACPI_UP, /* 0x4B 75. 'K' */ + _ACPI_UP, /* 0x4C 76. 'L' */ + _ACPI_UP, /* 0x4D 77. 'M' */ + _ACPI_UP, /* 0x4E 78. 'N' */ + _ACPI_UP, /* 0x4F 79. 'O' */ + _ACPI_UP, /* 0x50 80. 'P' */ + _ACPI_UP, /* 0x51 81. 'Q' */ + _ACPI_UP, /* 0x52 82. 'R' */ + _ACPI_UP, /* 0x53 83. 'S' */ + _ACPI_UP, /* 0x54 84. 'T' */ + _ACPI_UP, /* 0x55 85. 'U' */ + _ACPI_UP, /* 0x56 86. 'V' */ + _ACPI_UP, /* 0x57 87. 'W' */ + _ACPI_UP, /* 0x58 88. 'X' */ + _ACPI_UP, /* 0x59 89. 'Y' */ + _ACPI_UP, /* 0x5A 90. 'Z' */ + _ACPI_PU, /* 0x5B 91. '[' */ + _ACPI_PU, /* 0x5C 92. '\' */ + _ACPI_PU, /* 0x5D 93. ']' */ + _ACPI_PU, /* 0x5E 94. '^' */ + _ACPI_PU, /* 0x5F 95. '_' */ + _ACPI_PU, /* 0x60 96. '`' */ + _ACPI_XD|_ACPI_LO, /* 0x61 97. 'a' */ + _ACPI_XD|_ACPI_LO, /* 0x62 98. 'b' */ + _ACPI_XD|_ACPI_LO, /* 0x63 99. 'c' */ + _ACPI_XD|_ACPI_LO, /* 0x64 100. 'd' */ + _ACPI_XD|_ACPI_LO, /* 0x65 101. 'e' */ + _ACPI_XD|_ACPI_LO, /* 0x66 102. 'f' */ + _ACPI_LO, /* 0x67 103. 'g' */ + _ACPI_LO, /* 0x68 104. 'h' */ + _ACPI_LO, /* 0x69 105. 'i' */ + _ACPI_LO, /* 0x6A 106. 'j' */ + _ACPI_LO, /* 0x6B 107. 'k' */ + _ACPI_LO, /* 0x6C 108. 'l' */ + _ACPI_LO, /* 0x6D 109. 'm' */ + _ACPI_LO, /* 0x6E 110. 'n' */ + _ACPI_LO, /* 0x6F 111. 'o' */ + _ACPI_LO, /* 0x70 112. 'p' */ + _ACPI_LO, /* 0x71 113. 'q' */ + _ACPI_LO, /* 0x72 114. 'r' */ + _ACPI_LO, /* 0x73 115. 's' */ + _ACPI_LO, /* 0x74 116. 't' */ + _ACPI_LO, /* 0x75 117. 'u' */ + _ACPI_LO, /* 0x76 118. 'v' */ + _ACPI_LO, /* 0x77 119. 'w' */ + _ACPI_LO, /* 0x78 120. 'x' */ + _ACPI_LO, /* 0x79 121. 'y' */ + _ACPI_LO, /* 0x7A 122. 'z' */ + _ACPI_PU, /* 0x7B 123. '{' */ + _ACPI_PU, /* 0x7C 124. '|' */ + _ACPI_PU, /* 0x7D 125. '}' */ + _ACPI_PU, /* 0x7E 126. '~' */ + _ACPI_CN, /* 0x7F 127. */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80 to 0x8F */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90 to 0x9F */ @@ -522,10 +518,10 @@ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xF0 to 0x100 */ }; -#define IS_UPPER(c) (_ctype[(unsigned char)(c)] & (_UP)) -#define IS_LOWER(c) (_ctype[(unsigned char)(c)] & (_LO)) -#define IS_DIGIT(c) (_ctype[(unsigned char)(c)] & (_DI)) -#define IS_SPACE(c) (_ctype[(unsigned char)(c)] & (_SP)) +#define IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) +#define IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) +#define IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI)) +#define IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP)) /******************************************************************************* @@ -628,7 +624,7 @@ return (NULL); } - /* Walk entire string, uppercasing the letters */ + /* Walk entire string, comparing the letters */ for (string = string1; *string2; ) { if (*string2 != *string) { diff -urN linux-2.4.0-test12/drivers/acpi/common/cmcopy.c linux-2.4.0-test12-lia/drivers/acpi/common/cmcopy.c --- linux-2.4.0-test12/drivers/acpi/common/cmcopy.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmcopy.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmcopy - Internal to external object translation utilities - * $Revision: 56 $ + * $Revision: 58 $ * *****************************************************************************/ @@ -63,7 +63,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_cm_build_external_simple_object ( ACPI_OPERAND_OBJECT *internal_obj, ACPI_OBJECT *external_obj, @@ -199,7 +199,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_cm_build_external_package_object ( ACPI_OPERAND_OBJECT *internal_obj, u8 *buffer, @@ -487,6 +487,10 @@ } +#ifdef ACPI_FUTURE_IMPLEMENTATION + +/* Code to convert packages that are parameters to control methods */ + /****************************************************************************** * * FUNCTION: Acpi_cm_build_internal_package_object @@ -506,7 +510,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_cm_build_internal_package_object ( ACPI_OPERAND_OBJECT *internal_obj, u8 *buffer, @@ -641,6 +645,8 @@ } /* while (1) */ } +#endif /* Future implementation */ + /****************************************************************************** * @@ -667,6 +673,10 @@ /* * Package objects contain other objects (which can be objects) * buildpackage does it all + * + * TBD: Package conversion must be completed and tested + * NOTE: this code converts packages as input parameters to + * control methods only. This is a very, very rare case. */ /* Status = Acpi_cm_build_internal_package_object(Internal_obj, diff -urN linux-2.4.0-test12/drivers/acpi/common/cmdelete.c linux-2.4.0-test12-lia/drivers/acpi/common/cmdelete.c --- linux-2.4.0-test12/drivers/acpi/common/cmdelete.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmdelete.c Wed Nov 15 16:25:04 2000 @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: cmdelete - object deletion and reference count utilities - * $Revision: 53 $ + * $Revision: 59 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -34,7 +34,7 @@ MODULE_NAME ("cmdelete") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_delete_internal_obj * @@ -52,6 +52,7 @@ ACPI_OPERAND_OBJECT *object) { void *obj_pointer = NULL; + ACPI_OPERAND_OBJECT *handler_desc; if (!object) { @@ -120,6 +121,36 @@ break; + case ACPI_TYPE_REGION: + + + if (object->region.extra) { + /* + * Free the Region_context if and only if the handler is one of the + * default handlers -- and therefore, we created the context object + * locally, it was not created by an external caller. + */ + handler_desc = object->region.addr_handler; + if ((handler_desc) && + (handler_desc->addr_handler.hflags == ADDR_HANDLER_DEFAULT_INSTALLED)) + { + obj_pointer = object->region.extra->extra.region_context; + } + + /* Now we can free the Extra object */ + + acpi_cm_delete_object_desc (object->region.extra); + } + break; + + + case ACPI_TYPE_FIELD_UNIT: + + if (object->field_unit.extra) { + acpi_cm_delete_object_desc (object->field_unit.extra); + } + break; + default: break; } @@ -148,7 +179,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_delete_internal_object_list * @@ -197,12 +228,11 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_update_ref_count * * PARAMETERS: *Object - Object whose ref count is to be updated - * Count - Current ref count * Action - What to do * * RETURN: New ref count @@ -211,7 +241,7 @@ * ******************************************************************************/ -void +static void acpi_cm_update_ref_count ( ACPI_OPERAND_OBJECT *object, u32 action) @@ -287,7 +317,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_update_object_reference * @@ -397,9 +427,8 @@ * these are simply ignored */ - status = - acpi_cm_create_update_state_and_push (object->package.elements[i], - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->package.elements[i], action, &state_list); if (ACPI_FAILURE (status)) { return (status); } @@ -409,9 +438,9 @@ case ACPI_TYPE_FIELD_UNIT: - status = - acpi_cm_create_update_state_and_push (object->field_unit.container, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->field_unit.container, action, &state_list); + if (ACPI_FAILURE (status)) { return (status); } @@ -420,9 +449,8 @@ case INTERNAL_TYPE_DEF_FIELD: - status = - acpi_cm_create_update_state_and_push (object->field.container, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->field.container, action, &state_list); if (ACPI_FAILURE (status)) { return (status); } @@ -431,16 +459,14 @@ case INTERNAL_TYPE_BANK_FIELD: - status = - acpi_cm_create_update_state_and_push (object->bank_field.bank_select, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->bank_field.bank_select, action, &state_list); if (ACPI_FAILURE (status)) { return (status); } - status = - acpi_cm_create_update_state_and_push (object->bank_field.container, - action, &state_list); + status = acpi_cm_create_update_state_and_push ( + object->bank_field.container, action, &state_list); if (ACPI_FAILURE (status)) { return (status); } @@ -449,8 +475,6 @@ case ACPI_TYPE_REGION: - acpi_cm_update_ref_count (object->region.method, action); - /* TBD: [Investigate] Acpi_cm_update_ref_count (Object->Region.Addr_handler, Action); */ @@ -490,7 +514,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_add_reference * @@ -517,7 +541,6 @@ return; } - /* * We have a valid ACPI internal object, now increment the reference count */ @@ -528,7 +551,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_remove_reference * @@ -562,15 +585,6 @@ acpi_cm_update_object_reference (object, REF_DECREMENT); - /* - * If the reference count has reached zero, - * delete the object and all sub-objects contained within it - */ -/* - if (Object->Common.Reference_count == 0) { - Acpi_cm_delete_internal_obj (Object); - } -*/ return; } diff -urN linux-2.4.0-test12/drivers/acpi/common/cmeval.c linux-2.4.0-test12-lia/drivers/acpi/common/cmeval.c --- linux-2.4.0-test12/drivers/acpi/common/cmeval.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmeval.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmeval - Object evaluation - * $Revision: 14 $ + * $Revision: 18 $ * *****************************************************************************/ @@ -37,7 +37,8 @@ * * FUNCTION: Acpi_cm_evaluate_numeric_object * - * PARAMETERS: Device_node - Node for the device + * PARAMETERS: *Object_name - Object name to be evaluated + * Device_node - Node for the device * *Address - Where the value is returned * * RETURN: Status @@ -53,7 +54,7 @@ acpi_cm_evaluate_numeric_object ( NATIVE_CHAR *object_name, ACPI_NAMESPACE_NODE *device_node, - u32 *address) + ACPI_INTEGER *address) { ACPI_OPERAND_OBJECT *obj_desc; ACPI_STATUS status; @@ -151,15 +152,13 @@ if (obj_desc->common.type == ACPI_TYPE_NUMBER) { /* Convert the Numeric HID to string */ - acpi_aml_eisa_id_to_string (obj_desc->number.value, hid->data.buffer); - hid->type = STRING_DEVICE_ID; + acpi_aml_eisa_id_to_string ((u32) obj_desc->number.value, hid->buffer); } else { /* Copy the String HID from the returned object */ - hid->data.string_ptr = obj_desc->string.pointer; - hid->type = STRING_PTR_DEVICE_ID; + STRNCPY(hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer)); } } @@ -226,16 +225,15 @@ else { if (obj_desc->common.type == ACPI_TYPE_NUMBER) { - /* Convert the Numeric HID to string */ + /* Convert the Numeric UID to string */ - uid->data.number = obj_desc->number.value; + acpi_aml_unsigned_integer_to_string (obj_desc->number.value, uid->buffer); } else { - /* Copy the String HID from the returned object */ + /* Copy the String UID from the returned object */ - uid->data.string_ptr = obj_desc->string.pointer; - uid->type = STRING_PTR_DEVICE_ID; + STRNCPY(uid->buffer, obj_desc->string.pointer, sizeof(uid->buffer)); } } @@ -276,35 +274,35 @@ status = acpi_ns_evaluate_relative (device_node, METHOD_NAME__STA, NULL, &obj_desc); - if (ACPI_FAILURE (status)) { - - - return (status); + if (AE_NOT_FOUND == status) { + *flags = 0x0F; + status = AE_OK; } - /* Did we get a return object? */ - - if (!obj_desc) { - return (AE_TYPE); - } + else /* success */ { + /* Did we get a return object? */ - /* Is the return object of the correct type? */ + if (!obj_desc) { + return (AE_TYPE); + } - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { - status = AE_TYPE; - } + /* Is the return object of the correct type? */ - else { - /* Extract the status flags */ + if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + status = AE_TYPE; + } - *flags = obj_desc->number.value; - } + else { + /* Extract the status flags */ + *flags = (u32) obj_desc->number.value; + } - /* On exit, we must delete the return object */ + /* On exit, we must delete the return object */ - acpi_cm_remove_reference (obj_desc); + acpi_cm_remove_reference (obj_desc); + } return (status); } diff -urN linux-2.4.0-test12/drivers/acpi/common/cmglobal.c linux-2.4.0-test12-lia/drivers/acpi/common/cmglobal.c --- linux-2.4.0-test12/drivers/acpi/common/cmglobal.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmglobal.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmglobal - Global variables for the ACPI subsystem - * $Revision: 99 $ + * $Revision: 110 $ * *****************************************************************************/ @@ -52,7 +52,7 @@ /* Debug switch - layer (component) mask */ -u32 acpi_dbg_layer = ALL_COMPONENTS; +u32 acpi_dbg_layer = COMPONENT_DEFAULT; u32 acpi_gbl_nesting_level = 0; @@ -70,6 +70,9 @@ u8 acpi_gbl_shutdown = TRUE; +u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; + + /****************************************************************************** * * Namespace globals @@ -134,17 +137,19 @@ NSP_NORMAL, /* 21 Alias */ NSP_NORMAL, /* 22 Notify */ NSP_NORMAL, /* 23 Address Handler */ - NSP_NORMAL, /* 24 Def_field_defn */ - NSP_NORMAL, /* 25 Bank_field_defn */ - NSP_NORMAL, /* 26 Index_field_defn */ - NSP_NORMAL, /* 27 If */ - NSP_NORMAL, /* 28 Else */ - NSP_NORMAL, /* 29 While */ - NSP_NEWSCOPE, /* 30 Scope */ - NSP_LOCAL, /* 31 Def_any */ - NSP_NORMAL, /* 32 Method Arg */ - NSP_NORMAL, /* 33 Method Local */ - NSP_NORMAL /* 34 Invalid */ + NSP_NEWSCOPE | NSP_LOCAL, /* 24 Resource */ + NSP_NORMAL, /* 25 Def_field_defn */ + NSP_NORMAL, /* 26 Bank_field_defn */ + NSP_NORMAL, /* 27 Index_field_defn */ + NSP_NORMAL, /* 28 If */ + NSP_NORMAL, /* 29 Else */ + NSP_NORMAL, /* 30 While */ + NSP_NEWSCOPE, /* 31 Scope */ + NSP_LOCAL, /* 32 Def_any */ + NSP_NORMAL, /* 33 Method Arg */ + NSP_NORMAL, /* 34 Method Local */ + NSP_NORMAL, /* 35 Extra */ + NSP_NORMAL /* 36 Invalid */ }; @@ -152,6 +157,10 @@ * * Table globals * + * NOTE: This table includes ONLY the ACPI tables that the subsystem consumes. + * it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables + * that are not used by the subsystem are simply ignored. + * ******************************************************************************/ @@ -160,22 +169,17 @@ ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] = { - /* Name, Signature, Signature size, How many allowed?, Supported? Global typed pointer */ + /*********** Name, Signature, Signature size, How many allowed?, Supported? Global typed pointer */ - /* RSDP 0 */ {"RSDP", RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, - /* APIC 1 */ {APIC_SIG, APIC_SIG, sizeof (APIC_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_APIC}, - /* DSDT 2 */ {DSDT_SIG, DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_DSDT}, - /* FACP 3 */ {FACP_SIG, FACP_SIG, sizeof (FACP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACP}, - /* FACS 4 */ {FACS_SIG, FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACS}, - /* PSDT 5 */ {PSDT_SIG, PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, - /* RSDT 6 */ {RSDT_SIG, RSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, - /* SSDT 7 */ {SSDT_SIG, SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, - /* SBST 8 */ {SBST_SIG, SBST_SIG, sizeof (SBST_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_SBST}, - /* BOOT 9 */ {BOOT_SIG, BOOT_SIG, sizeof (BOOT_SIG)-1, ACPI_TABLE_SINGLE, AE_SUPPORT, NULL} + /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, + /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_DSDT}, + /* FADT 2 */ {FADT_SIG, FADT_SIG, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FADT}, + /* FACS 3 */ {FACS_SIG, FACS_SIG, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, (void **) &acpi_gbl_FACS}, + /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, + /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, + /* XSDT 6 */ {XSDT_SIG, XSDT_SIG, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE, AE_OK, NULL}, }; -ACPI_INIT_DATA acpi_gbl_acpi_init_data; - /***************************************************************************** * @@ -337,22 +341,15 @@ ***************************************************************************/ void -acpi_cm_init_globals (ACPI_INIT_DATA *init_data) +acpi_cm_init_globals ( + void) { u32 i; - if (init_data) { - MEMCPY (&acpi_gbl_acpi_init_data, init_data, sizeof (ACPI_INIT_DATA)); - } - - else { - MEMSET (&acpi_gbl_acpi_init_data, 0, sizeof (ACPI_INIT_DATA)); - } - /* ACPI table structure */ - for (i = 0; i < ACPI_TABLE_MAX; i++) { + for (i = 0; i < NUM_ACPI_TABLES; i++) { acpi_gbl_acpi_tables[i].prev = &acpi_gbl_acpi_tables[i]; acpi_gbl_acpi_tables[i].next = &acpi_gbl_acpi_tables[i]; acpi_gbl_acpi_tables[i].pointer = NULL; @@ -364,7 +361,7 @@ /* Address Space handler array */ - for (i = 0; i < ACPI_MAX_ADDRESS_SPACE; i++) { + for (i = 0; i < ACPI_NUM_ADDRESS_SPACES; i++) { acpi_gbl_address_spaces[i].handler = NULL; acpi_gbl_address_spaces[i].context = NULL; } @@ -385,12 +382,10 @@ /* Global "typed" ACPI table pointers */ acpi_gbl_RSDP = NULL; - acpi_gbl_RSDT = NULL; + acpi_gbl_XSDT = NULL; acpi_gbl_FACS = NULL; - acpi_gbl_FACP = NULL; - acpi_gbl_APIC = NULL; + acpi_gbl_FADT = NULL; acpi_gbl_DSDT = NULL; - acpi_gbl_SBST = NULL; /* Global Lock support */ @@ -404,7 +399,6 @@ acpi_gbl_startup_flags = 0; acpi_gbl_global_lock_set = FALSE; acpi_gbl_rsdp_original_location = 0; - acpi_gbl_when_to_parse_methods = METHOD_PARSE_CONFIGURATION; acpi_gbl_cm_single_step = FALSE; acpi_gbl_db_terminate_threads = FALSE; acpi_gbl_shutdown = FALSE; @@ -441,15 +435,6 @@ acpi_gbl_walk_state_cache_depth = 0; acpi_gbl_walk_state_cache_requests = 0; acpi_gbl_walk_state_cache_hits = 0; - - /* Interpreter */ - - acpi_gbl_buf_seq = 0; - acpi_gbl_node_err = FALSE; - - /* Parser */ - - acpi_gbl_parsed_namespace_root = NULL; /* Hardware oriented */ diff -urN linux-2.4.0-test12/drivers/acpi/common/cminit.c linux-2.4.0-test12-lia/drivers/acpi/common/cminit.c --- linux-2.4.0-test12/drivers/acpi/common/cminit.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cminit.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cminit - Common ACPI subsystem initialization - * $Revision: 79 $ + * $Revision: 88 $ * *****************************************************************************/ @@ -37,231 +37,111 @@ /******************************************************************************* * - * FUNCTION: Acpi_cm_facp_register_error + * FUNCTION: Acpi_cm_fadt_register_error * * PARAMETERS: *Register_name - Pointer to string identifying register * Value - Actual register contents value * Acpi_test_spec_section - TDS section containing assertion * Acpi_assertion - Assertion number being tested * - * RETURN: none + * RETURN: AE_BAD_VALUE * * DESCRIPTION: Display failure message and link failure to TDS assertion * ******************************************************************************/ -void -acpi_cm_facp_register_error ( +static ACPI_STATUS +acpi_cm_fadt_register_error ( NATIVE_CHAR *register_name, - u32 value) + UINT64 value) { - REPORT_ERROR ("Invalid FACP register value"); + REPORT_ERROR ( + ("Invalid FADT register value, %s = 0x%X (FADT=0x%X)\n", + register_name, value, acpi_gbl_FADT)); + + return (AE_BAD_VALUE); } /****************************************************************************** * - * FUNCTION: Acpi_cm_hardware_initialize + * FUNCTION: Acpi_cm_validate_fadt * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Initialize and validate various ACPI registers + * DESCRIPTION: Validate various ACPI registers in the FADT * ******************************************************************************/ ACPI_STATUS -acpi_cm_hardware_initialize (void) +acpi_cm_validate_fadt ( + void) { - ACPI_STATUS status = AE_OK; - u32 index; + ACPI_STATUS status = AE_OK; - /* Are we running on the actual hardware */ + /* + * Verify Fixed ACPI Description Table fields, + * but don't abort on any problems, just display error + */ - if (!acpi_gbl_acpi_hardware_present) { - /* No, just return */ - - return (AE_OK); + if (acpi_gbl_FADT->pm1_evt_len < 4) { + status = acpi_cm_fadt_register_error ("PM1_EVT_LEN", + (u32) acpi_gbl_FADT->pm1_evt_len); } - /* We must have the ACPI tables by the time we get here */ - - if (!acpi_gbl_FACP) { - acpi_gbl_restore_acpi_chipset = FALSE; - - return (AE_NO_ACPI_TABLES); + if (!acpi_gbl_FADT->pm1_cnt_len) { + status = acpi_cm_fadt_register_error ("PM1_CNT_LEN", + (u32) acpi_gbl_FADT->pm1_cnt_len); } - /* Must support *some* mode! */ -/* - if (!(System_flags & SYS_MODES_MASK)) { - Restore_acpi_chipset = FALSE; - - return (AE_ERROR); + if (!acpi_gbl_FADT->Xpm1a_evt_blk.address) { + status = acpi_cm_fadt_register_error ("PM1a_EVT_BLK", + acpi_gbl_FADT->Xpm1a_evt_blk.address); } -*/ + if (!acpi_gbl_FADT->Xpm1a_cnt_blk.address) { + status = acpi_cm_fadt_register_error ("PM1a_CNT_BLK", + acpi_gbl_FADT->Xpm1a_cnt_blk.address); + } + if (!acpi_gbl_FADT->Xpm_tmr_blk.address) { + status = acpi_cm_fadt_register_error ("PM_TMR_BLK", + acpi_gbl_FADT->Xpm_tmr_blk.address); + } - switch (acpi_gbl_system_flags & SYS_MODES_MASK) + if ((acpi_gbl_FADT->Xpm2_cnt_blk.address && + !acpi_gbl_FADT->pm2_cnt_len)) { - /* Identify current ACPI/legacy mode */ + status = acpi_cm_fadt_register_error ("PM2_CNT_LEN", + (u32) acpi_gbl_FADT->pm2_cnt_len); + } - case (SYS_MODE_ACPI): + if (acpi_gbl_FADT->pm_tm_len < 4) { + status = acpi_cm_fadt_register_error ("PM_TM_LEN", + (u32) acpi_gbl_FADT->pm_tm_len); + } - acpi_gbl_original_mode = SYS_MODE_ACPI; - break; + /* length of GPE blocks must be a multiple of 2 */ - case (SYS_MODE_LEGACY): - - acpi_gbl_original_mode = SYS_MODE_LEGACY; - break; - - - case (SYS_MODE_ACPI | SYS_MODE_LEGACY): - - if (acpi_hw_get_mode () == SYS_MODE_ACPI) { - acpi_gbl_original_mode = SYS_MODE_ACPI; - } - else { - acpi_gbl_original_mode = SYS_MODE_LEGACY; - } - - break; - } - - - if (acpi_gbl_system_flags & SYS_MODE_ACPI) { - /* Target system supports ACPI mode */ - - /* - * The purpose of this block of code is to save the initial state - * of the ACPI event enable registers. An exit function will be - * registered which will restore this state when the application - * exits. The exit function will also clear all of the ACPI event - * status bits prior to restoring the original mode. - * - * The location of the PM1a_evt_blk enable registers is defined as the - * base of PM1a_evt_blk + PM1a_evt_blk_length / 2. Since the spec further - * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset - * for the enable registers is always 2 from the base. It is hard - * coded here. If this changes in the spec, this code will need to - * be modified. The PM1b_evt_blk behaves as expected. - */ - - acpi_gbl_pm1_enable_register_save = - acpi_os_in16 ((acpi_gbl_FACP->pm1a_evt_blk + 2)); - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_gbl_pm1_enable_register_save |= - acpi_os_in16 ((acpi_gbl_FACP->pm1b_evt_blk + 2)); - } - - - /* - * The GPEs behave similarly, except that the length of the register - * block is not fixed, so the buffer must be allocated with malloc - */ - - if (acpi_gbl_FACP->gpe0blk && acpi_gbl_FACP->gpe0blk_len) { - /* GPE0 specified in FACP */ - - acpi_gbl_gpe0enable_register_save = - acpi_cm_allocate (DIV_2 (acpi_gbl_FACP->gpe0blk_len)); - if (!acpi_gbl_gpe0enable_register_save) { - return (AE_NO_MEMORY); - } - - /* Save state of GPE0 enable bits */ - - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe0blk_len); index++) { - acpi_gbl_gpe0enable_register_save[index] = - acpi_os_in8 (acpi_gbl_FACP->gpe0blk + - DIV_2 (acpi_gbl_FACP->gpe0blk_len)); - } - } - - else { - acpi_gbl_gpe0enable_register_save = NULL; - } - - if (acpi_gbl_FACP->gpe1_blk && acpi_gbl_FACP->gpe1_blk_len) { - /* GPE1 defined */ - - acpi_gbl_gpe1_enable_register_save = - acpi_cm_allocate (DIV_2 (acpi_gbl_FACP->gpe1_blk_len)); - if (!acpi_gbl_gpe1_enable_register_save) { - return (AE_NO_MEMORY); - } - - /* save state of GPE1 enable bits */ - - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe1_blk_len); index++) { - acpi_gbl_gpe1_enable_register_save[index] = - acpi_os_in8 (acpi_gbl_FACP->gpe1_blk + - DIV_2 (acpi_gbl_FACP->gpe1_blk_len)); - } - } - - else { - acpi_gbl_gpe1_enable_register_save = NULL; - } - - - /* - * Verify Fixed ACPI Description Table fields, - * but don't abort on any problems, just display error - */ - - if (acpi_gbl_FACP->pm1_evt_len < 4) { - acpi_cm_facp_register_error ("PM1_EVT_LEN", - (u32) acpi_gbl_FACP->pm1_evt_len); - } - - if (!acpi_gbl_FACP->pm1_cnt_len) { - acpi_cm_facp_register_error ("PM1_CNT_LEN", - (u32) acpi_gbl_FACP->pm1_cnt_len); - } - - if (!acpi_gbl_FACP->pm1a_evt_blk) { - acpi_cm_facp_register_error ("PM1a_EVT_BLK", acpi_gbl_FACP->pm1a_evt_blk); - } - - if (!acpi_gbl_FACP->pm1a_cnt_blk) { - acpi_cm_facp_register_error ("PM1a_CNT_BLK", acpi_gbl_FACP->pm1a_cnt_blk); - } - - if (!acpi_gbl_FACP->pm_tmr_blk) { - acpi_cm_facp_register_error ("PM_TMR_BLK", acpi_gbl_FACP->pm_tmr_blk); - } - - if (acpi_gbl_FACP->pm2_cnt_blk && !acpi_gbl_FACP->pm2_cnt_len) { - acpi_cm_facp_register_error ("PM2_CNT_LEN", - (u32) acpi_gbl_FACP->pm2_cnt_len); - } - - if (acpi_gbl_FACP->pm_tm_len < 4) { - acpi_cm_facp_register_error ("PM_TM_LEN", - (u32) acpi_gbl_FACP->pm_tm_len); - } - - /* length not multiple of 2 */ - if (acpi_gbl_FACP->gpe0blk && (acpi_gbl_FACP->gpe0blk_len & 1)) { - acpi_cm_facp_register_error ("GPE0_BLK_LEN", - (u32) acpi_gbl_FACP->gpe0blk_len); - } - - /* length not multiple of 2 */ - if (acpi_gbl_FACP->gpe1_blk && (acpi_gbl_FACP->gpe1_blk_len & 1)) { - acpi_cm_facp_register_error ("GPE1_BLK_LEN", - (u32) acpi_gbl_FACP->gpe1_blk_len); - } + if (acpi_gbl_FADT->Xgpe0blk.address && + (acpi_gbl_FADT->gpe0blk_len & 1)) + { + status = acpi_cm_fadt_register_error ("GPE0_BLK_LEN", + (u32) acpi_gbl_FADT->gpe0blk_len); } + if (acpi_gbl_FADT->Xgpe1_blk.address && + (acpi_gbl_FADT->gpe1_blk_len & 1)) + { + status = acpi_cm_fadt_register_error ("GPE1_BLK_LEN", + (u32) acpi_gbl_FADT->gpe1_blk_len); + } return (status); } @@ -354,8 +234,6 @@ #ifdef ENABLE_DEBUGGER acpi_cm_dump_current_allocations (ACPI_UINT32_MAX, NULL); #endif - - BREAKPOINT3; return (AE_OK); } diff -urN linux-2.4.0-test12/drivers/acpi/common/cmobject.c linux-2.4.0-test12-lia/drivers/acpi/common/cmobject.c --- linux-2.4.0-test12/drivers/acpi/common/cmobject.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmobject.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmobject - ACPI object create/delete/size/cache routines - * $Revision: 27 $ + * $Revision: 31 $ * *****************************************************************************/ @@ -193,7 +193,7 @@ /* Allocation failed */ _REPORT_ERROR (module_name, line_number, component_id, - "Could not allocate Object Descriptor"); + ("Could not allocate an object descriptor\n")); return (NULL); } @@ -499,10 +499,10 @@ { ACPI_OPERAND_OBJECT *this_internal_obj; - ACPI_OPERAND_OBJECT *parent_obj[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 }; + ACPI_OPERAND_OBJECT *parent_obj[MAX_PACKAGE_DEPTH]; ACPI_OPERAND_OBJECT *this_parent; u32 this_index; - u32 index[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 }; + u32 index[MAX_PACKAGE_DEPTH]; u32 length = 0; u32 object_space; u32 current_depth = 0; @@ -510,6 +510,11 @@ ACPI_STATUS status; + /* Init the package stack TBD: replace with linked list */ + + MEMSET(parent_obj, 0, MAX_PACKAGE_DEPTH); + MEMSET(index, 0, MAX_PACKAGE_DEPTH); + parent_obj[0] = internal_obj; while (1) { @@ -519,7 +524,7 @@ /* - * Check for 1) An unitialized package element. It is completely + * Check for 1) An uninitialized package element. It is completely * legal to declare a package and leave it uninitialized * 2) Any type other than a package. Packages are handled * below. diff -urN linux-2.4.0-test12/drivers/acpi/common/cmutils.c linux-2.4.0-test12-lia/drivers/acpi/common/cmutils.c --- linux-2.4.0-test12/drivers/acpi/common/cmutils.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmutils.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: cmutils - common utility procedures - * $Revision: 18 $ + * $Revision: 21 $ * ******************************************************************************/ @@ -618,6 +618,55 @@ /******************************************************************************* * + * FUNCTION: Acpi_cm_resolve_package_references + * + * PARAMETERS: Obj_desc - The Package object on which to resolve refs + * + * RETURN: Status + * + * DESCRIPTION: Walk through a package and turn internal references into values + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_resolve_package_references ( + ACPI_OPERAND_OBJECT *obj_desc) +{ + u32 count; + ACPI_OPERAND_OBJECT *sub_object; + + if (obj_desc->common.type != ACPI_TYPE_PACKAGE) { + /* Must be a package */ + + REPORT_ERROR (("Must resolve Package Refs on a Package\n")); + return(AE_ERROR); + } + + for (count = 0; count < obj_desc->package.count; count++) { + sub_object = obj_desc->package.elements[count]; + + if (sub_object->common.type == INTERNAL_TYPE_REFERENCE) { + if (sub_object->reference.op_code == AML_ZERO_OP) { + sub_object->common.type = ACPI_TYPE_NUMBER; + sub_object->number.value = 0; + } + else if (sub_object->reference.op_code == AML_ONE_OP) { + sub_object->common.type = ACPI_TYPE_NUMBER; + sub_object->number.value = 1; + } + else if (sub_object->reference.op_code == AML_ONES_OP) { + sub_object->common.type = ACPI_TYPE_NUMBER; + sub_object->number.value = ACPI_INTEGER_MAX; + } + } + } + + return(AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: _Report_error * * PARAMETERS: Module_name - Caller's module name (for error output) @@ -635,13 +684,11 @@ _report_error ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message) + u32 component_id) { - debug_print (module_name, line_number, component_id, ACPI_ERROR, - "*** Error: %s\n", message); + acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number); } @@ -664,13 +711,10 @@ _report_warning ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message) + u32 component_id) { - debug_print (module_name, line_number, component_id, ACPI_WARN, - "*** Warning: %s\n", message); - + acpi_os_printf ("%8s-%04d: *** Warning: ", module_name, line_number); } @@ -693,13 +737,10 @@ _report_info ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message) + u32 component_id) { - debug_print (module_name, line_number, component_id, ACPI_INFO, - "*** Info: %s\n", message); - + acpi_os_printf ("%8s-%04d: *** Info: ", module_name, line_number); } diff -urN linux-2.4.0-test12/drivers/acpi/common/cmxface.c linux-2.4.0-test12-lia/drivers/acpi/common/cmxface.c --- linux-2.4.0-test12/drivers/acpi/common/cmxface.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/common/cmxface.c Mon Nov 20 21:30:58 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmxface - External interfaces for "global" ACPI functions - * $Revision: 43 $ + * $Revision: 54 $ * *****************************************************************************/ @@ -39,7 +39,7 @@ /******************************************************************************* * - * FUNCTION: Acpi_initialize + * FUNCTION: Acpi_initialize_subsystem * * PARAMETERS: None * @@ -51,20 +51,22 @@ ******************************************************************************/ ACPI_STATUS -acpi_initialize (ACPI_INIT_DATA *init_data) +acpi_initialize_subsystem ( + void) { ACPI_STATUS status; /* Initialize all globals used by the subsystem */ - acpi_cm_init_globals (init_data); + acpi_cm_init_globals (); /* Initialize the OS-Dependent layer */ status = acpi_os_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR ("OSD Initialization Failure"); + REPORT_ERROR (("OSD failed to initialize, %s\n", + acpi_cm_format_exception (status))); return (status); } @@ -72,10 +74,24 @@ status = acpi_cm_mutex_initialize (); if (ACPI_FAILURE (status)) { - REPORT_ERROR ("Global Mutex Initialization Failure"); + REPORT_ERROR (("Global mutex creation failure, %s\n", + acpi_cm_format_exception (status))); return (status); } + /* + * Initialize the namespace manager and + * the root of the namespace tree + */ + + status = acpi_ns_root_initialize (); + if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Namespace initialization failure, %s\n", + acpi_cm_format_exception (status))); + return (status); + } + + /* If configured, initialize the AML debugger */ DEBUGGER_EXEC (acpi_db_initialize ()); @@ -86,6 +102,116 @@ /******************************************************************************* * + * FUNCTION: Acpi_enable_subsystem + * + * PARAMETERS: Flags - Init/enable Options + * + * RETURN: Status + * + * DESCRIPTION: Completes the subsystem initialization including hardware. + * Puts system into ACPI mode if it isn't already. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_enable_subsystem ( + u32 flags) +{ + ACPI_STATUS status = AE_OK; + + + /* Sanity check the FADT for valid values */ + + status = acpi_cm_validate_fadt (); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* + * Install the default Op_region handlers. These are + * installed unless other handlers have already been + * installed via the Install_address_space_handler interface + */ + + if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { + status = acpi_ev_install_default_address_space_handlers (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + /* + * We must initialize the hardware before we can enable ACPI. + */ + + if (!(flags & ACPI_NO_HARDWARE_INIT)) { + status = acpi_hw_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + /* + * Enable ACPI on this platform + */ + + if (!(flags & ACPI_NO_ACPI_ENABLE)) { + status = acpi_enable (); + if (ACPI_FAILURE (status)) { + //return (status); Fix for old FW. + printk("ACPI: enable fail\n"); + } + } + + /* + * Note: + * We must have the hardware AND events initialized before we can execute + * ANY control methods SAFELY. Any control method can require ACPI hardware + * support, so the hardware MUST be initialized before execution! + */ + + if (!(flags & ACPI_NO_EVENT_INIT)) { + status = acpi_ev_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + + /* + * Initialize all device objects in the namespace + * This runs the _STA, _INI, and _HID methods, and detects + * the PCI root bus(es) + */ + + if (!(flags & ACPI_NO_DEVICE_INIT)) { + status = acpi_ns_initialize_devices (flags & ACPI_NO_PCI_INIT); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + + /* + * Initialize the objects that remain unitialized. This + * runs the executable AML that is part of the declaration of Op_regions + * and Fields. + */ + + if (!(flags & ACPI_NO_OBJECT_INIT)) { + status = acpi_ns_initialize_objects (); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + + return (status); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_terminate * * PARAMETERS: None @@ -102,7 +228,7 @@ /* Terminate the AML Debuger if present */ - acpi_gbl_db_terminate_threads = TRUE; + DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); /* TBD: [Investigate] This is no longer needed?*/ /* Acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */ @@ -202,7 +328,7 @@ /* Current status of the ACPI tables, per table type */ info_ptr->num_table_types = NUM_ACPI_TABLES; - for (i = 0; i < NUM_ACPI_TABLES; i++); { + for (i = 0; i < NUM_ACPI_TABLES; i++) { info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count; } diff -urN linux-2.4.0-test12/drivers/acpi/cpu.c linux-2.4.0-test12-lia/drivers/acpi/cpu.c --- linux-2.4.0-test12/drivers/acpi/cpu.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/cpu.c Wed Nov 15 16:25:04 2000 @@ -37,55 +37,65 @@ static int acpi_c2_tested = 0; static int acpi_c3_tested = 0; static int acpi_max_c_state = 1; +static int acpi_pm_tmr_len; /* * Clear busmaster activity flag */ static inline void -acpi_clear_bm_activity(struct acpi_facp *facp) +acpi_clear_bm_activity(void) { - acpi_write_pm1_status(facp, ACPI_BM); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 0); } /* * Returns 1 if there has been busmaster activity */ static inline int -acpi_bm_activity(struct acpi_facp *facp) +acpi_bm_activity(void) { - return acpi_read_pm1_status(facp) & ACPI_BM; + return acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, BM_STS); } /* * Set system to sleep through busmaster requests */ static void -acpi_sleep_on_busmaster(struct acpi_facp *facp) +acpi_sleep_on_busmaster(void) { - u32 pm1_cntr = acpi_read_pm1_control(facp); - if (pm1_cntr & ACPI_BM_RLD) { - pm1_cntr &= ~ACPI_BM_RLD; - acpi_write_pm1_control(facp, pm1_cntr); - } + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); } /* * Set system to wake on busmaster requests */ static void -acpi_wake_on_busmaster(struct acpi_facp *facp) +acpi_wake_on_busmaster(void) { - u32 pm1_cntr = acpi_read_pm1_control(facp); - if (!(pm1_cntr & ACPI_BM_RLD)) { - pm1_cntr |= ACPI_BM_RLD; - acpi_write_pm1_control(facp, pm1_cntr); - } - acpi_clear_bm_activity(facp); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); } -/* The ACPI timer is just the low 24 bits */ -#define TIME_BEGIN(tmr) inl(tmr) -#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff) +u32 +acpi_read_pm_timer(void) +{ + return acpi_hw_register_read(ACPI_MTX_LOCK, PM_TIMER); +} + +/* + * Do a compare, accounting for 24/32bit rollover + */ +static u32 +acpi_compare_pm_timers(u32 first, u32 second) +{ + if (first < second) { + return (second - first); + } else { + if (acpi_pm_tmr_len == 24) + return (second + (0xFFFFFF - first)); + else + return (second + (0xFFFFFFFF - first)); + } +} /* * Idle loop (uniprocessor only) @@ -94,11 +104,11 @@ acpi_idle(void) { static int sleep_level = 1; - struct acpi_facp *facp = &acpi_facp; + FADT_DESCRIPTOR *fadt = &acpi_fadt; - if (!facp - || facp->hdr.signature != ACPI_FACP_SIG - || !facp->pm_tmr + if (!fadt + || (STRNCMP(fadt->header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) + || !fadt->Xpm_tmr_blk.address || !acpi_pblk) goto not_initialized; @@ -116,110 +126,108 @@ sleep3: sleep_level = 3; if (!acpi_c3_tested) { - printk(KERN_DEBUG "ACPI C3 works\n"); + DEBUG_PRINT(ACPI_INFO, ("C3 works\n")); acpi_c3_tested = 1; } - acpi_wake_on_busmaster(facp); - if (facp->pm2_cnt) + acpi_wake_on_busmaster(); + if (fadt->Xpm2_cnt_blk.address) goto sleep3_with_arbiter; for (;;) { unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; - + unsigned long diff; + __cli(); if (current->need_resched) goto out; - if (acpi_bm_activity(facp)) + if (acpi_bm_activity()) goto sleep2; - time = TIME_BEGIN(pm_tmr); + time = acpi_read_pm_timer(); inb(acpi_pblk + ACPI_P_LVL3); /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); + acpi_read_pm_timer(); + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); __sti(); - if (time < acpi_c3_exit_latency) + if (diff < acpi_c3_exit_latency) goto sleep2; } sleep3_with_arbiter: for (;;) { unsigned long time; - u8 arbiter; - unsigned int pm2_cntr = facp->pm2_cnt; - unsigned int pm_tmr = facp->pm_tmr; + unsigned long diff; __cli(); if (current->need_resched) goto out; - if (acpi_bm_activity(facp)) + if (acpi_bm_activity()) goto sleep2; - time = TIME_BEGIN(pm_tmr); - arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS; + time = acpi_read_pm_timer(); + /* Disable arbiter, park on CPU */ - outb(arbiter | ACPI_ARB_DIS, pm2_cntr); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1); inb(acpi_pblk + ACPI_P_LVL3); /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); + acpi_read_pm_timer(); + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); /* Enable arbiter again.. */ - outb(arbiter, pm2_cntr); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0); __sti(); - if (time < acpi_c3_exit_latency) + if (diff < acpi_c3_exit_latency) goto sleep2; } sleep2: sleep_level = 2; if (!acpi_c2_tested) { - printk(KERN_DEBUG "ACPI C2 works\n"); + DEBUG_PRINT(ACPI_INFO, ("C2 works\n")); acpi_c2_tested = 1; } - acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */ + acpi_wake_on_busmaster(); /* Required to track BM activity.. */ for (;;) { unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; + unsigned long diff; __cli(); if (current->need_resched) goto out; - time = TIME_BEGIN(pm_tmr); + time = acpi_read_pm_timer(); inb(acpi_pblk + ACPI_P_LVL2); /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); + acpi_read_pm_timer(); + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); __sti(); - if (time < acpi_c2_exit_latency) + if (diff < acpi_c2_exit_latency) goto sleep1; - if (acpi_bm_activity(facp)) { - acpi_clear_bm_activity(facp); + if (acpi_bm_activity()) { + acpi_clear_bm_activity(); continue; } - if (time > acpi_c3_enter_latency + if (diff > acpi_c3_enter_latency && acpi_max_c_state >= 3) goto sleep3; } sleep1: sleep_level = 1; - acpi_sleep_on_busmaster(facp); + acpi_sleep_on_busmaster(); for (;;) { unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; + unsigned long diff; __cli(); if (current->need_resched) goto out; - time = TIME_BEGIN(pm_tmr); + time = acpi_read_pm_timer(); safe_halt(); - time = TIME_END(pm_tmr, time); - if (time > acpi_c2_enter_latency + diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); + if (diff > acpi_c2_enter_latency && acpi_max_c_state >= 2) goto sleep2; } @@ -240,7 +248,7 @@ * Get processor information */ static ACPI_STATUS -acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) { ACPI_OBJECT obj; ACPI_CX_STATE lat[4]; @@ -253,10 +261,11 @@ if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf))) return AE_OK; - printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n", - obj.processor.proc_id, - obj.processor.pblk_address, - obj.processor.pblk_length); + DEBUG_PRINT(ACPI_INFO, ("PBLK %d @ 0x%04x:%d\n", + obj.processor.proc_id, + obj.processor.pblk_address, + obj.processor.pblk_length)); + if (acpi_pblk != ACPI_INVALID || !obj.processor.pblk_address || obj.processor.pblk_length != 6) @@ -270,19 +279,16 @@ return AE_OK; if (lat[2].latency < MAX_CX_STATE_LATENCY) { - printk(KERN_INFO "ACPI: C2"); + printk(KERN_INFO "ACPI: System firmware supports: C2"); acpi_c2_exit_latency = lat[2].latency; acpi_max_c_state = 2; if (lat[3].latency < MAX_CX_STATE_LATENCY) { - printk(", C3 supported\n"); + printk(" C3"); acpi_c3_exit_latency = lat[3].latency; acpi_max_c_state = 3; } - else { - printk(" supported\n"); - } - + printk("\n"); } memset(throttle, 0, sizeof(throttle)); @@ -296,9 +302,29 @@ if (throttle[i].percent_of_clock) count++; } + + /* 0% throttled really doesn't count */ count--; - if (count > 0) - printk(KERN_INFO "ACPI: %d throttling states\n", count); + + if (count > 0) { + DEBUG_PRINT(ACPI_INFO, ("%d throttling states\n", count)); + } + + return AE_OK; +} + +static int +acpi_pm_timer_init(void) +{ + FADT_DESCRIPTOR *fadt = &acpi_fadt; + + if (fadt->tmr_val_ext) { + acpi_pm_tmr_len = 32; + } else { + acpi_pm_tmr_len = 24; + } + + DEBUG_PRINT(ACPI_INFO, ("PM Timer width: %d bits\n", acpi_pm_tmr_len)); return AE_OK; } @@ -309,9 +335,12 @@ acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - acpi_find_cpu, + acpi_found_cpu, NULL, NULL); + + acpi_pm_timer_init(); + #ifdef CONFIG_SMP if (smp_num_cpus == 1) diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/Makefile linux-2.4.0-test12-lia/drivers/acpi/dispatcher/Makefile --- linux-2.4.0-test12/drivers/acpi/dispatcher/Makefile Fri Sep 15 18:21:43 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dsobject.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dsobject.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dsobject.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dsobject.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 43 $ + * $Revision: 51 $ * *****************************************************************************/ @@ -64,9 +64,13 @@ { OBJECT_TYPE_INTERNAL type; ACPI_STATUS status; - INIT_WALK_INFO *info = (INIT_WALK_INFO *) context; + ACPI_INIT_WALK_INFO *info = (ACPI_INIT_WALK_INFO *) context; + u8 table_revision; + info->object_count++; + table_revision = info->table_desc->pointer->revision; + /* * We are only interested in objects owned by the table that * was just loaded @@ -98,6 +102,14 @@ info->method_count++; + /* + * Set the execution data width (32 or 64) based upon the + * revision number of the parent ACPI table. + */ + + if (table_revision == 1) { + ((ACPI_NAMESPACE_NODE *)obj_handle)->flags |= ANOBJ_DATA_WIDTH_32; + } /* * Always parse methods to detect errors, we may delete @@ -113,14 +125,10 @@ } /* - * Keep the parse tree only if we are parsing all methods - * at init time (versus just-in-time) + * Delete the parse tree. We simple re-parse the method + * for every execution since there isn't much overhead */ - - if (acpi_gbl_when_to_parse_methods != METHOD_PARSE_AT_INIT) { - acpi_ns_delete_namespace_subtree (obj_handle); - } - + acpi_ns_delete_namespace_subtree (obj_handle); break; default: @@ -154,12 +162,13 @@ ACPI_NAMESPACE_NODE *start_node) { ACPI_STATUS status; - INIT_WALK_INFO info; + ACPI_INIT_WALK_INFO info; - info.method_count = 0; + info.method_count = 0; info.op_region_count = 0; - info.table_desc = table_desc; + info.object_count = 0; + info.table_desc = table_desc; /* Walk entire namespace from the supplied root */ @@ -239,16 +248,24 @@ /* Get the value, delete the internal object */ - (*obj_desc)->buffer.length = arg_desc->number.value; + (*obj_desc)->buffer.length = (u32) arg_desc->number.value; acpi_cm_remove_reference (arg_desc); /* Allocate the buffer */ - (*obj_desc)->buffer.pointer = - acpi_cm_callocate ((*obj_desc)->buffer.length); + if ((*obj_desc)->buffer.length == 0) { + (*obj_desc)->buffer.pointer = NULL; + REPORT_WARNING (("Buffer created with zero length in AML\n")); + break; + } + + else { + (*obj_desc)->buffer.pointer = + acpi_cm_callocate ((*obj_desc)->buffer.length); - if (!(*obj_desc)->buffer.pointer) { - return (AE_NO_MEMORY); + if (!(*obj_desc)->buffer.pointer) { + return (AE_NO_MEMORY); + } } /* @@ -360,7 +377,7 @@ * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ds_build_internal_simple_obj ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op, @@ -369,6 +386,8 @@ ACPI_OPERAND_OBJECT *obj_desc; OBJECT_TYPE_INTERNAL type; ACPI_STATUS status; + u32 length; + char *name; if (op->opcode == AML_NAMEPATH_OP) { @@ -387,6 +406,22 @@ (ACPI_NAMESPACE_NODE **)&(op->node)); if (ACPI_FAILURE (status)) { + if (status == AE_NOT_FOUND) { + name = NULL; + acpi_ns_externalize_name (ACPI_UINT32_MAX, op->value.string, &length, &name); + + if (name) { + REPORT_WARNING (("Reference %s AML 0x%X not found\n", + name, op->aml_offset)); + acpi_cm_free (name); + } + else { + REPORT_WARNING (("Reference %s AML 0x%X not found\n", + op->value.string, op->aml_offset)); + } + *obj_desc_ptr = NULL; + } + return (status); } } @@ -473,7 +508,7 @@ if (!obj_desc->package.elements) { /* Package vector allocation failure */ - REPORT_ERROR ("Ds_build_internal_package_obj: Package vector allocation failure"); + REPORT_ERROR (("Ds_build_internal_package_obj: Package vector allocation failure\n")); acpi_cm_delete_object_desc (obj_desc); return (AE_NO_MEMORY); @@ -578,7 +613,7 @@ status = acpi_ds_build_internal_object (walk_state, op->value.arg, &obj_desc); if (ACPI_FAILURE (status)) { - goto cleanup; + return (status); } diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dsopcode.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dsopcode.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dsopcode.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dsopcode.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: dsopcode - Dispatcher Op Region support and handling of * "control" opcodes - * $Revision: 17 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -40,9 +40,117 @@ /***************************************************************************** * + * FUNCTION: Acpi_ds_get_field_unit_arguments + * + * PARAMETERS: Obj_desc - A valid Field_unit object + * + * RETURN: Status. + * + * DESCRIPTION: Get Field_unit Buffer and Index. This implements the late + * evaluation of these field attributes. + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ds_get_field_unit_arguments ( + ACPI_OPERAND_OBJECT *obj_desc) +{ + ACPI_OPERAND_OBJECT *extra_desc; + ACPI_NAMESPACE_NODE *node; + ACPI_PARSE_OBJECT *op; + ACPI_PARSE_OBJECT *field_op; + ACPI_STATUS status; + ACPI_TABLE_DESC *table_desc; + + + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + return (AE_OK); + } + + + /* Get the AML pointer (method object) and Field_unit node */ + + extra_desc = obj_desc->field_unit.extra; + node = obj_desc->field_unit.node; + + + /* + * Allocate a new parser op to be the root of the parsed + * Op_region tree + */ + + op = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!op) { + return (AE_NO_MEMORY); + } + + /* Save the Node for use in Acpi_ps_parse_aml */ + + op->node = acpi_ns_get_parent_object (node); + + /* Get a handle to the parent ACPI table */ + + status = acpi_tb_handle_to_object (node->owner_id, &table_desc); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Pass1: Parse the entire Field_unit declaration */ + + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, 0, + NULL, NULL, NULL, acpi_ds_load1_begin_op, acpi_ds_load1_end_op); + if (ACPI_FAILURE (status)) { + acpi_ps_delete_parse_tree (op); + return (status); + } + + + /* Get and init the actual Fiel_unit_op created above */ + + field_op = op->value.arg; + op->node = node; + + + field_op = op->value.arg; + field_op->node = node; + acpi_ps_delete_parse_tree (op); + + /* Acpi_evaluate the address and length arguments for the Op_region */ + + op = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!op) { + return (AE_NO_MEMORY); + } + + op->node = acpi_ns_get_parent_object (node); + + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, + ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE, + NULL /*Method_desc*/, NULL, NULL, + acpi_ds_exec_begin_op, acpi_ds_exec_end_op); + /* All done with the parse tree, delete it */ + + acpi_ps_delete_parse_tree (op); + + + /* + * The pseudo-method object is no longer needed since the region is + * now initialized + */ + acpi_cm_remove_reference (obj_desc->field_unit.extra); + obj_desc->field_unit.extra = NULL; + + return (status); +} + + +/***************************************************************************** + * * FUNCTION: Acpi_ds_get_region_arguments * - * PARAMETERS: Rgn_desc - A valid region object + * PARAMETERS: Obj_desc - A valid region object * * RETURN: Status. * @@ -53,9 +161,9 @@ ACPI_STATUS acpi_ds_get_region_arguments ( - ACPI_OPERAND_OBJECT *rgn_desc) + ACPI_OPERAND_OBJECT *obj_desc) { - ACPI_OPERAND_OBJECT *method_desc; + ACPI_OPERAND_OBJECT *extra_desc = NULL; ACPI_NAMESPACE_NODE *node; ACPI_PARSE_OBJECT *op; ACPI_PARSE_OBJECT *region_op; @@ -63,14 +171,15 @@ ACPI_TABLE_DESC *table_desc; - if (rgn_desc->region.flags & AOPOBJ_DATA_VALID) { + if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { return (AE_OK); } - method_desc = rgn_desc->region.method; - node = rgn_desc->region.node; + /* Get the AML pointer (method object) and region node */ + extra_desc = obj_desc->region.extra; + node = obj_desc->region.node; /* * Allocate a new parser op to be the root of the parsed @@ -95,8 +204,8 @@ /* Parse the entire Op_region declaration, creating a parse tree */ - status = acpi_ps_parse_aml (op, method_desc->method.pcode, - method_desc->method.pcode_length, 0, + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, 0, NULL, NULL, NULL, acpi_ds_load1_begin_op, acpi_ds_load1_end_op); if (ACPI_FAILURE (status)) { @@ -107,8 +216,8 @@ /* Get and init the actual Region_op created above */ -/* Region_op = Op->Value.Arg; - Op->Node = Node;*/ + region_op = op->value.arg; + op->node = node; region_op = op->value.arg; @@ -124,16 +233,12 @@ op->node = acpi_ns_get_parent_object (node); - status = acpi_ps_parse_aml (op, method_desc->method.pcode, - method_desc->method.pcode_length, + status = acpi_ps_parse_aml (op, extra_desc->extra.pcode, + extra_desc->extra.pcode_length, ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE, NULL /*Method_desc*/, NULL, NULL, acpi_ds_exec_begin_op, acpi_ds_exec_end_op); -/* - Acpi_ps_walk_parsed_aml (Region_op, Region_op, NULL, NULL, NULL, - NULL, Table_desc->Table_id, - Acpi_ds_exec_begin_op, Acpi_ds_exec_end_op); -*/ + /* All done with the parse tree, delete it */ acpi_ps_delete_parse_tree (op); @@ -174,6 +279,252 @@ /***************************************************************************** * + * FUNCTION: Acpi_ds_eval_field_unit_operands + * + * PARAMETERS: Op - A valid Field_unit Op object + * + * RETURN: Status + * + * DESCRIPTION: Get Field_unit Buffer and Index + * Called from Acpi_ds_exec_end_op during Field_unit parse tree walk + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ds_eval_field_unit_operands ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op) +{ + ACPI_STATUS status; + ACPI_OPERAND_OBJECT *field_desc; + ACPI_NAMESPACE_NODE *node; + ACPI_PARSE_OBJECT *next_op; + u32 offset; + u32 bit_offset; + u16 bit_count; + + + ACPI_OPERAND_OBJECT *res_desc = NULL; + ACPI_OPERAND_OBJECT *cnt_desc = NULL; + ACPI_OPERAND_OBJECT *off_desc = NULL; + ACPI_OPERAND_OBJECT *src_desc = NULL; + u32 num_operands = 3; + + + /* + * This is where we evaluate the address and length fields of the Op_field_unit declaration + */ + + node = op->node; + + /* Next_op points to the op that holds the Buffer */ + next_op = op->value.arg; + + /* Acpi_evaluate/create the address and length operands */ + + status = acpi_ds_create_operands (walk_state, next_op); + if (ACPI_FAILURE (status)) { + return (status); + } + + field_desc = acpi_ns_get_attached_object (node); + if (!field_desc) { + return (AE_NOT_EXIST); + } + + + /* Resolve the operands */ + + status = acpi_aml_resolve_operands (op->opcode, WALK_OPERANDS, walk_state); + + /* Get the operands */ + + status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state); + if (AML_CREATE_FIELD_OP == op->opcode) { + num_operands = 4; + status |= acpi_ds_obj_stack_pop_object (&cnt_desc, walk_state); + } + + status |= acpi_ds_obj_stack_pop_object (&off_desc, walk_state); + status |= acpi_ds_obj_stack_pop_object (&src_desc, walk_state); + + if (ACPI_FAILURE (status)) { + /* Invalid parameters on object stack */ + + goto cleanup; + } + + + offset = (u32) off_desc->number.value; + + + /* + * If Res_desc is a Name, it will be a direct name pointer after + * Acpi_aml_resolve_operands() + */ + + if (!VALID_DESCRIPTOR_TYPE (res_desc, ACPI_DESC_TYPE_NAMED)) { + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + + /* + * Setup the Bit offsets and counts, according to the opcode + */ + + switch (op->opcode) + { + + /* Def_create_bit_field */ + + case AML_BIT_FIELD_OP: + + /* Offset is in bits, Field is a bit */ + + bit_offset = offset; + bit_count = 1; + break; + + + /* Def_create_byte_field */ + + case AML_BYTE_FIELD_OP: + + /* Offset is in bytes, field is a byte */ + + bit_offset = 8 * offset; + bit_count = 8; + break; + + + /* Def_create_word_field */ + + case AML_WORD_FIELD_OP: + + /* Offset is in bytes, field is a word */ + + bit_offset = 8 * offset; + bit_count = 16; + break; + + + /* Def_create_dWord_field */ + + case AML_DWORD_FIELD_OP: + + /* Offset is in bytes, field is a dword */ + + bit_offset = 8 * offset; + bit_count = 32; + break; + + + /* Def_create_field */ + + case AML_CREATE_FIELD_OP: + + /* Offset is in bits, count is in bits */ + + bit_offset = offset; + bit_count = (u16) cnt_desc->number.value; + break; + + + default: + + status = AE_AML_BAD_OPCODE; + goto cleanup; + } + + + /* + * Setup field according to the object type + */ + + switch (src_desc->common.type) + { + + /* Source_buff := Term_arg=>Buffer */ + + case ACPI_TYPE_BUFFER: + + if (bit_offset + (u32) bit_count > + (8 * (u32) src_desc->buffer.length)) + { + status = AE_AML_BUFFER_LIMIT; + goto cleanup; + } + + + /* Construct the remainder of the field object */ + + field_desc->field_unit.access = (u8) ACCESS_ANY_ACC; + field_desc->field_unit.lock_rule = (u8) GLOCK_NEVER_LOCK; + field_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE; + field_desc->field_unit.length = bit_count; + field_desc->field_unit.bit_offset = (u8) (bit_offset % 8); + field_desc->field_unit.offset = DIV_8 (bit_offset); + field_desc->field_unit.container = src_desc; + + /* Reference count for Src_desc inherits Field_desc count */ + + src_desc->common.reference_count = (u16) (src_desc->common.reference_count + + field_desc->common.reference_count); + + break; + + + /* Improper object type */ + + default: + + if ((src_desc->common.type > (u8) INTERNAL_TYPE_REFERENCE) || + !acpi_cm_valid_object_type (src_desc->common.type)) + + + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + + if (AML_CREATE_FIELD_OP == op->opcode) { + /* Delete object descriptor unique to Create_field */ + + acpi_cm_remove_reference (cnt_desc); + cnt_desc = NULL; + } + + +cleanup: + + /* Always delete the operands */ + + acpi_cm_remove_reference (off_desc); + acpi_cm_remove_reference (src_desc); + + if (AML_CREATE_FIELD_OP == op->opcode) { + acpi_cm_remove_reference (cnt_desc); + } + + /* On failure, delete the result descriptor */ + + if (ACPI_FAILURE (status)) { + acpi_cm_remove_reference (res_desc); /* Result descriptor */ + } + + else { + /* Now the address and length are valid for this op_field_unit */ + + field_desc->field_unit.flags |= AOPOBJ_DATA_VALID; + } + + return (status); +} + + +/***************************************************************************** + * * FUNCTION: Acpi_ds_eval_region_operands * * PARAMETERS: Op - A valid region Op object @@ -192,7 +543,7 @@ { ACPI_STATUS status; ACPI_OPERAND_OBJECT *obj_desc; - ACPI_OPERAND_OBJECT *region_desc; + ACPI_OPERAND_OBJECT *operand_desc; ACPI_NAMESPACE_NODE *node; ACPI_PARSE_OBJECT *next_op; @@ -216,31 +567,41 @@ return (status); } - region_desc = acpi_ns_get_attached_object (node); - if (!region_desc) { - return (AE_NOT_EXIST); + /* Resolve the length and address operands to numbers */ + + status = acpi_aml_resolve_operands (op->opcode, WALK_OPERANDS, walk_state); + if (ACPI_FAILURE (status)) { + return (status); } - /* Get the length and save it */ - /* Top of stack */ - obj_desc = walk_state->operands[walk_state->num_operands - 1]; + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + return (AE_NOT_EXIST); + } - region_desc->region.length = obj_desc->number.value; - acpi_cm_remove_reference (obj_desc); + /* + * Get the length operand and save it + * (at Top of stack) + */ + operand_desc = walk_state->operands[walk_state->num_operands - 1]; - /* Get the address and save it */ + obj_desc->region.length = (u32) operand_desc->number.value; + acpi_cm_remove_reference (operand_desc); - /* Top of stack - 1 */ - obj_desc = walk_state->operands[walk_state->num_operands - 2]; + /* + * Get the address and save it + * (at top of stack - 1) + */ + operand_desc = walk_state->operands[walk_state->num_operands - 2]; - region_desc->region.address = obj_desc->number.value; - acpi_cm_remove_reference (obj_desc); + obj_desc->region.address = (ACPI_PHYSICAL_ADDRESS) operand_desc->number.value; + acpi_cm_remove_reference (operand_desc); /* Now the address and length are valid for this opregion */ - region_desc->region.flags |= AOPOBJ_DATA_VALID; + obj_desc->region.flags |= AOPOBJ_DATA_VALID; return (status); } @@ -294,6 +655,7 @@ */ walk_state->control_state->control.aml_predicate_start = walk_state->parser_state->aml - 1; + /* TBD: can this be removed? */ /*Acpi_ps_pkg_length_encoding_size (GET8 (Walk_state->Parser_state->Aml));*/ break; @@ -385,15 +747,14 @@ status = AE_CTRL_PENDING; } -/* else {*/ - /* Pop this control state and free it */ - control_state = - acpi_cm_pop_generic_state (&walk_state->control_state); + /* Pop this control state and free it */ - walk_state->aml_last_while = control_state->control.aml_predicate_start; - acpi_cm_delete_generic_state (control_state); -/* }*/ + control_state = + acpi_cm_pop_generic_state (&walk_state->control_state); + + walk_state->aml_last_while = control_state->control.aml_predicate_start; + acpi_cm_delete_generic_state (control_state); break; diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dsutils.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dsutils.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dsutils.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dsutils.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dsutils - Dispatcher utilities - * $Revision: 44 $ + * $Revision: 48 $ * ******************************************************************************/ @@ -52,7 +52,8 @@ u8 acpi_ds_is_result_used ( - ACPI_PARSE_OBJECT *op) + ACPI_PARSE_OBJECT *op, + ACPI_WALK_STATE *walk_state) { ACPI_OPCODE_INFO *parent_info; @@ -85,13 +86,6 @@ } - /* Never delete the return value associated with a return opcode */ - - if (op->parent->opcode == AML_RETURN_OP) { - return (TRUE); - } - - /* * Decide what to do with the result based on the parent. If * the parent opcode will not use the result, delete the object. @@ -105,6 +99,37 @@ * In these cases, the parent will never use the return object */ case OPTYPE_CONTROL: /* IF, ELSE, WHILE only */ + + switch (op->parent->opcode) + { + case AML_RETURN_OP: + + /* Never delete the return value associated with a return opcode */ + + return (TRUE); + break; + + case AML_IF_OP: + case AML_WHILE_OP: + + /* + * If we are executing the predicate AND this is the predicate op, + * we will use the return value! + */ + + if ((walk_state->control_state->common.state == CONTROL_PREDICATE_EXECUTING) && + (walk_state->control_state->control.predicate_op == op)) + { + return (TRUE); + } + + break; + } + + + /* Fall through to not used case below */ + + case OPTYPE_NAMED_OBJECT: /* Scope, method, etc. */ return (FALSE); @@ -158,7 +183,7 @@ } - if (!acpi_ds_is_result_used (op)) { + if (!acpi_ds_is_result_used (op, walk_state)) { /* * Must pop the result stack (Obj_desc should be equal * to Result_obj) @@ -237,6 +262,7 @@ parent_op = arg->parent; if ((acpi_ps_is_node_op (parent_op->opcode)) && (parent_op->opcode != AML_METHODCALL_OP) && + (parent_op->opcode != AML_REGION_OP) && (parent_op->opcode != AML_NAMEPATH_OP)) { /* Enter name into namespace if not found */ @@ -539,8 +565,10 @@ case AML_NAMEPATH_OP: data_type = INTERNAL_TYPE_REFERENCE; break; - } + default: + break; + } break; @@ -557,8 +585,10 @@ data_type = ACPI_TYPE_PACKAGE; break; - } + default: + break; + } break; @@ -581,21 +611,18 @@ flags = OP_HAS_RETURN_VALUE; data_type = ACPI_TYPE_ANY; - break; case OPTYPE_METHOD_CALL: flags = OP_HAS_RETURN_VALUE; data_type = ACPI_TYPE_METHOD; - break; case OPTYPE_NAMED_OBJECT: data_type = acpi_ds_map_named_opcode_to_data_type (opcode); - break; diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dswexec.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswexec.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dswexec.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswexec.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: dswexec - Dispatcher method execution callbacks; * dispatch to interpreter. - * $Revision: 42 $ + * $Revision: 48 $ * *****************************************************************************/ @@ -40,6 +40,110 @@ /***************************************************************************** * + * FUNCTION: Acpi_ds_get_predicate_value + * + * PARAMETERS: Walk_state - Current state of the parse tree walk + * + * RETURN: Status + * + * DESCRIPTION: + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ds_get_predicate_value ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op, + u32 has_result_obj) +{ + ACPI_STATUS status = AE_OK; + ACPI_OPERAND_OBJECT *obj_desc; + + + walk_state->control_state->common.state = 0; + + if (has_result_obj) { + status = acpi_ds_result_stack_pop (&obj_desc, walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + else { + status = acpi_ds_create_operand (walk_state, op); + if (ACPI_FAILURE (status)) { + return (status); + } + + status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state); + if (ACPI_FAILURE (status)) { + return (status); + } + + obj_desc = walk_state->operands [0]; + } + + if (!obj_desc) { + return (AE_AML_NO_OPERAND); + } + + + /* + * Result of predicate evaluation currently must + * be a number + */ + + if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + status = AE_AML_OPERAND_TYPE; + goto cleanup; + } + + + /* TBD: 64/32-bit */ + + obj_desc->number.value &= (UINT64) 0x00000000FFFFFFFF; + + /* + * Save the result of the predicate evaluation on + * the control stack + */ + + if (obj_desc->number.value) { + walk_state->control_state->common.value = TRUE; + } + + else { + /* + * Predicate is FALSE, we will just toss the + * rest of the package + */ + + walk_state->control_state->common.value = FALSE; + status = AE_CTRL_FALSE; + } + + +cleanup: + + /* Break to debugger to display result */ + + DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state)); + + /* + * Delete the predicate result object (we know that + * we don't need it anymore) + */ + + acpi_cm_remove_reference (obj_desc); + + walk_state->control_state->common.state = CONTROL_NORMAL; + + return (status); +} + + +/***************************************************************************** + * * FUNCTION: Acpi_ds_exec_begin_op * * PARAMETERS: Walk_state - Current state of the parse tree walk @@ -171,7 +275,6 @@ ACPI_STATUS status = AE_OK; u16 opcode; u8 optype; - ACPI_OPERAND_OBJECT *obj_desc; ACPI_PARSE_OBJECT *next_op; ACPI_NAMESPACE_NODE *node; ACPI_PARSE_OBJECT *first_arg; @@ -236,7 +339,6 @@ case OPTYPE_RECONFIGURATION: case OPTYPE_INDEX: case OPTYPE_MATCH: - case OPTYPE_CREATE_FIELD: case OPTYPE_FATAL: @@ -341,14 +443,6 @@ break; - case OPTYPE_CREATE_FIELD: - - /* 3 or 4 Operands, 0 External_result, 0 Internal_result */ - - status = acpi_aml_exec_create_field (opcode, walk_state); - break; - - case OPTYPE_FATAL: /* 3 Operands, 0 External_result, 0 Internal_result */ @@ -400,17 +494,17 @@ * the method Node pointer */ /* Next_op points to the op that holds the method name */ + next_op = first_arg; node = next_op->node; /* Next_op points to first argument op */ - next_op = next_op->next; + next_op = next_op->next; /* * Get the method's arguments and put them on the operand stack */ - status = acpi_ds_create_operands (walk_state, next_op); if (ACPI_FAILURE (status)) { break; @@ -428,43 +522,37 @@ break; } - /* Open new scope on the scope stack */ -/* - Status = Acpi_ns_scope_stack_push_entry (Node); - if (ACPI_FAILURE (Status)) { - break; - } -*/ + /* + * Tell the walk loop to preempt this running method and + * execute the new method + */ + status = AE_CTRL_TRANSFER; - /* Tell the walk loop to preempt this running method and - execute the new method */ + /* + * Return now; we don't want to disturb anything, + * especially the operand count! + */ + return (status); + break; - status = AE_CTRL_TRANSFER; - /* Return now; we don't want to disturb anything, - especially the operand count! */ + case OPTYPE_CREATE_FIELD: - return (status); + status = acpi_ds_load2_end_op (walk_state, op); + if (ACPI_FAILURE (status)) { + break; + } + + status = acpi_ds_eval_field_unit_operands (walk_state, op); break; case OPTYPE_NAMED_OBJECT: - status = acpi_ds_load2_end_op (walk_state, op); if (ACPI_FAILURE (status)) { break; } -/* - if ((Walk_state->Origin->Opcode == AML_METHOD_OP) && - (Walk_state->Origin != Op)) - { - Status = Acpi_ds_load2_end_op (Walk_state, Op); - if (ACPI_FAILURE (Status)) { - break; - } - } -*/ switch (op->opcode) { @@ -504,6 +592,12 @@ /* + * ACPI 2.0 support for 64-bit integers: + * Truncate numeric result value if we are executing from a 32-bit ACPI table + */ + acpi_aml_truncate_for32bit_table (result_obj, walk_state); + + /* * Check if we just completed the evaluation of a * conditional predicate */ @@ -513,70 +607,12 @@ CONTROL_PREDICATE_EXECUTING) && (walk_state->control_state->control.predicate_op == op)) { - /* Completed the predicate, the result must be a number */ - - walk_state->control_state->common.state = 0; - - if (result_obj) { - status = acpi_ds_result_stack_pop (&obj_desc, walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - } - - else { - status = acpi_ds_create_operand (walk_state, op); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - obj_desc = walk_state->operands [0]; - } - - if (!obj_desc) { - status = AE_AML_NO_OPERAND; - goto cleanup; - } - - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - /* Save the result of the predicate evaluation on - the control stack */ - - if (obj_desc->number.value) { - walk_state->control_state->common.value = TRUE; - } - else { - /* Predicate is FALSE, we will just toss the - rest of the package */ - - walk_state->control_state->common.value = FALSE; - status = AE_CTRL_FALSE; - } - - /* Break to debugger to display result */ - - DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state)); - - /* Delete the predicate result object (we know that - we don't need it anymore) and cleanup the stack */ - - acpi_cm_remove_reference (obj_desc); + status = acpi_ds_get_predicate_value (walk_state, op, (u32) result_obj); result_obj = NULL; - - walk_state->control_state->common.state = CONTROL_NORMAL; } cleanup: - if (result_obj) { /* Break to debugger to display result */ diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dswload.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswload.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dswload.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswload.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswload - Dispatcher namespace load callbacks - * $Revision: 19 $ + * $Revision: 23 $ * *****************************************************************************/ @@ -86,6 +86,7 @@ data_type = acpi_ds_map_named_opcode_to_data_type (opcode); + /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve @@ -438,6 +439,11 @@ case AML_WORD_FIELD_OP: case AML_DWORD_FIELD_OP: + /* + * Create the field object, but the field buffer and index must + * be evaluated later during the execution phase + */ + /* Get the Name_string argument */ if (op->opcode == AML_CREATE_FIELD_OP) { @@ -468,15 +474,22 @@ op->node = new_node; /* - * If this is NOT a control method, we need to evaluate this opcode now. + * If there is no object attached to the node, this node was just created and + * we need to create the field object. Otherwise, this was a lookup of an + * existing node and we don't want to create the field object again. */ - - /* THIS WON"T WORK. Must execute all operands like Add(). => Must do an execute pass - if (!Walk_state->Method_desc) { - Status = Acpi_ds_exec_end_op (Walk_state, Op); + if (!new_node->object) { + /* + * The Field definition is not fully parsed at this time. + * (We must save the address of the AML for the buffer and index operands) + */ + status = acpi_aml_exec_create_field (((ACPI_PARSE2_OBJECT *) op)->data, + ((ACPI_PARSE2_OBJECT *) op)->length, + new_node, walk_state); } - */ } + + break; @@ -639,7 +652,15 @@ case AML_NAME_OP: - status = acpi_ds_create_node (walk_state, node, op); + /* + * Because of the execution pass through the non-control-method + * parts of the table, we can arrive here twice. Only init + * the named object node the first time through + */ + + if (!node->object) { + status = acpi_ds_create_node (walk_state, node, op); + } break; @@ -661,4 +682,5 @@ acpi_ds_obj_stack_pop (1, walk_state); return (status); } + diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dswscope.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswscope.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dswscope.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswscope.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswscope - Scope stack manipulation - * $Revision: 38 $ + * $Revision: 39 $ * *****************************************************************************/ @@ -89,14 +89,14 @@ if (!node) { /* invalid scope */ - REPORT_ERROR ("Ds_scope_stack_push: null scope passed"); + REPORT_ERROR (("Ds_scope_stack_push: null scope passed\n")); return (AE_BAD_PARAMETER); } /* Make sure object type is valid */ if (!acpi_aml_validate_object_type (type)) { - REPORT_WARNING ("Ds_scope_stack_push: type code out of range"); + REPORT_WARNING (("Ds_scope_stack_push: type code out of range\n")); } diff -urN linux-2.4.0-test12/drivers/acpi/dispatcher/dswstate.c linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswstate.c --- linux-2.4.0-test12/drivers/acpi/dispatcher/dswstate.c Fri Sep 15 14:30:29 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/dispatcher/dswstate.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dswstate - Dispatcher parse tree walk management routines - * $Revision: 31 $ + * $Revision: 34 $ * *****************************************************************************/ @@ -414,7 +414,7 @@ * ******************************************************************************/ -void +static void acpi_ds_push_walk_state ( ACPI_WALK_STATE *walk_state, ACPI_WALK_LIST *walk_list) @@ -528,7 +528,9 @@ /* Init the method args/local */ +#ifndef _ACPI_ASL_COMPILER acpi_ds_method_data_init (walk_state); +#endif /* Put the new state at the head of the walk list */ diff -urN linux-2.4.0-test12/drivers/acpi/driver.c linux-2.4.0-test12-lia/drivers/acpi/driver.c --- linux-2.4.0-test12/drivers/acpi/driver.c Wed Dec 13 17:29:33 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/driver.c Wed Dec 13 17:31:39 2000 @@ -48,7 +48,15 @@ static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); static volatile int acpi_thread_pid = -1; + +/************************************************/ +/* DECLARE_TASK_QUEUE is defined in */ +/* /usr/src/linux/include/linux/tqueue.h */ +/* So, acpi_thread_run is a pointer to a */ +/* tq_struct structure,defined in the same file.*/ +/************************************************/ static DECLARE_TASK_QUEUE(acpi_thread_run); + static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait); static struct ctl_table_header *acpi_sysctl = NULL; @@ -98,6 +106,38 @@ return 0; } +static int +acpi_do_pm_timer(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + int size; + u32 val = 0; + + char str[12]; + + if (file->f_pos) { + *len = 0; + return 0; + } + + val = acpi_read_pm_timer(); + + size = sprintf(str, "0x%08x\n", val); + if (*len >= size) { + copy_to_user(buffer, str, size); + *len = size; + } + else + *len = 0; + + file->f_pos += *len; + + return 0; +} + /* * Handle ACPI event */ @@ -105,13 +145,18 @@ acpi_event(void *context) { unsigned long flags; - int event = (int) context; + int event = (int)(long)context; int mask = 0; switch (event) { - case ACPI_EVENT_POWER_BUTTON: mask = ACPI_PWRBTN; break; - case ACPI_EVENT_SLEEP_BUTTON: mask = ACPI_SLPBTN; break; - default: return AE_ERROR; + case ACPI_EVENT_POWER_BUTTON: + mask = ACPI_PWRBTN; + break; + case ACPI_EVENT_SLEEP_BUTTON: + mask = ACPI_SLPBTN; + break; + default: + return AE_ERROR; } if (mask) { @@ -196,19 +241,78 @@ } } else { -#ifdef CONFIG_ACPI_S1_SLEEP int status = acpi_enter_sx(ACPI_S1); if (status) return status; -#endif } file->f_pos += *len; return 0; } + /* - * Run queued callback + * Output important ACPI tables to proc */ +static int +acpi_do_table(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + u32 table_type; + size_t size; + ACPI_BUFFER buf; + u8* data; + + table_type = (u32) ctl->data; + size = 0; + buf.length = 0; + buf.pointer = NULL; + + /* determine what buffer size we will need */ + if (acpi_get_table(table_type, 1, &buf) != AE_BUFFER_OVERFLOW) { + *len = 0; + return 0; + } + + buf.pointer = kmalloc(buf.length, GFP_KERNEL); + if (!buf.pointer) { + return -ENOMEM; + } + + /* get the table for real */ + if (!ACPI_SUCCESS(acpi_get_table(table_type, 1, &buf))) { + kfree(buf.pointer); + *len = 0; + return 0; + } + + if (file->f_pos < buf.length) { + data = buf.pointer + file->f_pos; + size = buf.length - file->f_pos; + if (size > *len) + size = *len; + if (copy_to_user(buffer, data, size)) + return -EFAULT; + } + + kfree(buf.pointer); + + *len = size; + file->f_pos += size; + return 0; +} + +/********************************************************************/ +/* R U N Q U E U E D C A L L B A C K */ +/* */ +/* The "callback" function address that was tramped through via */ +/* "acpi_run" below is finally called and executed. If we trace all */ +/* this down, the function is acpi_ev_asynch_execute_gpe_method, in */ +/* evevent.c The only other function that is ever queued is */ +/* acpi_ev_global_lock_thread in evmisc.c. */ +/********************************************************************/ static void acpi_run_exec(void *context) { @@ -266,6 +370,20 @@ {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event}, + {ACPI_FADT, "fadt", (void *) ACPI_TABLE_FADT, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_DSDT, "dsdt", (void *) ACPI_TABLE_DSDT, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_FACS, "facs", (void *) ACPI_TABLE_FACS, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_XSDT, "xsdt", (void *) ACPI_TABLE_XSDT, sizeof(int), + 0444, NULL, &acpi_do_table}, + + {ACPI_PMTIMER, "pm_timer", NULL, 0, 0444, NULL, &acpi_do_pm_timer}, + {0} }; @@ -281,50 +399,74 @@ static int acpi_thread(void *context) { + ACPI_PHYSICAL_ADDRESS rsdp_phys; + /* * initialize */ - daemonize(); - strcpy(current->comm, "acpi"); + strcpy(current->comm, "kacpid"); - if (!ACPI_SUCCESS(acpi_initialize(NULL))) { - printk(KERN_ERR "ACPI: initialize failed\n"); + if (!ACPI_SUCCESS(acpi_initialize_subsystem())) { + printk(KERN_ERR "ACPI: Driver initialization failed\n"); return -ENODEV; } + + /* arch-specific call to get rsdp ptr */ + rsdp_phys = acpi_get_rsdp_ptr(); + + if (!rsdp_phys) { + printk(KERN_ERR "ACPI: System description tables not found\n"); + return -ENODEV; + } + + printk(KERN_ERR "ACPI: System description tables found\n"); - if (acpi_load_tables()) + if (!ACPI_SUCCESS(acpi_find_and_load_tables(rsdp_phys))) return -ENODEV; if (PM_IS_ACTIVE()) { - printk(KERN_NOTICE "ACPI: APM is already active.\n"); + printk(KERN_NOTICE "ACPI: APM is already active, exiting\n"); acpi_terminate(); return -ENODEV; } - pm_active = 1; - - if (!ACPI_SUCCESS(acpi_enable())) { - printk(KERN_ERR "ACPI: enable failed\n"); + if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION))) { + printk(KERN_ERR "ACPI: Subsystem enable failed\n"); acpi_terminate(); return -ENODEV; } + printk(KERN_ERR "ACPI: Subsystem enabled\n"); + + pm_active = 1; + acpi_cpu_init(); acpi_sys_init(); acpi_ec_init(); + acpi_cmbatt_init(); - if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( - ACPI_EVENT_POWER_BUTTON, - acpi_event, - (void *) ACPI_EVENT_POWER_BUTTON))) { - printk(KERN_ERR "ACPI: power button enable failed\n"); - } - if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( - ACPI_EVENT_SLEEP_BUTTON, - acpi_event, - (void *) ACPI_EVENT_SLEEP_BUTTON))) { - printk(KERN_ERR "ACPI: sleep button enable failed\n"); + /* + * Non-intuitive: 0 means pwr and sleep are implemented using the fixed + * feature model, so we install handlers. 1 means a control method + * implementation, or none at all, so do nothing. See ACPI spec. + */ + if (acpi_fadt.pwr_button == 0) { + if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( + ACPI_EVENT_POWER_BUTTON, + acpi_event, + (void *) ACPI_EVENT_POWER_BUTTON))) { + printk(KERN_ERR "ACPI: power button enable failed\n"); + } + } + + if (acpi_fadt.sleep_button == 0) { + if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( + ACPI_EVENT_SLEEP_BUTTON, + acpi_event, + (void *) ACPI_EVENT_SLEEP_BUTTON))) { + printk(KERN_ERR "ACPI: sleep button enable failed\n"); + } } acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); @@ -343,7 +485,9 @@ * terminate */ unregister_sysctl_table(acpi_sysctl); - acpi_terminate(); + + /* do not terminate, because we need acpi in order to shut down */ + /*acpi_terminate();*/ acpi_thread_pid = -1; diff -urN linux-2.4.0-test12/drivers/acpi/driver.h linux-2.4.0-test12-lia/drivers/acpi/driver.h --- linux-2.4.0-test12/drivers/acpi/driver.h Wed Jul 12 13:21:57 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/driver.h Wed Dec 6 17:20:12 2000 @@ -35,6 +35,7 @@ * cpu.c */ int acpi_cpu_init(void); +u32 acpi_read_pm_timer(void); extern unsigned long acpi_c2_exit_latency; extern unsigned long acpi_c3_exit_latency; @@ -50,8 +51,11 @@ * ec.c */ int acpi_ec_init(void); -int acpi_ec_read(int addr, int *value); -int acpi_ec_write(int addr, int value); + +/* + * cmbatt.c + */ +int acpi_cmbatt_init(void); /* * sys.c @@ -62,54 +66,10 @@ extern volatile acpi_sstate_t acpi_sleep_state; /* - * tables.c - */ -extern struct acpi_facp acpi_facp; - -int acpi_load_tables(void); - -/* - * access ACPI registers + * table.c */ +extern FADT_DESCRIPTOR acpi_fadt; -extern inline u32 -acpi_read_pm1_control(struct acpi_facp *facp) -{ - u32 value = 0; - if (facp->pm1a_cnt) - value = inw(facp->pm1a_cnt); - if (facp->pm1b_cnt) - value |= inw(facp->pm1b_cnt); - return value; -} - -extern inline void -acpi_write_pm1_control(struct acpi_facp *facp, u32 value) -{ - if (facp->pm1a_cnt) - outw(value, facp->pm1a_cnt); - if (facp->pm1b_cnt) - outw(value, facp->pm1b_cnt); -} - -extern inline u32 -acpi_read_pm1_status(struct acpi_facp *facp) -{ - u32 value = 0; - if (facp->pm1a_evt) - value = inw(facp->pm1a_evt); - if (facp->pm1b_evt) - value |= inw(facp->pm1b_evt); - return value; -} - -extern inline void -acpi_write_pm1_status(struct acpi_facp *facp, u32 value) -{ - if (facp->pm1a_evt) - outw(value, facp->pm1a_evt); - if (facp->pm1b_evt) - outw(value, facp->pm1b_evt); -} +int acpi_find_and_load_tables(u64 rsdp); #endif /* __DRIVER_H */ diff -urN linux-2.4.0-test12/drivers/acpi/ec.c linux-2.4.0-test12-lia/drivers/acpi/ec.c --- linux-2.4.0-test12/drivers/acpi/ec.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/ec.c Wed Nov 15 16:25:04 2000 @@ -1,21 +1,21 @@ /* - * ec.c - Embedded controller support + * ec.c - Embedded controller support * - * Copyright (C) 2000 Andrew Henroid + * Copyright (C) 2000 Andrew Henroid * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -31,7 +31,7 @@ #define _COMPONENT OS_DEPENDENT MODULE_NAME ("ec") -#define ACPI_EC_HID "PNP0A09" +#define ACPI_EC_HID "PNP0C09" enum { @@ -52,9 +52,15 @@ ACPI_EC_QUERY = 0x84, }; +struct ec_context +{ + u32 gpe_bit; + ACPI_IO_ADDRESS status_port; + ACPI_IO_ADDRESS data_port; + u32 need_global_lock; +}; + -static int acpi_ec_data = 0; -static int acpi_ec_status = 0; static DECLARE_WAIT_QUEUE_HEAD(acpi_ec_wait); /* @@ -64,6 +70,7 @@ acpi_ec_gpe(void *context) { printk(KERN_INFO "ACPI: EC GPE\n"); + /* TODO fix this to use per-device sem */ if (waitqueue_active(&acpi_ec_wait)) wake_up_interruptible(&acpi_ec_wait); } @@ -72,28 +79,36 @@ * wait for read/write status to clear */ static void -acpi_ec_wait_control(void) +acpi_ec_wait_control(struct ec_context *ec_cxt) { - udelay(1); - while(inb(acpi_ec_status) & ACPI_EC_IBF) - udelay(10); + udelay(1); + while(inb(ec_cxt->status_port) & ACPI_EC_IBF) + udelay(10); } /* * read a byte from the EC */ int -acpi_ec_read(int addr, int *value) +acpi_ec_read(struct ec_context *ec_cxt, + int addr, + int *value) { - if (!acpi_ec_data || !acpi_ec_status) + if (!ec_cxt->data_port || !ec_cxt->status_port) return -1; - outb(ACPI_EC_READ, acpi_ec_status); - acpi_ec_wait_control(); - outb(addr, acpi_ec_data); - acpi_ec_wait_control(); - interruptible_sleep_on(&acpi_ec_wait); - *value = inb(acpi_ec_data); + if (ec_cxt->need_global_lock) + acpi_acquire_global_lock(); + + outb(ACPI_EC_READ, ec_cxt->status_port); + acpi_ec_wait_control(ec_cxt); + outb(addr, ec_cxt->data_port); + acpi_ec_wait_control(ec_cxt); + /*interruptible_sleep_on(&acpi_ec_wait);*/ + *value = inb(ec_cxt->data_port); + + if (ec_cxt->need_global_lock) + acpi_release_global_lock(); return 0; } @@ -102,38 +117,95 @@ * write a byte to the EC */ int -acpi_ec_write(int addr, int value) +acpi_ec_write(struct ec_context *ec_cxt, + int addr, + int value) { - if (!acpi_ec_data || !acpi_ec_status) + if (!ec_cxt->data_port || !ec_cxt->status_port) return -1; - outb(ACPI_EC_WRITE, acpi_ec_status); - acpi_ec_wait_control(); - outb(addr, acpi_ec_data); - acpi_ec_wait_control(); - outb(value, acpi_ec_data); - acpi_ec_wait_control(); - interruptible_sleep_on(&acpi_ec_wait); + if (ec_cxt->need_global_lock) + acpi_acquire_global_lock(); + + outb(ACPI_EC_WRITE, ec_cxt->status_port); + acpi_ec_wait_control(ec_cxt); + outb(addr, ec_cxt->data_port); + acpi_ec_wait_control(ec_cxt); + outb(value, ec_cxt->data_port); + acpi_ec_wait_control(ec_cxt); + /*interruptible_sleep_on(&acpi_ec_wait);*/ + + if (ec_cxt->need_global_lock) + acpi_release_global_lock(); return 0; } +static ACPI_STATUS +acpi_ec_region_setup ( + ACPI_HANDLE handle, + u32 function, + void *handler_context, + void **region_context) +{ + FUNCTION_TRACE("acpi_ec_region_setup"); + + printk("acpi_ec_region_setup\n"); + + if (function == ACPI_REGION_DEACTIVATE) + { + if (*region_context) + { + acpi_cm_free (*region_context); + *region_context = NULL; + } + + return_ACPI_STATUS (AE_OK); + } + + *region_context = NULL; + + return_ACPI_STATUS (AE_OK); +} + +static ACPI_STATUS +acpi_ec_region_handler (u32 function, + ACPI_PHYSICAL_ADDRESS address, + u32 bitwidth, + u32 *value, + void *handler_context, + void *region_context) +{ + struct ec_context *ec_cxt; + + FUNCTION_TRACE("acpi_ec_region_handler"); + + ec_cxt = handler_context; + + if (function == ADDRESS_SPACE_READ) { + *value = 0; + acpi_ec_read(ec_cxt, address, value); + /*printk("EC read %x from %x\n", *value, address);*/ + } + else { + acpi_ec_write(ec_cxt, address, *value); + /*printk("EC write value %x to %x\n", *value, address);*/ + } + + return_ACPI_STATUS (AE_OK); +} + /* * Get Embedded Controller information */ static ACPI_STATUS -acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +acpi_found_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value) { - ACPI_DEVICE_INFO dev_info; + ACPI_STATUS status; ACPI_OBJECT obj; ACPI_BUFFER buf; RESOURCE *res; - int gpe; - - if (!ACPI_SUCCESS(acpi_get_object_info(handle, &dev_info)) - || !(dev_info.valid & ACPI_VALID_HID) - || 0 != STRCMP(dev_info.hardware_id, ACPI_EC_HID)) - return AE_OK; + struct ec_context *ec_cxt; buf.length = 0; buf.pointer = NULL; @@ -142,40 +214,72 @@ buf.pointer = kmalloc(buf.length, GFP_KERNEL); if (!buf.pointer) - return AE_OK; + return AE_NO_MEMORY; if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) { kfree(buf.pointer); return AE_OK; } + ec_cxt = kmalloc(sizeof(struct ec_context), GFP_KERNEL); + if (!ec_cxt) { + kfree(buf.pointer); + return AE_NO_MEMORY; + } + res = (RESOURCE*) buf.pointer; - acpi_ec_data = (int) res->data.io.min_base_address; - res = (RESOURCE*)((u8*) buf.pointer + res->length); - acpi_ec_status = (int) res->data.io.min_base_address; + ec_cxt->data_port = res->data.io.min_base_address; + res = NEXT_RESOURCE(res); + ec_cxt->status_port = (int) res->data.io.min_base_address; kfree(buf.pointer); + /* determine GPE bit */ + /* BUG: in acpi 2.0 this could return a package */ buf.length = sizeof(obj); buf.pointer = &obj; if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf)) || obj.type != ACPI_TYPE_NUMBER) return AE_OK; - gpe = (int) obj.number.value; - printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,%d)\n", - acpi_ec_data, acpi_ec_status, gpe); + ec_cxt->gpe_bit = obj.number.value; + + /* determine if we need the Global Lock when accessing */ + buf.length = sizeof(obj); + buf.pointer = &obj; + + status = acpi_evaluate_object(handle, "_GLK", NULL, &buf); + if (status == AE_NOT_FOUND) + ec_cxt->need_global_lock = 0; + else if (!ACPI_SUCCESS(status) || obj.type != ACPI_TYPE_NUMBER) { + DEBUG_PRINT(ACPI_ERROR, ("_GLK failed\n")); + return AE_OK; + } + + ec_cxt->need_global_lock = obj.number.value; + + printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,gpe %d GL %d)\n", + ec_cxt->data_port, ec_cxt->status_port, ec_cxt->gpe_bit, + ec_cxt->need_global_lock); if (!ACPI_SUCCESS(acpi_install_gpe_handler( - gpe, + ec_cxt->gpe_bit, (ACPI_EVENT_LEVEL_TRIGGERED | ACPI_EVENT_EDGE_TRIGGERED), acpi_ec_gpe, NULL))) { - DEBUG_PRINT(ACPI_ERROR, ("Could not install GPE handler for EC.\n")); + REPORT_ERROR(("Could not install GPE handler for EC.\n")); return AE_OK; } + + status = acpi_install_address_space_handler (handle, ADDRESS_SPACE_EC, + acpi_ec_region_handler, acpi_ec_region_setup, ec_cxt); + + if (!ACPI_SUCCESS(status)) { + REPORT_ERROR(("Could not install EC address " + "space handler, error %s\n", acpi_cm_format_exception (status))); + } return AE_OK; } @@ -183,11 +287,19 @@ int acpi_ec_init(void) { - acpi_walk_namespace(ACPI_TYPE_DEVICE, - ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - acpi_find_ec, - NULL, - NULL); + acpi_get_devices(ACPI_EC_HID, + acpi_found_ec, + NULL, + NULL); + + return 0; +} + +int +acpi_ec_terminate(void) +{ + /* TODO */ + /* walk list of EC's */ + /* free their context and release resources */ return 0; } diff -urN linux-2.4.0-test12/drivers/acpi/events/Makefile linux-2.4.0-test12-lia/drivers/acpi/events/Makefile --- linux-2.4.0-test12/drivers/acpi/events/Makefile Fri Sep 15 18:21:43 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/events/evevent.c linux-2.4.0-test12-lia/drivers/acpi/events/evevent.c --- linux-2.4.0-test12/drivers/acpi/events/evevent.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evevent.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: evevent - Fixed and General Purpose Acpi_event * handling and dispatch - * $Revision: 13 $ + * $Revision: 26 $ * *****************************************************************************/ @@ -34,6 +34,86 @@ MODULE_NAME ("evevent") +/************************************************************************** + * + * FUNCTION: Acpi_ev_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly + * configured, disables SCI event sources, installs the SCI + * handler + * + *************************************************************************/ + +ACPI_STATUS +acpi_ev_initialize ( + void) +{ + ACPI_STATUS status; + + + /* Make sure we've got ACPI tables */ + + if (!acpi_gbl_DSDT) { + return (AE_NO_ACPI_TABLES); + } + + + /* Make sure the BIOS supports ACPI mode */ + + if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { + return (AE_ERROR); + } + + + acpi_gbl_original_mode = acpi_hw_get_mode(); + + /* + * Initialize the Fixed and General Purpose Acpi_events prior. This is + * done prior to enabling SCIs to prevent interrupts from occuring + * before handers are installed. + */ + + status = acpi_ev_fixed_event_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + + status = acpi_ev_gpe_initialize (); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Install the SCI handler */ + + status = acpi_ev_install_sci_handler (); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* Install handlers for control method GPE handlers (_Lxx, _Exx) */ + + status = acpi_ev_init_gpe_control_methods (); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Install the handler for the Global Lock */ + + status = acpi_ev_init_global_lock_handler (); + if (ACPI_FAILURE (status)) { + return (status); + } + + + return (status); +} + + /****************************************************************************** * * FUNCTION: Acpi_ev_fixed_event_initialize @@ -58,16 +138,11 @@ acpi_gbl_fixed_event_handlers[i].context = NULL; } - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_PMTIMER + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_GLOBAL + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_POWER_BUTTON + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_SLEEP_BUTTON + - TMR_EN, 0); - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_RTC + - TMR_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, TMR_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, GBL_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, PWRBTN_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, SLPBTN_EN, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, RTC_EN, 0); return (AE_OK); } @@ -89,25 +164,17 @@ acpi_ev_fixed_event_detect(void) { u32 int_status = INTERRUPT_NOT_HANDLED; - u32 status_register = 0; - u32 enable_register = 0; + u32 status_register; + u32 enable_register; /* * Read the fixed feature status and enable registers, as all the cases * depend on their values. */ - status_register = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk); - if (acpi_gbl_FACP->pm1b_evt_blk) { - status_register |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk); - } + status_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); + enable_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); - enable_register = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); - if (acpi_gbl_FACP->pm1b_evt_blk) { - enable_register |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); - } /* power management timer roll over */ @@ -162,20 +229,53 @@ acpi_ev_fixed_event_dispatch ( u32 event) { + u32 register_id; + /* Clear the status bit */ - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, TMR_STS + - event, 1); + switch (event) + { + case ACPI_EVENT_PMTIMER: + register_id = TMR_STS; + break; + + case ACPI_EVENT_GLOBAL: + register_id = GBL_STS; + break; + + case ACPI_EVENT_POWER_BUTTON: + register_id = PWRBTN_STS; + break; + + case ACPI_EVENT_SLEEP_BUTTON: + register_id = SLPBTN_STS; + break; + + case ACPI_EVENT_RTC: + register_id = RTC_STS; + break; + + default: + return 0; + break; + } + + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, register_id, 1); /* * Make sure we've got a handler. If not, report an error. * The event is disabled to prevent further interrupts. */ if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, - TMR_EN + event, 0); + register_id = (PM1_EN | REGISTER_BIT_ID(register_id)); + + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, + register_id, 0); + + REPORT_ERROR ( + ("Ev_gpe_dispatch: No installed handler for fixed event [0x%08X]\n", + event)); - REPORT_ERROR("No installed handler for fixed event."); return (INTERRUPT_NOT_HANDLED); } @@ -210,15 +310,28 @@ /* - * Setup various GPE counts + * Set up various GPE counts + * + * You may ask,why are the GPE register block lengths divided by 2? + * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event + * Registers, we have, + * + * "Each register block contains two registers of equal length + * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the + * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN + * The length of the GPE1_STS and GPE1_EN registers is equal to + * half the GPE1_LEN. If a generic register block is not supported + * then its respective block pointer and block length values in the + * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need + * to be the same size." */ - gpe0register_count = (u16) DIV_2 (acpi_gbl_FACP->gpe0blk_len); - gpe1_register_count = (u16) DIV_2 (acpi_gbl_FACP->gpe1_blk_len); + gpe0register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); + gpe1_register_count = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count; if (!acpi_gbl_gpe_register_count) { - REPORT_WARNING ("No GPEs defined in the FACP"); + REPORT_WARNING (("Zero GPEs are defined in the FADT\n")); return (AE_OK); } @@ -262,10 +375,10 @@ for (i = 0; i < gpe0register_count; i++) { acpi_gbl_gpe_registers[register_index].status_addr = - (u16) (acpi_gbl_FACP->gpe0blk + i); + (u16) (acpi_gbl_FADT->Xgpe0blk.address + i); acpi_gbl_gpe_registers[register_index].enable_addr = - (u16) (acpi_gbl_FACP->gpe0blk + i + gpe0register_count); + (u16) (acpi_gbl_FADT->Xgpe0blk.address + i + gpe0register_count); acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i); @@ -289,13 +402,13 @@ for (i = 0; i < gpe1_register_count; i++) { acpi_gbl_gpe_registers[register_index].status_addr = - (u16) (acpi_gbl_FACP->gpe1_blk + i); + (u16) (acpi_gbl_FADT->Xgpe1_blk.address + i); acpi_gbl_gpe_registers[register_index].enable_addr = - (u16) (acpi_gbl_FACP->gpe1_blk + i + gpe1_register_count); + (u16) (acpi_gbl_FADT->Xgpe1_blk.address + i + gpe1_register_count); acpi_gbl_gpe_registers[register_index].gpe_base = - (u8) (acpi_gbl_FACP->gpe1_base + MUL_8 (i)); + (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i)); for (j = 0; j < 8; j++) { gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j; @@ -339,7 +452,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ev_save_method_info ( ACPI_HANDLE obj_handle, u32 level, @@ -446,29 +559,6 @@ /****************************************************************************** * - * FUNCTION: Acpi_ev_gpe_cleanup - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Cleanup in preparation for unload. - * - ******************************************************************************/ - -void -acpi_ev_gpe_cleanup (void) -{ - - acpi_cm_free (acpi_gbl_gpe_registers); - acpi_cm_free (acpi_gbl_gpe_info); - - return; -} - - -/****************************************************************************** - * * FUNCTION: Acpi_ev_gpe_detect * * PARAMETERS: None @@ -549,7 +639,7 @@ * ******************************************************************************/ -void +static void acpi_ev_asynch_execute_gpe_method ( void *context) { @@ -564,20 +654,11 @@ acpi_cm_release_mutex (ACPI_MTX_EVENTS); /* - * Function Handler (e.g. EC): - * --------------------------- - * Execute the installed function handler to handle this event. - */ - if (gpe_info.handler) { - gpe_info.handler (gpe_info.context); - } - - /* * Method Handler (_Lxx, _Exx): * ---------------------------- * Acpi_evaluate the _Lxx/_Exx control method that corresponds to this GPE. */ - else if (gpe_info.method_handle) { + if (gpe_info.method_handle) { acpi_ns_evaluate_by_handle (gpe_info.method_handle, NULL, NULL); } @@ -588,7 +669,7 @@ * that edge-triggered events are cleared prior to calling (via DPC) * this function. */ - if (gpe_info.type | ACPI_EVENT_LEVEL_TRIGGERED) { + if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { acpi_hw_clear_gpe (gpe_number); } @@ -645,7 +726,7 @@ * level-triggered events are cleared after the GPE is serviced * (see Acpi_ev_asynch_execute_gpe_method). */ - if (acpi_gbl_gpe_info [gpe_number].type | ACPI_EVENT_EDGE_TRIGGERED) { + if (acpi_gbl_gpe_info[gpe_number].type & ACPI_EVENT_EDGE_TRIGGERED) { acpi_hw_clear_gpe (gpe_number); } @@ -655,9 +736,7 @@ * Queue the handler, which is either an installable function handler * (e.g. EC) or a control method (e.g. _Lxx/_Exx) for later execution. */ - if (acpi_gbl_gpe_info [gpe_number].handler || - acpi_gbl_gpe_info [gpe_number].method_handle) - { + if (acpi_gbl_gpe_info[gpe_number].method_handle) { if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE, acpi_ev_asynch_execute_gpe_method, (void*)(NATIVE_UINT)gpe_number))) @@ -667,10 +746,27 @@ * the GPE will remain disabled until the ACPI Core Subsystem * is restarted, or the handler is removed/reinstalled. */ - REPORT_ERROR ("Unable to queue-up handler for GPE."); + REPORT_ERROR ( + ("Ev_gpe_dispatch: Unable to queue the handler for GPE [0x%08X]\n", + gpe_number)); } } + else if (acpi_gbl_gpe_info[gpe_number].handler) { + ACPI_GPE_LEVEL_INFO gpe_info; + /* + * Function Handler (e.g. EC): + * --------------------------- + * Execute the installed function handler to handle this event. + * Without queueing. + */ + acpi_cm_acquire_mutex (ACPI_MTX_EVENTS); + gpe_info = acpi_gbl_gpe_info [gpe_number]; + acpi_cm_release_mutex (ACPI_MTX_EVENTS); + if (gpe_info.handler) { + gpe_info.handler (gpe_info.context); + } + } /* * Non Handled GPEs: * ----------------- @@ -678,7 +774,9 @@ * is registered for them. */ else { - REPORT_ERROR ("No installed handler for GPE."); + REPORT_ERROR ( + ("Ev_gpe_dispatch: No installed handler for GPE [0x%08X]\n", + gpe_number)); } return (INTERRUPT_HANDLED); diff -urN linux-2.4.0-test12/drivers/acpi/events/evmisc.c linux-2.4.0-test12-lia/drivers/acpi/events/evmisc.c --- linux-2.4.0-test12/drivers/acpi/events/evmisc.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evmisc.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: evmisc - ACPI device notification handler dispatch * and ACPI Global Lock support - * $Revision: 13 $ + * $Revision: 19 $ * *****************************************************************************/ @@ -157,7 +157,7 @@ * **************************************************************************/ -void +static void acpi_ev_global_lock_thread ( void *context) { @@ -185,7 +185,7 @@ * **************************************************************************/ -u32 +static u32 acpi_ev_global_lock_handler ( void *context) { @@ -199,7 +199,7 @@ * take another interrupt when it becomes free. */ - global_lock = &acpi_gbl_FACS->global_lock; + global_lock = acpi_gbl_FACS->global_lock; ACPI_ACQUIRE_GLOBAL_LOCK (global_lock, acquired); if (acquired) { /* Got the lock, now wake all threads waiting for it */ @@ -275,9 +275,9 @@ } - /* We must acquire the actualy hardware lock */ + /* We must acquire the actual hardware lock */ - global_lock = &acpi_gbl_FACS->global_lock; + global_lock = acpi_gbl_FACS->global_lock; ACPI_ACQUIRE_GLOBAL_LOCK (global_lock, acquired); if (acquired) { /* We got the lock */ @@ -298,11 +298,8 @@ * Since this wait will block, we must release the interpreter */ - acpi_aml_exit_interpreter (); status = acpi_aml_system_wait_semaphore (acpi_gbl_global_lock_semaphore, ACPI_UINT32_MAX); - acpi_aml_enter_interpreter (); - return (status); } @@ -323,7 +320,8 @@ void *global_lock; - if (!acpi_gbl_FACS) { + if (!acpi_gbl_global_lock_thread_count) { + REPORT_WARNING(("Releasing a non-acquired Global Lock\n")); return; } @@ -331,7 +329,6 @@ acpi_gbl_global_lock_thread_count--; - /* Have all threads released the lock? */ if (!acpi_gbl_global_lock_thread_count) { @@ -340,7 +337,7 @@ * release */ - global_lock = &acpi_gbl_FACS->global_lock; + global_lock = acpi_gbl_FACS->global_lock; ACPI_RELEASE_GLOBAL_LOCK (global_lock, pending); acpi_gbl_global_lock_acquired = FALSE; @@ -349,8 +346,8 @@ * register */ if (pending) { - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, - PM1_CONTROL | GBL_RLS, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, + GBL_RLS, 1); } } diff -urN linux-2.4.0-test12/drivers/acpi/events/evregion.c linux-2.4.0-test12-lia/drivers/acpi/events/evregion.c --- linux-2.4.0-test12/drivers/acpi/events/evregion.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evregion.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * - * Module Name: evregion - ACPI Address_space / Op_region handler dispatch - * $Revision: 76 $ + * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch + * $Revision: 88 $ * *****************************************************************************/ @@ -34,202 +34,6 @@ MODULE_NAME ("evregion") -#define PCI_ROOT_HID_STRING "PNP0A03" -#define PCI_ROOT_HID_VALUE 0x030AD041 /* EISAID("PNP0A03") */ - - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_find_one_pci_root_bus - * - * PARAMETERS: - * - * RETURN: None - * - * DESCRIPTION: - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_find_one_pci_root_bus ( - ACPI_HANDLE obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - ACPI_NAMESPACE_NODE *node; - ACPI_OPERAND_OBJECT *obj_desc; - ACPI_STATUS status; - - - node = (ACPI_NAMESPACE_NODE *) obj_handle; - obj_desc = ((ACPI_NAMESPACE_NODE *) obj_handle)->object; - - - /* - * We are looking for all valid _HID objects. - */ - - if (STRNCMP ((NATIVE_CHAR *) &node->name, METHOD_NAME__HID, ACPI_NAME_SIZE) || - (!obj_desc)) - { - return (AE_OK); - } - - - /* - * Found an _HID object. - * Now we need a HID with the value EISAID("PNP0A03") - * HID can be either a number or a string. - */ - - switch (obj_desc->common.type) - { - case ACPI_TYPE_NUMBER: - - if (obj_desc->number.value != PCI_ROOT_HID_VALUE) { - return (AE_OK); - } - - break; - - case ACPI_TYPE_STRING: - - if (STRNCMP (obj_desc->string.pointer, PCI_ROOT_HID_STRING, - sizeof (PCI_ROOT_HID_STRING))) - { - return (AE_OK); - } - - break; - - default: - - return (AE_OK); - } - - - /* - * We found a valid PCI_ROOT_HID. - * The parent of the HID entry is the PCI device; Install the default PCI - * handler for this PCI device. - */ - - status = acpi_install_address_space_handler (acpi_ns_get_parent_object (node), - ADDRESS_SPACE_PCI_CONFIG, - ACPI_DEFAULT_HANDLER, NULL, NULL); - - return (AE_OK); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_find_pci_root_buses - * - * PARAMETERS: - * - * RETURN: None - * - * DESCRIPTION: - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_find_pci_root_buses ( - void) -{ - - acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - FALSE, acpi_ev_find_one_pci_root_bus, NULL, NULL); - - return (AE_OK); -} - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_init_one_device - * - * PARAMETERS: The usual "I'm a namespace callback" stuff - * - * RETURN: ACPI_STATUS - * - * DESCRIPTION: This is called once per device soon after ACPI is enabled - * to initialize each device. It determines if the device is - * present, and if so, calls _INI. - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_init_one_device ( - ACPI_HANDLE obj_handle, - u32 nesting_level, - void *context, - void **return_value) -{ - ACPI_STATUS status; - ACPI_OPERAND_OBJECT *ret_obj; - - - /* - * Run _STA to determine if we can run _INI on the device. - */ - status = acpi_ns_evaluate_relative(obj_handle, "_STA", NULL, &ret_obj); - if (AE_NOT_FOUND == status) { - /* No _STA means device is present */ - } - else if (ACPI_FAILURE (status)) { - return (status); - } - else if (ret_obj) { - if (ACPI_TYPE_NUMBER != ret_obj->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - - /* - * if _STA "present" bit not set, we're done. - */ - if (!(ret_obj->number.value & 1)) { - goto cleanup; - } - } - - /* - * The device is present. Run _INI. - */ - - status = acpi_ns_evaluate_relative(obj_handle, "_INI", NULL, NULL); - -cleanup: - - acpi_cm_remove_reference (ret_obj); - return (status); -} - -/****************************************************************************** - * - * FUNCTION: Acpi_ev_init_devices - * - * PARAMETERS: None - * - * RETURN: ACPI_STATUS - * - * DESCRIPTION: This initializes all ACPI devices. - * - *****************************************************************************/ - -ACPI_STATUS -acpi_ev_init_devices ( - void) -{ - acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - FALSE, acpi_ev_init_one_device, NULL, NULL); - - return (AE_OK); -} - - /************************************************************************** * * FUNCTION: Acpi_ev_install_default_address_space_handlers @@ -250,23 +54,45 @@ /* - * NOTE: All address spaces (PCI Config, EC, SMBus) are scope dependent - * and registration must occur for a specific device. In the case - * system memory and IO address spaces there is currently no device - * associated with the address space. For these we use the root. + * All address spaces (PCI Config, EC, SMBus) are scope dependent + * and registration must occur for a specific device. In the case + * system memory and IO address spaces there is currently no device + * associated with the address space. For these we use the root. + * We install the default PCI config space handler at the root so + * that this space is immediately available even though the we have + * not enumerated all the PCI Root Buses yet. This is to conform + * to the ACPI specification which states that the PCI config + * space must be always available -- even though we are nowhere + * near ready to find the PCI root buses at this point. + * + * NOTE: We ignore AE_EXIST because this means that a handler has + * already been installed (via Acpi_install_address_space_handler) */ status = acpi_install_address_space_handler (acpi_gbl_root_node, ADDRESS_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL); - if (ACPI_FAILURE (status)) { + if ((ACPI_FAILURE (status)) && + (status != AE_EXIST)) + { return (status); } status = acpi_install_address_space_handler (acpi_gbl_root_node, ADDRESS_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL); - if (ACPI_FAILURE (status)) { + if ((ACPI_FAILURE (status)) && + (status != AE_EXIST)) + { + return (status); + } + + status = acpi_install_address_space_handler (acpi_gbl_root_node, + ADDRESS_SPACE_PCI_CONFIG, + ACPI_DEFAULT_HANDLER, NULL, NULL); + if ((ACPI_FAILURE (status)) && + (status != AE_EXIST)) + { return (status); } @@ -275,7 +101,7 @@ } -/* TBD: [Restructure] Move to the methods directory */ +/* TBD: [Restructure] Move elsewhere */ /************************************************************************** * @@ -290,7 +116,7 @@ * *************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ev_execute_reg_method ( ACPI_OPERAND_OBJECT *region_obj, u32 function) @@ -301,7 +127,7 @@ ACPI_STATUS status; - if (region_obj->region.REGmethod == NULL) { + if (region_obj->region.extra->extra.method_REG == NULL) { return (AE_OK); } @@ -337,7 +163,7 @@ /* * Execute the method, no return value */ - status = acpi_ns_evaluate_by_handle (region_obj->region.REGmethod, params, NULL); + status = acpi_ns_evaluate_by_handle (region_obj->region.extra->extra.method_REG, params, NULL); return (status); } @@ -364,7 +190,7 @@ acpi_ev_address_space_dispatch ( ACPI_OPERAND_OBJECT *region_obj, u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value) { @@ -381,7 +207,7 @@ handler_desc = region_obj->region.addr_handler; if (!handler_desc) { - return(AE_EXIST); + return(AE_NOT_EXIST); } /* @@ -421,11 +247,13 @@ return(status); } + region_obj->region.flags |= AOPOBJ_INITIALIZED; + /* * Save the returned context for use in all accesses to * this particular region. */ - region_obj->region.region_context = region_context; + region_obj->region.extra->extra.region_context = region_context; } /* @@ -447,7 +275,7 @@ */ status = handler (function, address, bit_width, value, handler_desc->addr_handler.context, - region_obj->region.region_context); + region_obj->region.extra->extra.region_context); if (!(handler_desc->addr_handler.flags & ADDR_HANDLER_DEFAULT_INSTALLED)) { @@ -462,7 +290,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_ev_disassociate_region_and_handler + * FUNCTION: Acpi_ev_disassociate_region_from_handler * * PARAMETERS: Handler_obj - Handler Object * Region_obj - Region Object @@ -482,10 +310,12 @@ ACPI_OPERAND_OBJECT *obj_desc; ACPI_OPERAND_OBJECT **last_obj_ptr; ADDRESS_SPACE_SETUP region_setup; - void *region_context = region_obj->region.region_context; + void *region_context; ACPI_STATUS status; + region_context = region_obj->region.extra->extra.region_context; + /* * Get the address handler from the region object */ @@ -533,6 +363,8 @@ /* * Init routine may fail, Just ignore errors */ + + region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); /* * Remove handler reference in the region diff -urN linux-2.4.0-test12/drivers/acpi/events/evrgnini.c linux-2.4.0-test12-lia/drivers/acpi/events/evrgnini.c --- linux-2.4.0-test12/drivers/acpi/events/evrgnini.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evrgnini.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * - * Module Name: evrgnini- ACPI Address_space / Op_region init - * $Revision: 22 $ + * Module Name: evrgnini- ACPI Address_space (Op_region) init + * $Revision: 29 $ * *****************************************************************************/ @@ -56,12 +56,8 @@ void *handler_context, void **region_context) { - ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - if (function == ACPI_REGION_DEACTIVATE) { - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); - if (*region_context) { acpi_cm_free (*region_context); *region_context = NULL; @@ -77,10 +73,6 @@ return (AE_NO_MEMORY); } - /* Init. (Mapping fields are all set to zeros above) */ - - region_obj->region.flags |= AOPOBJ_INITIALIZED; - return (AE_OK); } @@ -107,15 +99,11 @@ void *handler_context, void **region_context) { - ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - if (function == ACPI_REGION_DEACTIVATE) { *region_context = NULL; - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); } else { *region_context = handler_context; - region_obj->region.flags |= AOPOBJ_INITIALIZED; } return (AE_OK); @@ -135,7 +123,7 @@ * * DESCRIPTION: Do any prep work for region handling * - * MUTEX: Assumes namespace is locked + * MUTEX: Assumes namespace is not locked * ****************************************************************************/ @@ -147,12 +135,12 @@ void **region_context) { ACPI_STATUS status = AE_OK; - u32 temp; + ACPI_INTEGER temp; PCI_HANDLER_CONTEXT *pci_context = *region_context; ACPI_OPERAND_OBJECT *handler_obj; ACPI_NAMESPACE_NODE *node; ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - + DEVICE_ID object_hID; handler_obj = region_obj->region.addr_handler; @@ -161,12 +149,10 @@ * No installed handler. This shouldn't happen because the dispatch * routine checks before we get here, but we check again just in case. */ - return(AE_EXIST); + return(AE_NOT_EXIST); } if (function == ACPI_REGION_DEACTIVATE) { - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); - if (pci_context) { acpi_cm_free (pci_context); *region_context = NULL; @@ -197,8 +183,6 @@ node = acpi_ns_get_parent_object (region_obj->region.node); - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); - /* Acpi_evaluate the _ADR object */ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp); @@ -210,7 +194,7 @@ /* * Got it.. */ - pci_context->dev_func = temp; + pci_context->dev_func = (u32) temp; } /* @@ -221,14 +205,43 @@ * This is the device the handler has been registered to handle. */ - node = handler_obj->addr_handler.node; + /* + * If the Addr_handler.Node is still pointing to the root, we need + * to scan upward for a PCI Root bridge and re-associate the Op_region + * handlers with that device. + */ + if (handler_obj->addr_handler.node == acpi_gbl_root_node) { + /* + * Node is currently the parent object + */ + while (node != acpi_gbl_root_node) { + status = acpi_cm_execute_HID(node, &object_hID); + + if (ACPI_SUCCESS (status)) { + if (!(STRNCMP(object_hID.buffer, PCI_ROOT_HID_STRING, + sizeof (PCI_ROOT_HID_STRING)))) + { + acpi_install_address_space_handler(node, + ADDRESS_SPACE_PCI_CONFIG, + ACPI_DEFAULT_HANDLER, NULL, NULL); + + break; + } + } + + node = acpi_ns_get_parent_object(node); + } + } + else { + node = handler_obj->addr_handler.node; + } status = acpi_cm_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp); if (ACPI_SUCCESS (status)) { /* * Got it.. */ - pci_context->seg = temp; + pci_context->seg = (u32) temp; } status = acpi_cm_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp); @@ -236,15 +249,11 @@ /* * Got it.. */ - pci_context->bus = temp; + pci_context->bus = (u32) temp; } *region_context = pci_context; - acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - - region_obj->region.flags |= AOPOBJ_INITIALIZED; - return (AE_OK); } @@ -271,16 +280,11 @@ void *handler_context, void **region_context) { - ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle; - - if (function == ACPI_REGION_DEACTIVATE) { *region_context = NULL; - region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); } else { *region_context = handler_context; - region_obj->region.flags |= AOPOBJ_INITIALIZED; } return (AE_OK); @@ -332,7 +336,7 @@ space_id = region_obj->region.space_id; region_obj->region.addr_handler = NULL; - region_obj->region.REGmethod = NULL; + region_obj->region.extra->extra.method_REG = NULL; region_obj->region.flags &= ~(AOPOBJ_INITIALIZED); /* @@ -346,7 +350,7 @@ * definition. This will be executed when the handler is attached * or removed */ - region_obj->region.REGmethod = method_node; + region_obj->region.extra->extra.method_REG = method_node; } /* diff -urN linux-2.4.0-test12/drivers/acpi/events/evsci.c linux-2.4.0-test12-lia/drivers/acpi/events/evsci.c --- linux-2.4.0-test12/drivers/acpi/events/evsci.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evsci.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: evsci - System Control Interrupt configuration and * legacy to ACPI mode state transition functions - * $Revision: 59 $ + * $Revision: 67 $ * ******************************************************************************/ @@ -48,7 +48,7 @@ * * FUNCTION: Acpi_ev_sci_handler * - * PARAMETERS: none + * PARAMETERS: Context - Calling Context * * RETURN: Status code indicates whether interrupt was handled. * @@ -58,7 +58,7 @@ * ******************************************************************************/ -u32 +static u32 acpi_ev_sci_handler (void *context) { u32 interrupt_handled = INTERRUPT_NOT_HANDLED; @@ -68,7 +68,7 @@ * Make sure that ACPI is enabled by checking SCI_EN. Note that we are * required to treat the SCI interrupt as sharable, level, active low. */ - if (!acpi_hw_register_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) { + if (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) { /* ACPI is not enabled; this interrupt cannot be for us */ return (INTERRUPT_NOT_HANDLED); @@ -110,7 +110,7 @@ u32 except = AE_OK; - except = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FACP->sci_int, + except = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_handler, NULL); @@ -163,7 +163,7 @@ #endif - acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FACP->sci_int, + acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_handler); return (AE_OK); @@ -208,20 +208,11 @@ if (acpi_gbl_restore_acpi_chipset == TRUE) { /* Restore the fixed events */ - if (acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk + 2) != - acpi_gbl_pm1_enable_register_save) - { - acpi_os_out16 ((acpi_gbl_FACP->pm1a_evt_blk + 2), - acpi_gbl_pm1_enable_register_save); - } - - if (acpi_gbl_FACP->pm1b_evt_blk) { - if (acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk + 2) != + if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) != acpi_gbl_pm1_enable_register_save) - { - acpi_os_out16 ((acpi_gbl_FACP->pm1b_evt_blk + 2), - acpi_gbl_pm1_enable_register_save); - } + { + acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN, + acpi_gbl_pm1_enable_register_save); } @@ -232,26 +223,24 @@ /* Now restore the GPEs */ - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe0blk_len); index++) { - if (acpi_os_in8 (acpi_gbl_FACP->gpe0blk + - DIV_2 (acpi_gbl_FACP->gpe0blk_len)) != - acpi_gbl_gpe0enable_register_save[index]) + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { + if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) != + acpi_gbl_gpe0enable_register_save[index]) { - acpi_os_out8 ((acpi_gbl_FACP->gpe0blk + - DIV_2 (acpi_gbl_FACP->gpe0blk_len)), - acpi_gbl_gpe0enable_register_save[index]); + acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index, + acpi_gbl_gpe0enable_register_save[index]); } } - if (acpi_gbl_FACP->gpe1_blk && acpi_gbl_FACP->gpe1_blk_len) { - for (index = 0; index < DIV_2 (acpi_gbl_FACP->gpe1_blk_len); index++) { - if (acpi_os_in8 (acpi_gbl_FACP->gpe1_blk + - DIV_2 (acpi_gbl_FACP->gpe1_blk_len)) != + /* GPE 1 present? */ + + if (acpi_gbl_FADT->gpe1_blk_len) { + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { + if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) != acpi_gbl_gpe1_enable_register_save[index]) { - acpi_os_out8 ((acpi_gbl_FACP->gpe1_blk + - DIV_2 (acpi_gbl_FACP->gpe1_blk_len)), - acpi_gbl_gpe1_enable_register_save[index]); + acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index, + acpi_gbl_gpe1_enable_register_save[index]); } } } diff -urN linux-2.4.0-test12/drivers/acpi/events/evxface.c linux-2.4.0-test12-lia/drivers/acpi/events/evxface.c --- linux-2.4.0-test12/drivers/acpi/events/evxface.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evxface.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evxface - External interfaces for ACPI events - * $Revision: 88 $ + * $Revision: 96 $ * *****************************************************************************/ @@ -81,9 +81,9 @@ acpi_gbl_fixed_event_handlers[event].handler = handler; acpi_gbl_fixed_event_handlers[event].context = context; - if (1 != acpi_hw_register_access (ACPI_WRITE, - ACPI_MTX_LOCK, event + TMR_EN, 1)) - { + status = acpi_enable_event(event, ACPI_EVENT_FIXED); + + if (!ACPI_SUCCESS(status)) { /* Remove the handler */ acpi_gbl_fixed_event_handlers[event].handler = NULL; @@ -131,11 +131,12 @@ /* Disable the event before removing the handler - just in case... */ - if (0 != acpi_hw_register_access (ACPI_WRITE, - ACPI_MTX_LOCK, event + TMR_EN, 0)) - { + status = acpi_disable_event(event, ACPI_EVENT_FIXED); + + if (!ACPI_SUCCESS(status)) { status = AE_ERROR; - goto cleanup; + acpi_cm_release_mutex (ACPI_MTX_EVENTS); + return (status); } /* Remove the handler */ @@ -143,7 +144,6 @@ acpi_gbl_fixed_event_handlers[event].handler = NULL; acpi_gbl_fixed_event_handlers[event].context = NULL; -cleanup: acpi_cm_release_mutex (ACPI_MTX_EVENTS); return (status); } @@ -426,14 +426,14 @@ * * PARAMETERS: Gpe_number - The GPE number. The numbering scheme is * bank 0 first, then bank 1. - * Trigger - Whether this GPE should be treated as an + * Type - Whether this GPE should be treated as an * edge- or level-triggered interrupt. * Handler - Address of the handler * Context - Value passed to the handler on each GPE * * RETURN: Status * - * DESCRIPTION: Install a handler for a General Purpose Acpi_event. + * DESCRIPTION: Install a handler for a General Purpose Event. * ******************************************************************************/ @@ -554,11 +554,9 @@ * DESCRIPTION: Acquire the ACPI Global Lock * ******************************************************************************/ - ACPI_STATUS acpi_acquire_global_lock ( - u32 timeout, - u32 *out_handle) + void) { ACPI_STATUS status; @@ -573,7 +571,6 @@ status = acpi_ev_acquire_global_lock (); acpi_aml_exit_interpreter (); - *out_handle = 0; return (status); } @@ -592,12 +589,8 @@ ACPI_STATUS acpi_release_global_lock ( - u32 handle) + void) { - - - /* TBD: [Restructure] Validate handle */ - acpi_ev_release_global_lock (); return (AE_OK); } diff -urN linux-2.4.0-test12/drivers/acpi/events/evxfevnt.c linux-2.4.0-test12-lia/drivers/acpi/events/evxfevnt.c --- linux-2.4.0-test12/drivers/acpi/events/evxfevnt.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evxfevnt.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable - * $Revision: 19 $ + * $Revision: 26 $ * *****************************************************************************/ @@ -35,14 +35,6 @@ MODULE_NAME ("evxfevnt") -ACPI_STATUS -acpi_ev_find_pci_root_buses ( - void); - -ACPI_STATUS -acpi_ev_init_devices ( - void); - /************************************************************************** * * FUNCTION: Acpi_enable @@ -51,9 +43,7 @@ * * RETURN: Status * - * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly - * configured, disables SCI event sources, installs the SCI - * handler, and transfers the system into ACPI mode. + * DESCRIPTION: Transfers the system into ACPI mode. * *************************************************************************/ @@ -69,52 +59,12 @@ return (AE_NO_ACPI_TABLES); } - /* Init the hardware */ - - /* - * With the advent of a 3-pass parser, we need to be - * prepared to execute on initialized HW before the - * namespace has completed its load. - */ - - status = acpi_cm_hardware_initialize (); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Make sure the BIOS supports ACPI mode */ if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) { return (AE_ERROR); } - - acpi_gbl_original_mode = acpi_hw_get_mode(); - - /* - * Initialize the Fixed and General Purpose Acpi_events prior. This is - * done prior to enabling SCIs to prevent interrupts from occuring - * before handers are installed. - */ - - status = acpi_ev_fixed_event_initialize (); - if (ACPI_FAILURE (status)) { - return (status); - } - - status = acpi_ev_gpe_initialize (); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Install the SCI handler */ - - status = acpi_ev_install_sci_handler (); - if (ACPI_FAILURE (status)) { - return (status); - } - /* Transition to ACPI mode */ status = acpi_hw_set_mode (SYS_MODE_ACPI); @@ -122,32 +72,6 @@ return (status); } - /* Install handlers for control method GPE handlers (_Lxx, _Exx) */ - - acpi_ev_init_gpe_control_methods (); - - status = acpi_ev_init_global_lock_handler (); - - /* - * Perform additional initialization that may cause control methods - * to be executed - * - * It may be wise to move this code to a new interface - */ - - - /* - * Install PCI config space handler for all PCI root bridges. A PCI root - * bridge is found by searching for devices containing a HID with the value - * EISAID("PNP0A03") - */ - - acpi_ev_find_pci_root_buses (); - - /* Call _INI on all devices */ - - acpi_ev_init_devices (); - return (status); } @@ -250,7 +174,12 @@ * enable register bit) */ - acpi_hw_register_access (ACPI_WRITE, TRUE, register_id, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); + + if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { + return (AE_ERROR); + } + break; @@ -344,7 +273,12 @@ * enable register bit) */ - acpi_hw_register_access (ACPI_WRITE, TRUE, register_id, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0); + + if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) { + return (AE_ERROR); + } + break; @@ -435,7 +369,7 @@ * status register bit) */ - acpi_hw_register_access (ACPI_WRITE, TRUE, register_id, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1); break; @@ -532,7 +466,7 @@ /* Get the status of the requested fixed event */ - *event_status = acpi_hw_register_access (ACPI_READ, TRUE, register_id); + *event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id); break; diff -urN linux-2.4.0-test12/drivers/acpi/events/evxfregn.c linux-2.4.0-test12-lia/drivers/acpi/events/evxfregn.c --- linux-2.4.0-test12/drivers/acpi/events/evxfregn.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/events/evxfregn.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and * Address Spaces. - * $Revision: 20 $ + * $Revision: 22 $ * *****************************************************************************/ @@ -43,12 +43,12 @@ * PARAMETERS: Device - Handle for the device * Space_id - The address space ID * Handler - Address of the handler + * Setup - Address of the setup function * Context - Value passed to the handler on each access * * RETURN: Status * - * DESCRIPTION: Install a handler for accesses on an address space controlled - * a specific device. + * DESCRIPTION: Install a handler for all Op_regions of a given Space_id. * ******************************************************************************/ @@ -190,7 +190,7 @@ /* Attach the new object to the Node */ - status = acpi_ns_attach_object (device, obj_desc, (u8) type); + status = acpi_ns_attach_object (node, obj_desc, (u8) type); if (ACPI_FAILURE (status)) { acpi_cm_remove_reference (obj_desc); goto unlock_and_exit; diff -urN linux-2.4.0-test12/drivers/acpi/hardware/Makefile linux-2.4.0-test12-lia/drivers/acpi/hardware/Makefile --- linux-2.4.0-test12/drivers/acpi/hardware/Makefile Fri Sep 15 18:21:43 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/hardware/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/hardware/hwacpi.c linux-2.4.0-test12-lia/drivers/acpi/hardware/hwacpi.c --- linux-2.4.0-test12/drivers/acpi/hardware/hwacpi.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/hardware/hwacpi.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: hwacpi - ACPI hardware functions - mode and timer - * $Revision: 22 $ + * $Revision: 31 $ * *****************************************************************************/ @@ -34,6 +34,147 @@ /****************************************************************************** * + * FUNCTION: Acpi_hw_initialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize and validate various ACPI registers + * + ******************************************************************************/ + +ACPI_STATUS +acpi_hw_initialize ( + void) +{ + ACPI_STATUS status = AE_OK; + u32 index; + + + /* We must have the ACPI tables by the time we get here */ + + if (!acpi_gbl_FADT) { + acpi_gbl_restore_acpi_chipset = FALSE; + + return (AE_NO_ACPI_TABLES); + } + + /* Must support *some* mode! */ +/* + if (!(System_flags & SYS_MODES_MASK)) { + Restore_acpi_chipset = FALSE; + + return (AE_ERROR); + } + +*/ + + + switch (acpi_gbl_system_flags & SYS_MODES_MASK) + { + /* Identify current ACPI/legacy mode */ + + case (SYS_MODE_ACPI): + + acpi_gbl_original_mode = SYS_MODE_ACPI; + break; + + + case (SYS_MODE_LEGACY): + + acpi_gbl_original_mode = SYS_MODE_LEGACY; + break; + + + case (SYS_MODE_ACPI | SYS_MODE_LEGACY): + + if (acpi_hw_get_mode () == SYS_MODE_ACPI) { + acpi_gbl_original_mode = SYS_MODE_ACPI; + } + else { + acpi_gbl_original_mode = SYS_MODE_LEGACY; + } + + break; + } + + + if (acpi_gbl_system_flags & SYS_MODE_ACPI) { + /* Target system supports ACPI mode */ + + /* + * The purpose of this code is to save the initial state + * of the ACPI event enable registers. An exit function will be + * registered which will restore this state when the application + * exits. The exit function will also clear all of the ACPI event + * status bits prior to restoring the original mode. + * + * The location of the PM1a_evt_blk enable registers is defined as the + * base of PM1a_evt_blk + DIV_2(PM1a_evt_blk_length). Since the spec further + * fully defines the PM1a_evt_blk to be a total of 4 bytes, the offset + * for the enable registers is always 2 from the base. It is hard + * coded here. If this changes in the spec, this code will need to + * be modified. The PM1b_evt_blk behaves as expected. + */ + + acpi_gbl_pm1_enable_register_save = (u16) acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN); + + + /* + * The GPEs behave similarly, except that the length of the register + * block is not fixed, so the buffer must be allocated with malloc + */ + + if (acpi_gbl_FADT->Xgpe0blk.address && acpi_gbl_FADT->gpe0blk_len) { + /* GPE0 specified in FADT */ + + acpi_gbl_gpe0enable_register_save = + acpi_cm_allocate (DIV_2 (acpi_gbl_FADT->gpe0blk_len)); + if (!acpi_gbl_gpe0enable_register_save) { + return (AE_NO_MEMORY); + } + + /* Save state of GPE0 enable bits */ + + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { + acpi_gbl_gpe0enable_register_save[index] = + (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index); + } + } + + else { + acpi_gbl_gpe0enable_register_save = NULL; + } + + if (acpi_gbl_FADT->Xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len) { + /* GPE1 defined */ + + acpi_gbl_gpe1_enable_register_save = + acpi_cm_allocate (DIV_2 (acpi_gbl_FADT->gpe1_blk_len)); + if (!acpi_gbl_gpe1_enable_register_save) { + return (AE_NO_MEMORY); + } + + /* save state of GPE1 enable bits */ + + for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { + acpi_gbl_gpe1_enable_register_save[index] = + (u8) acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index); + } + } + + else { + acpi_gbl_gpe1_enable_register_save = NULL; + } + } + + return (status); +} + + +/****************************************************************************** + * * FUNCTION: Acpi_hw_set_mode * * PARAMETERS: Mode - SYS_MODE_ACPI or SYS_MODE_LEGACY @@ -56,7 +197,7 @@ if (mode == SYS_MODE_ACPI) { /* BIOS should have disabled ALL fixed and GP events */ - acpi_os_out8 (acpi_gbl_FACP->smi_cmd, acpi_gbl_FACP->acpi_enable); + acpi_os_out8 (acpi_gbl_FADT->smi_cmd, acpi_gbl_FADT->acpi_enable); } else if (mode == SYS_MODE_LEGACY) { @@ -65,7 +206,7 @@ * enable bits to default */ - acpi_os_out8 (acpi_gbl_FACP->smi_cmd, acpi_gbl_FACP->acpi_disable); + acpi_os_out8 (acpi_gbl_FADT->smi_cmd, acpi_gbl_FADT->acpi_disable); } if (acpi_hw_get_mode () == mode) { @@ -78,8 +219,7 @@ /****************************************************************************** * - * FUNCTION: Acpi_hw - + * FUNCTION: Acpi_hw_get_mode * * PARAMETERS: none * @@ -95,7 +235,7 @@ { - if (acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, SCI_EN)) { + if (acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, SCI_EN)) { return (SYS_MODE_ACPI); } else { @@ -177,7 +317,7 @@ { u32 ticks; - ticks = acpi_os_in32 (acpi_gbl_FACP->pm_tmr_blk); + ticks = acpi_os_in32 ((ACPI_IO_ADDRESS) acpi_gbl_FADT->Xpm_tmr_blk.address); return (ticks); } @@ -198,7 +338,7 @@ u32 acpi_hw_pmt_resolution (void) { - if (0 == acpi_gbl_FACP->tmr_val_ext) { + if (0 == acpi_gbl_FADT->tmr_val_ext) { return (24); } diff -urN linux-2.4.0-test12/drivers/acpi/hardware/hwcpu32.c linux-2.4.0-test12-lia/drivers/acpi/hardware/hwcpu32.c --- linux-2.4.0-test12/drivers/acpi/hardware/hwcpu32.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/hardware/hwcpu32.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: hwcpu32.c - CPU support for IA32 (Throttling, Cx_states) - * $Revision: 33 $ + * $Revision: 39 $ * *****************************************************************************/ @@ -132,7 +132,7 @@ * We have to do something useless after reading LVL2 because chipsets * cannot guarantee that STPCLK# gets asserted in time to freeze execution. */ - acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); + acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); /* * Compute Time in C2: @@ -171,7 +171,6 @@ u32 *pm_timer_ticks) { u32 timer = 0; - u8 pm2_cnt_blk = 0; u32 bus_master_status = 0; @@ -187,12 +186,12 @@ * eventually cause a demotion to C2 */ if (1 == (bus_master_status = - acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS))) + acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS))) { /* * Clear the BM_STS bit by setting it. */ - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1); *pm_timer_ticks = 0; return (AE_OK); } @@ -207,9 +206,7 @@ * ---------------------- * Set the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits. */ - pm2_cnt_blk = acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); - pm2_cnt_blk |= 0x01; - acpi_os_out8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk, pm2_cnt_blk); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1); /* * Get the timer base before entering C state @@ -229,8 +226,7 @@ * We have to do something useless after reading LVL3 because chipsets * cannot guarantee that STPCLK# gets asserted in time to freeze execution. */ - acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); - + acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); /* * Immediately compute the time in the C state */ @@ -241,9 +237,7 @@ * ------------------------ * Clear the PM2_CNT.ARB_DIS bit (bit #0), preserving all other bits. */ - pm2_cnt_blk = acpi_os_in8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk); - pm2_cnt_blk &= 0xFE; - acpi_os_out8 ((ACPI_IO_ADDRESS) acpi_gbl_FACP->pm2_cnt_blk, pm2_cnt_blk); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 0); /* TBD: [Unhandled]: Support 24-bit timers (this algorithm assumes 32-bit) */ @@ -332,7 +326,7 @@ switch (cx_state) { case 3: - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1); break; } @@ -346,7 +340,7 @@ switch (acpi_hw_active_cx_state) { case 3: - acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); + acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0); break; } @@ -408,15 +402,15 @@ * and on SMP systems when P_LVL2_UP (which indicates C2 only on UP) * is not set. */ - if (acpi_gbl_FACP->plvl2_lat <= 100) { + if (acpi_gbl_FADT->plvl2_lat <= 100) { if (!SMP_system) { acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; - cx_states[2] = acpi_gbl_FACP->plvl2_lat; + cx_states[2] = acpi_gbl_FADT->plvl2_lat; } - else if (!acpi_gbl_FACP->plvl2_up) { + else if (!acpi_gbl_FADT->plvl2_up) { acpi_hw_cx_handlers[2] = acpi_hw_enter_c2; - cx_states[2] = acpi_gbl_FACP->plvl2_lat; + cx_states[2] = acpi_gbl_FADT->plvl2_lat; } } @@ -431,12 +425,12 @@ * cannot be used on SMP systems, and flushing caches (e.g. WBINVD) * is simply too costly (at this time). */ - if (acpi_gbl_FACP->plvl3_lat <= 1000) { - if (!SMP_system && (acpi_gbl_FACP->pm2_cnt_blk && - acpi_gbl_FACP->pm2_cnt_len)) + if (acpi_gbl_FADT->plvl3_lat <= 1000) { + if (!SMP_system && (acpi_gbl_FADT->Xpm2_cnt_blk.address && + acpi_gbl_FADT->pm2_cnt_len)) { acpi_hw_cx_handlers[3] = acpi_hw_enter_c3; - cx_states[3] = acpi_gbl_FACP->plvl3_lat; + cx_states[3] = acpi_gbl_FADT->plvl3_lat; } } diff -urN linux-2.4.0-test12/drivers/acpi/hardware/hwgpe.c linux-2.4.0-test12-lia/drivers/acpi/hardware/hwgpe.c --- linux-2.4.0-test12/drivers/acpi/hardware/hwgpe.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/hardware/hwgpe.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions - * $Revision: 22 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -32,9 +32,6 @@ MODULE_NAME ("hwgpe") -u8 decode_to8bit [8] = {1,2,4,8,16,32,64,128}; - - /****************************************************************************** * * FUNCTION: Acpi_hw_enable_gpe @@ -63,7 +60,7 @@ /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Read the current value of the register, set the appropriate bit @@ -103,7 +100,7 @@ /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Read the current value of the register, clear the appropriate bit, @@ -142,7 +139,7 @@ /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Write a one to the appropriate bit in the status register to @@ -187,7 +184,7 @@ /* * Figure out the bit offset for this GPE within the target register. */ - bit_mask = decode_to8bit [MOD_8 (gpe_number)]; + bit_mask = acpi_gbl_decode_to8bit [MOD_8 (gpe_number)]; /* * Enabled?: diff -urN linux-2.4.0-test12/drivers/acpi/hardware/hwregs.c linux-2.4.0-test12-lia/drivers/acpi/hardware/hwregs.c --- linux-2.4.0-test12/drivers/acpi/hardware/hwregs.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/hardware/hwregs.c Wed Nov 15 16:25:04 2000 @@ -3,7 +3,7 @@ * * Module Name: hwregs - Read/write access functions for the various ACPI * control and status registers. - * $Revision: 67 $ + * $Revision: 81 $ * ******************************************************************************/ @@ -36,8 +36,8 @@ /* This matches the #defines in actypes.h. */ -NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", - "\\_S4_","\\_S4_b","\\_S5_"}; +NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", + "\\_S4_","\\_S4_b","\\_S5_"}; /******************************************************************************* @@ -53,7 +53,7 @@ * ******************************************************************************/ -u32 +static u32 acpi_hw_get_bit_shift ( u32 mask) { @@ -87,28 +87,31 @@ acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - acpi_os_out16 (acpi_gbl_FACP->pm1a_evt_blk, (u16) ALL_FIXED_STS_BITS); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); + - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_os_out16 ((u16) acpi_gbl_FACP->pm1b_evt_blk, + if (acpi_gbl_FADT->Xpm1b_evt_blk.address) { + acpi_os_out16 ((ACPI_IO_ADDRESS) acpi_gbl_FADT->Xpm1b_evt_blk.address, (u16) ALL_FIXED_STS_BITS); } /* now clear the GPE Bits */ - if (acpi_gbl_FACP->gpe0blk_len) { - gpe_length = (u16) DIV_2 (acpi_gbl_FACP->gpe0blk_len); + if (acpi_gbl_FADT->gpe0blk_len) { + gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len); for (index = 0; index < gpe_length; index++) { - acpi_os_out8 ((acpi_gbl_FACP->gpe0blk + index), (u8) 0xff); + acpi_os_out8 ((ACPI_IO_ADDRESS) (acpi_gbl_FADT->Xgpe0blk.address + index), + (u8) 0xff); } } - if (acpi_gbl_FACP->gpe1_blk_len) { - gpe_length = (u16) DIV_2 (acpi_gbl_FACP->gpe1_blk_len); + if (acpi_gbl_FADT->gpe1_blk_len) { + gpe_length = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len); for (index = 0; index < gpe_length; index++) { - acpi_os_out8 ((acpi_gbl_FACP->gpe1_blk + index), (u8) 0xff); + acpi_os_out8 ((ACPI_IO_ADDRESS) (acpi_gbl_FADT->Xgpe1_blk.address + index), + (u8) 0xff); } } @@ -162,7 +165,7 @@ } if (!obj_desc) { - REPORT_ERROR ("Missing Sleep State object"); + REPORT_ERROR (("Missing Sleep State object\n")); return (AE_NOT_EXIST); } @@ -172,17 +175,12 @@ * two elements */ - if (obj_desc->common.type != ACPI_TYPE_PACKAGE) { - /* Must be a package */ - - REPORT_ERROR ("Sleep State object is not of type Package"); - status = AE_ERROR; - } + status = acpi_cm_resolve_package_references(obj_desc); - else if (obj_desc->package.count < 2) { + if (obj_desc->package.count < 2) { /* Must have at least two elements */ - REPORT_ERROR ("Sleep State package does not have at least two elements"); + REPORT_ERROR (("Sleep State package does not have at least two elements\n")); status = AE_ERROR; } @@ -193,7 +191,7 @@ { /* Must have two */ - REPORT_ERROR ("Sleep State package elements are not both of type Number"); + REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); status = AE_ERROR; } @@ -216,23 +214,23 @@ /******************************************************************************* * - * FUNCTION: Acpi_hw_register_access + * FUNCTION: Acpi_hw_register_bit_access * * PARAMETERS: Read_write - Either ACPI_READ or ACPI_WRITE. * Use_lock - Lock the hardware - * Register_id - index of ACPI register to access + * Register_id - index of ACPI Register to access * Value - (only used on write) value to write to the - * register. Shifted all the way right. + * Register. Shifted all the way right. * - * RETURN: Value written to or read from specified register. This value + * RETURN: Value written to or read from specified Register. This value * is shifted all the way right. * - * DESCRIPTION: Generic ACPI register read/write function. + * DESCRIPTION: Generic ACPI Register read/write function. * ******************************************************************************/ u32 -acpi_hw_register_access ( +acpi_hw_register_bit_access ( NATIVE_UINT read_write, u8 use_lock, u32 register_id, @@ -241,7 +239,6 @@ u32 register_value = 0; u32 mask = 0; u32 value = 0; - ACPI_IO_ADDRESS gpe_reg = 0; if (read_write == ACPI_WRITE) { @@ -252,184 +249,126 @@ va_end (marker); } - /* - * TBD: [Restructure] May want to split the Acpi_event code and the - * Control code - */ + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + } /* * Decode the Register ID + * Register id = Register block id | bit id + * + * Check bit id to fine locate Register offset. + * check Mask to determine Register offset, and then read-write. */ - switch (register_id & REGISTER_BLOCK_MASK) + switch (REGISTER_BLOCK_ID(register_id)) { - case PM1_EVT: + case PM1_STS: - if (register_id < TMR_EN) { - /* status register */ + switch (register_id) + { + case TMR_STS: + mask = TMR_STS_MASK; + break; - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } + case BM_STS: + mask = BM_STS_MASK; + break; + case GBL_STS: + mask = GBL_STS_MASK; + break; - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk); - if (acpi_gbl_FACP->pm1b_evt_blk) { - register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk); - } + case PWRBTN_STS: + mask = PWRBTN_STS_MASK; + break; - switch (register_id) - { - case TMR_STS: - mask = TMR_STS_MASK; - break; - - case BM_STS: - mask = BM_STS_MASK; - break; - - case GBL_STS: - mask = GBL_STS_MASK; - break; - - case PWRBTN_STS: - mask = PWRBTN_STS_MASK; - break; - - case SLPBTN_STS: - mask = SLPBTN_STS_MASK; - break; - - case RTC_STS: - mask = RTC_STS_MASK; - break; - - case WAK_STS: - mask = WAK_STS_MASK; - break; - - default: - mask = 0; - break; - } + case SLPBTN_STS: + mask = SLPBTN_STS_MASK; + break; - if (read_write == ACPI_WRITE) { - /* - * Status registers are different from the rest. Clear by - * writing 1, writing 0 has no effect. So, the only relevent - * information is the single bit we're interested in, all - * others should be written as 0 so they will be left - * unchanged - */ - - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - - if (value) { - acpi_os_out16 (acpi_gbl_FACP->pm1a_evt_blk, (u16) value); - - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_os_out16 (acpi_gbl_FACP->pm1b_evt_blk, (u16) value); - } + case RTC_STS: + mask = RTC_STS_MASK; + break; - register_value = 0; - } - } + case WAK_STS: + mask = WAK_STS_MASK; + break; - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); - } + default: + mask = 0; + break; } - else { - /* enable register */ - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS); - if (acpi_gbl_FACP->pm1b_evt_blk) { - register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)); + if (read_write == ACPI_WRITE) { + /* + * Status Registers are different from the rest. Clear by + * writing 1, writing 0 has no effect. So, the only relevent + * information is the single bit we're interested in, all + * others should be written as 0 so they will be left + * unchanged + */ - } + value <<= acpi_hw_get_bit_shift (mask); + value &= mask; - switch (register_id) - { - case TMR_EN: - mask = TMR_EN_MASK; - break; - - case GBL_EN: - mask = GBL_EN_MASK; - break; - - case PWRBTN_EN: - mask = PWRBTN_EN_MASK; - break; - - case SLPBTN_EN: - mask = SLPBTN_EN_MASK; - break; - - case RTC_EN: - mask = RTC_EN_MASK; - break; - - default: - mask = 0; - break; - } + if (value) { + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_STS, (u16) value); - if (read_write == ACPI_WRITE) { - register_value &= ~mask; - value <<= acpi_hw_get_bit_shift (mask); - value &= mask; - register_value |= value; - - acpi_os_out16 ((acpi_gbl_FACP->pm1a_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)), - (u16) register_value); - - if (acpi_gbl_FACP->pm1b_evt_blk) { - acpi_os_out16 ((acpi_gbl_FACP->pm1b_evt_blk + - DIV_2 (acpi_gbl_FACP->pm1_evt_len)), - (u16) register_value); - } - } - if(ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + register_value = 0; } } + break; - case PM1_CONTROL: + case PM1_EN: - register_value = 0; + switch (register_id) + { + case TMR_EN: + mask = TMR_EN_MASK; + break; - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } + case GBL_EN: + mask = GBL_EN_MASK; + break; - if (register_id != SLP_TYPE_B) { - /* - * SLP_TYPx registers are written differently - * than any other control registers with - * respect to A and B registers. The value - * for A may be different than the value for B - */ + case PWRBTN_EN: + mask = PWRBTN_EN_MASK; + break; + + case SLPBTN_EN: + mask = SLPBTN_EN_MASK; + break; - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_cnt_blk); + case RTC_EN: + mask = RTC_EN_MASK; + break; + + default: + mask = 0; + break; } - if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (u32) SLP_TYPE_A) { - register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_cnt_blk); + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN); + + if (read_write == ACPI_WRITE) { + register_value &= ~mask; + value <<= acpi_hw_get_bit_shift (mask); + value &= mask; + register_value |= value; + + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (u16) register_value); } + break; + + + case PM1_CONTROL: + switch (register_id) { case SCI_EN: @@ -458,6 +397,14 @@ break; } + + /* + * Read the PM1 Control register. + * Note that at this level, the fact that there are actually TWO + * registers (A and B) and that B may not exist, are abstracted. + */ + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); + if (read_write == ACPI_WRITE) { register_value &= ~mask; value <<= acpi_hw_get_bit_shift (mask); @@ -465,47 +412,20 @@ register_value |= value; /* - * SLP_TYPE_x registers are written differently - * than any other control registers with - * respect to A and B registers. The value + * SLP_TYPE_x Registers are written differently + * than any other control Registers with + * respect to A and B Registers. The value * for A may be different than the value for B */ - if (register_id != SLP_TYPE_B) { - if (mask == SLP_EN_MASK) { - disable(); /* disable interrupts */ - } - - acpi_os_out16 (acpi_gbl_FACP->pm1a_cnt_blk, (u16) register_value); - - if (mask == SLP_EN_MASK) { - /* - * Enable interrupts, the SCI handler is likely going to - * be invoked as soon as interrupts are enabled, since gpe's - * and most fixed resume events also generate SCI's. - */ - enable(); - } - } - - if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (u32) SLP_TYPE_A) { - acpi_os_out16 (acpi_gbl_FACP->pm1b_cnt_blk, (u16) register_value); - } - } - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + PM1_CONTROL, (u16) register_value); } break; case PM2_CONTROL: - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - - register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm2_cnt_blk); switch (register_id) { case ARB_DIS: @@ -517,85 +437,64 @@ break; } + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); + if (read_write == ACPI_WRITE) { register_value &= ~mask; value <<= acpi_hw_get_bit_shift (mask); value &= mask; register_value |= value; - acpi_os_out16 (acpi_gbl_FACP->pm2_cnt_blk, (u16) register_value); - } - - if (ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + PM2_CONTROL, (u8) (register_value)); } break; case PM_TIMER: - register_value = acpi_os_in32 (acpi_gbl_FACP->pm_tmr_blk); - mask = 0xFFFFFFFF; + mask = TMR_VAL_MASK; + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + PM_TIMER); break; case GPE1_EN_BLOCK: - - gpe_reg = (acpi_gbl_FACP->gpe1_blk + acpi_gbl_FACP->gpe1_base) + - (gpe_reg + (DIV_2 (acpi_gbl_FACP->gpe1_blk_len))); - - case GPE1_STS_BLOCK: - - if (!gpe_reg) { - gpe_reg = (acpi_gbl_FACP->gpe1_blk + acpi_gbl_FACP->gpe1_base); - } - - case GPE0_EN_BLOCK: - - if (!gpe_reg) { - gpe_reg = acpi_gbl_FACP->gpe0blk + DIV_2 (acpi_gbl_FACP->gpe0blk_len); - } - - case GPE0_STS_BLOCK: - if (!gpe_reg) { - gpe_reg = acpi_gbl_FACP->gpe0blk; - } - - /* Determine the bit to be accessed */ + /* Determine the bit to be accessed + * + * (u32) Register_id: + * 31 24 16 8 0 + * +--------+--------+--------+--------+ + * | gpe_block_id | gpe_bit_number | + * +--------+--------+--------+--------+ + * + * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK + * gpe_bit_number is relative from the gpe_block (0x00~0xFF) + */ - mask = (((u32) register_id) & BIT_IN_REGISTER_MASK); - mask = 1 << (mask-1); + mask = REGISTER_BIT_ID(register_id); /* gpe_bit_number */ + register_id = REGISTER_BLOCK_ID(register_id) | (mask >> 3); + mask = acpi_gbl_decode_to8bit [mask % 8]; /* * The base address of the GPE 0 Register Block * Plus 1/2 the length of the GPE 0 Register Block - * The enable register is the register following the Status Register - * and each register is defined as 1/2 of the total Register Block + * The enable Register is the Register following the Status Register + * and each Register is defined as 1/2 of the total Register Block */ /* * This sets the bit within Enable_bit that needs to be written to - * the register indicated in Mask to a 1, all others are 0 + * the Register indicated in Mask to a 1, all others are 0 */ - if (mask > LOW_BYTE) { - /* Shift the value 1 byte to the right and add 1 to the register */ - - mask >>= ONE_BYTE; - gpe_reg++; - } - /* Now get the current Enable Bits in the selected Reg */ - if(ACPI_MTX_LOCK == use_lock) { - acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); - } - - register_value = (u32) acpi_os_in8 (gpe_reg); + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id); if (read_write == ACPI_WRITE) { register_value &= ~mask; value <<= acpi_hw_get_bit_shift (mask); @@ -603,29 +502,498 @@ register_value |= value; /* This write will put the Action state into the General Purpose */ - /* Enable Register indexed by the value in Mask */ - acpi_os_out8 (gpe_reg, (u8) register_value); - register_value = (u32) acpi_os_in8 (gpe_reg); - } - - if(ACPI_MTX_LOCK == use_lock) { - acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + register_id, (u8) register_value); + register_value = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, register_id); } break; + case SMI_CMD_BLOCK: case PROCESSOR_BLOCK: + /* not used */ default: mask = 0; break; } + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + } + register_value &= mask; register_value >>= acpi_hw_get_bit_shift (mask); return (register_value); } + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_register_read + * + * PARAMETERS: Use_lock - Mutex hw access. + * Register_id - Register_iD + Offset. + * + * RETURN: Value read or written. + * + * DESCRIPTION: Acpi register read function. Registers are read at the + * given offset. + * + ******************************************************************************/ + +u32 +acpi_hw_register_read ( + u8 use_lock, + u32 register_id) +{ + u32 value = 0; + u32 offset = REGISTER_OFFSET (register_id); + u32 bank_offset; + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + } + + + switch (REGISTER_BLOCK_ID(register_id)) + { + case PM1_STS: /* 16-bit access */ + + value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, offset); + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, offset); + break; + + + case PM1_EN: /* 16-bit access*/ + + bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); + value = acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset + offset); + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset + offset); + break; + + + case PM1_CONTROL: /* 16-bit access */ + + if (register_id != SLP_TYPE_B) { + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1a_cnt_blk, 0); + } + + if (register_id != SLP_TYPE_A) { + value |= acpi_hw_low_level_read (16, &acpi_gbl_FADT->Xpm1b_cnt_blk, 0); + } + break; + + + case PM2_CONTROL: /* 8-bit access */ + + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xpm2_cnt_blk, offset); + break; + + + case PM_TIMER: /* 32-bit access */ + + value = acpi_hw_low_level_read (32, &acpi_gbl_FADT->Xpm_tmr_blk, offset); + break; + + + case GPE0_STS_BLOCK: /* 8-bit access */ + + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, offset); + break; + + + case GPE0_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len); + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe0blk, bank_offset + offset); + break; + + + case GPE1_STS_BLOCK: /* 8-bit access */ + + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, offset); + break; + + + case GPE1_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len); + value = acpi_hw_low_level_read (8, &acpi_gbl_FADT->Xgpe1_blk, bank_offset + offset); + break; + + + case SMI_CMD_BLOCK: /* 8bit */ + + value = (u32) acpi_os_in8 (acpi_gbl_FADT->smi_cmd); + break; + + + default: + value = 0; + break; + } + + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + } + + return (value); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_register_write + * + * PARAMETERS: Use_lock - Mutex hw access. + * Register_id - Register_iD + Offset. + * + * RETURN: Value read or written. + * + * DESCRIPTION: Acpi register Write function. Registers are written at the + * given offset. + * + ******************************************************************************/ + +void +acpi_hw_register_write ( + u8 use_lock, + u32 register_id, + u32 value) +{ + u32 offset = REGISTER_OFFSET (register_id); + u32 bank_offset; + + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_acquire_mutex (ACPI_MTX_HARDWARE); + } + + + switch (REGISTER_BLOCK_ID (register_id)) + { + case PM1_STS: /* 16-bit access */ + + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, offset); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, offset); + break; + + + case PM1_EN: /* 16-bit access*/ + + bank_offset = DIV_2 (acpi_gbl_FADT->pm1_evt_len); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_evt_blk, bank_offset + offset); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_evt_blk, bank_offset + offset); + break; + + + case PM1_CONTROL: /* 16-bit access */ + + /* + * If SLP_TYP_A or SLP_TYP_B, only write to one reg block. + * Otherwise, write to both. + */ + if (register_id == SLP_TYPE_A) { + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, offset); + } + else if (register_id == SLP_TYPE_B) { + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, offset); + } + else { + /* disable/re-enable interrupts if sleeping */ + if (register_id == SLP_EN) { + disable(); + } + + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1a_cnt_blk, offset); + acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->Xpm1b_cnt_blk, offset); + + if (register_id == SLP_EN) { + enable(); + } + } + + break; + + + case PM2_CONTROL: /* 8-bit access */ + + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xpm2_cnt_blk, offset); + break; + + + case PM_TIMER: /* 32-bit access */ + + acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->Xpm_tmr_blk, offset); + break; + + + case GPE0_STS_BLOCK: /* 8-bit access */ + + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, offset); + break; + + + case GPE0_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe0blk_len); + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe0blk, bank_offset + offset); + break; + + + case GPE1_STS_BLOCK: /* 8-bit access */ + + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, offset); + break; + + + case GPE1_EN_BLOCK: /* 8-bit access */ + + bank_offset = DIV_2 (acpi_gbl_FADT->gpe1_blk_len); + acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->Xgpe1_blk, bank_offset + offset); + break; + + + case SMI_CMD_BLOCK: /* 8bit */ + + /* For 2.0, SMI_CMD is always in IO space */ + /* TBD: what about 1.0? 0.71? */ + + acpi_os_out8 (acpi_gbl_FADT->smi_cmd, (u8) value); + break; + + + default: + value = 0; + break; + } + + + if (ACPI_MTX_LOCK == use_lock) { + acpi_cm_release_mutex (ACPI_MTX_HARDWARE); + } + + return; +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_low_level_read + * + * PARAMETERS: Register - GAS register structure + * Offset - Offset from the base address in the GAS + * Width - 8, 16, or 32 + * + * RETURN: Value read + * + * DESCRIPTION: Read from either memory, IO, or PCI config space. + * + ******************************************************************************/ + +u32 +acpi_hw_low_level_read ( + u32 width, + ACPI_GAS *reg, + u32 offset) +{ + u32 value = 0; + ACPI_PHYSICAL_ADDRESS mem_address; + ACPI_IO_ADDRESS io_address; + u32 pci_register; + u32 pci_dev_func; + + + /* + * Must have a valid pointer to a GAS structure, and + * a non-zero address within + */ + if ((!reg) || + (!reg->address)) + { + return 0; + } + + + /* + * Three address spaces supported: + * Memory, Io, or PCI config. + */ + + switch (reg->address_space_id) + { + case ADDRESS_SPACE_SYSTEM_MEMORY: + + mem_address = (ACPI_PHYSICAL_ADDRESS) reg->address + offset; + + switch (width) + { + case 8: + value = acpi_os_mem_in8 (mem_address); + break; + case 16: + value = acpi_os_mem_in16 (mem_address); + break; + case 32: + value = acpi_os_mem_in32 (mem_address); + break; + } + break; + + + case ADDRESS_SPACE_SYSTEM_IO: + + io_address = (ACPI_IO_ADDRESS) reg->address + offset; + + switch (width) + { + case 8: + value = acpi_os_in8 (io_address); + break; + case 16: + value = acpi_os_in16 (io_address); + break; + case 32: + value = acpi_os_in32 (io_address); + break; + } + break; + + + case ADDRESS_SPACE_PCI_CONFIG: + + pci_dev_func = ACPI_PCI_DEVFUN (reg->address); + pci_register = ACPI_PCI_REGISTER (reg->address) + offset; + + switch (width) + { + case 8: + acpi_os_read_pci_cfg_byte (0, pci_dev_func, pci_register, (u8 *) &value); + break; + case 16: + acpi_os_read_pci_cfg_word (0, pci_dev_func, pci_register, (u16 *) &value); + break; + case 32: + acpi_os_read_pci_cfg_dword (0, pci_dev_func, pci_register, (u32 *) &value); + break; + } + break; + } + + return value; +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_hw_low_level_write + * + * PARAMETERS: Width - 8, 16, or 32 + * Value - To be written + * Register - GAS register structure + * Offset - Offset from the base address in the GAS + * + * + * RETURN: Value read + * + * DESCRIPTION: Read from either memory, IO, or PCI config space. + * + ******************************************************************************/ + +void +acpi_hw_low_level_write ( + u32 width, + u32 value, + ACPI_GAS *reg, + u32 offset) +{ + ACPI_PHYSICAL_ADDRESS mem_address; + ACPI_IO_ADDRESS io_address; + u32 pci_register; + u32 pci_dev_func; + + + /* + * Must have a valid pointer to a GAS structure, and + * a non-zero address within + */ + if ((!reg) || + (!reg->address)) + { + return; + } + + + /* + * Three address spaces supported: + * Memory, Io, or PCI config. + */ + + switch (reg->address_space_id) + { + case ADDRESS_SPACE_SYSTEM_MEMORY: + + mem_address = (ACPI_PHYSICAL_ADDRESS) reg->address + offset; + + switch (width) + { + case 8: + acpi_os_mem_out8 (mem_address, (u8) value); + break; + case 16: + acpi_os_mem_out16 (mem_address, (u16) value); + break; + case 32: + acpi_os_mem_out32 (mem_address, (u32) value); + break; + } + break; + + + case ADDRESS_SPACE_SYSTEM_IO: + + io_address = (ACPI_IO_ADDRESS) reg->address + offset; + + switch (width) + { + case 8: + acpi_os_out8 (io_address, (u8) value); + break; + case 16: + acpi_os_out16 (io_address, (u16) value); + break; + case 32: + acpi_os_out32 (io_address, (u32) value); + break; + } + break; + + + case ADDRESS_SPACE_PCI_CONFIG: + + pci_dev_func = ACPI_PCI_DEVFUN (reg->address); + pci_register = ACPI_PCI_REGISTER (reg->address) + offset; + + switch (width) + { + case 8: + acpi_os_write_pci_cfg_byte (0, pci_dev_func, pci_register, (u8) value); + break; + case 16: + acpi_os_write_pci_cfg_word (0, pci_dev_func, pci_register, (u16) value); + break; + case 32: + acpi_os_write_pci_cfg_dword (0, pci_dev_func, pci_register, (u32) value); + break; + } + break; + } +} + + diff -urN linux-2.4.0-test12/drivers/acpi/hardware/hwxface.c linux-2.4.0-test12-lia/drivers/acpi/hardware/hwxface.c --- linux-2.4.0-test12/drivers/acpi/hardware/hwxface.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/hardware/hwxface.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: hwxface.c - Hardware access external interfaces - * $Revision: 31 $ + * $Revision: 36 $ * *****************************************************************************/ @@ -69,7 +69,7 @@ NATIVE_UINT num_throttle_states; NATIVE_UINT buffer_space_needed; NATIVE_UINT i; - u8 duty_width = 0; + u8 duty_width; ACPI_NAMESPACE_NODE *cpu_node; ACPI_OPERAND_OBJECT *cpu_obj; ACPI_CPU_THROTTLING_STATE *state_ptr; @@ -100,12 +100,10 @@ return (AE_NOT_FOUND); } -#ifndef _IA64 /* - * No Duty fields in IA64 tables + * (Duty Width on IA-64 is zero) */ - duty_width = acpi_gbl_FACP->duty_width; -#endif + duty_width = acpi_gbl_FADT->duty_width; /* * P0 must always have a P_BLK all others may be null @@ -115,7 +113,7 @@ * */ if (!cpu_obj->processor.length || !duty_width || - (0xFFFF < cpu_obj->processor.address)) + (ACPI_UINT16_MAX < cpu_obj->processor.address)) { /* * Acpi_even though we can't throttle, we still have one state (100%) @@ -177,8 +175,8 @@ ACPI_OPERAND_OBJECT *cpu_obj; u32 num_throttle_states; u32 duty_cycle; - u8 duty_offset = 0; - u8 duty_width = 0; + u8 duty_offset; + u8 duty_width; /* Convert and validate the device handle */ @@ -195,13 +193,11 @@ return (AE_NOT_FOUND); } -#ifndef _IA64 /* * No Duty fields in IA64 tables */ - duty_offset = acpi_gbl_FACP->duty_offset; - duty_width = acpi_gbl_FACP->duty_width; -#endif + duty_offset = acpi_gbl_FADT->duty_offset; + duty_width = acpi_gbl_FADT->duty_width; /* * Must have a valid P_BLK P0 must have a P_BLK all others may be null @@ -211,7 +207,7 @@ * also, if Duty_width is zero there are no additional states */ if (!cpu_obj->processor.length || !duty_width || - (0xFFFF < cpu_obj->processor.address)) + (ACPI_UINT16_MAX < cpu_obj->processor.address)) { *throttle_state = 0; return(AE_OK); @@ -263,8 +259,8 @@ ACPI_NAMESPACE_NODE *cpu_node; ACPI_OPERAND_OBJECT *cpu_obj; u32 num_throttle_states = 0; - u8 duty_offset = 0; - u8 duty_width = 0; + u8 duty_offset; + u8 duty_width; u32 duty_cycle = 0; @@ -282,13 +278,11 @@ return (AE_NOT_FOUND); } -#ifndef _IA64 /* * No Duty fields in IA64 tables */ - duty_offset = acpi_gbl_FACP->duty_offset; - duty_width = acpi_gbl_FACP->duty_width; -#endif + duty_offset = acpi_gbl_FADT->duty_offset; + duty_width = acpi_gbl_FADT->duty_width; /* * Must have a valid P_BLK P0 must have a P_BLK all others may be null @@ -298,7 +292,7 @@ * also, if Duty_width is zero there are no additional states */ if (!cpu_obj->processor.length || !duty_width || - (0xFFFF < cpu_obj->processor.address)) + (ACPI_UINT16_MAX < cpu_obj->processor.address)) { /* * If caller wants to set the state to the only state we handle @@ -314,7 +308,7 @@ return (AE_SUPPORT); } - num_throttle_states = (int) acpi_hw_local_pow (2,duty_width); + num_throttle_states = (u32) acpi_hw_local_pow (2,duty_width); /* * Convert throttling state to duty cycle (invert). @@ -533,9 +527,10 @@ ACPI_STATUS acpi_set_firmware_waking_vector ( - void *physical_address) + ACPI_PHYSICAL_ADDRESS physical_address) { + /* Make sure that we have an FACS */ if (!acpi_gbl_FACS) { @@ -544,7 +539,12 @@ /* Set the vector */ - * ((void **) acpi_gbl_FACS->firmware_waking_vector) = physical_address; + if (acpi_gbl_FACS->vector_width == 32) { + * (u32 *) acpi_gbl_FACS->firmware_waking_vector = (u32) physical_address; + } + else { + *acpi_gbl_FACS->firmware_waking_vector = physical_address; + } return (AE_OK); } @@ -555,7 +555,7 @@ * FUNCTION: Acpi_get_firmware_waking_vector * * PARAMETERS: *Physical_address - Output buffer where contents of - * the d_firmware_waking_vector field of + * the Firmware_waking_vector field of * the FACS will be stored. * * RETURN: Status @@ -566,9 +566,10 @@ ACPI_STATUS acpi_get_firmware_waking_vector ( - void **physical_address) + ACPI_PHYSICAL_ADDRESS *physical_address) { + if (!physical_address) { return (AE_BAD_PARAMETER); } @@ -581,8 +582,12 @@ /* Get the vector */ - *physical_address = * ((void **) acpi_gbl_FACS->firmware_waking_vector); - + if (acpi_gbl_FACS->vector_width == 32) { + *physical_address = * (u32 *) acpi_gbl_FACS->firmware_waking_vector; + } + else { + *physical_address = *acpi_gbl_FACS->firmware_waking_vector; + } return (AE_OK); } diff -urN linux-2.4.0-test12/drivers/acpi/include/accommon.h linux-2.4.0-test12-lia/drivers/acpi/include/accommon.h --- linux-2.4.0-test12/drivers/acpi/include/accommon.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/accommon.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: accommon.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 74 $ + * $Revision: 81 $ * *****************************************************************************/ @@ -43,7 +43,7 @@ void acpi_cm_init_globals ( - ACPI_INIT_DATA *init_data); + void); void acpi_cm_terminate ( @@ -51,7 +51,7 @@ /* - * Acpi_cm_init - miscellaneous initialization and shutdown + * Cm_init - miscellaneous initialization and shutdown */ ACPI_STATUS @@ -62,8 +62,12 @@ acpi_cm_subsystem_shutdown ( void); +ACPI_STATUS +acpi_cm_validate_fadt ( + void); + /* - * Acpi_cm_global - Global data structures and procedures + * Cm_global - Global data structures and procedures */ NATIVE_CHAR * @@ -84,7 +88,7 @@ /* - * Acpi_cm_clib - Local implementations of C library functions + * Cm_clib - Local implementations of C library functions */ NATIVE_UINT @@ -161,7 +165,7 @@ /* - * Acpi_cm_copy - Object construction and conversion interfaces + * Cm_copy - Object construction and conversion interfaces */ ACPI_STATUS @@ -204,7 +208,7 @@ /* - * Acpi_cm_create - Object creation + * Cm_create - Object creation */ ACPI_STATUS @@ -221,7 +225,7 @@ /* - * Acpi_cm_debug - Debug interfaces + * Cm_debug - Debug interfaces */ u32 @@ -315,22 +319,19 @@ _report_info ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message); + u32 component_id); void _report_error ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message); + u32 component_id); void _report_warning ( NATIVE_CHAR *module_name, u32 line_number, - u32 component_id, - NATIVE_CHAR *message); + u32 component_id); void acpi_cm_dump_buffer ( @@ -341,7 +342,7 @@ /* - * Acpi_cm_delete - Object deletion + * Cm_delete - Object deletion */ void @@ -362,7 +363,7 @@ /* - * Acpi_cm_eval - object evaluation + * Cm_eval - object evaluation */ /* Method name strings */ @@ -378,9 +379,9 @@ ACPI_STATUS acpi_cm_evaluate_numeric_object ( - NATIVE_CHAR *method_name, + NATIVE_CHAR *object_name, ACPI_NAMESPACE_NODE *device_node, - u32 *address); + ACPI_INTEGER *address); ACPI_STATUS acpi_cm_execute_HID ( @@ -399,7 +400,7 @@ /* - * Acpi_cm_error - exception interfaces + * Cm_error - exception interfaces */ NATIVE_CHAR * @@ -408,7 +409,7 @@ /* - * Acpi_cm_mutex - mutual exclusion interfaces + * Cm_mutex - mutual exclusion interfaces */ ACPI_STATUS @@ -437,7 +438,7 @@ /* - * Acpi_cm_object - internal object create/delete/cache routines + * Cm_object - internal object create/delete/cache routines */ void * @@ -459,7 +460,7 @@ /* - * Acpi_cm_ref_cnt - Object reference count management + * Cm_ref_cnt - Object reference count management */ void @@ -471,7 +472,7 @@ ACPI_OPERAND_OBJECT *object); /* - * Acpi_cm_size - Object size routines + * Cm_size - Object size routines */ ACPI_STATUS @@ -491,7 +492,7 @@ /* - * Acpi_cm_state - Generic state creation/cache routines + * Cm_state - Generic state creation/cache routines */ void @@ -536,7 +537,7 @@ void); /* - * Acpi_cmutils + * Cmutils */ u8 @@ -546,6 +547,10 @@ u8 acpi_cm_valid_acpi_character ( NATIVE_CHAR character); + +ACPI_STATUS +acpi_cm_resolve_package_references ( + ACPI_OPERAND_OBJECT *obj_desc); /* diff -urN linux-2.4.0-test12/drivers/acpi/include/acconfig.h linux-2.4.0-test12-lia/drivers/acpi/include/acconfig.h --- linux-2.4.0-test12/drivers/acpi/include/acconfig.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acconfig.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acconfig.h - Global configuration constants - * $Revision: 42 $ + * $Revision: 48 $ * *****************************************************************************/ @@ -55,29 +55,6 @@ #define ACPI_CA_VERSION __DATE__ -/* Name of host operating system (returned by the _OS_ namespace object) */ - -#ifdef _LINUX -#define ACPI_OS_NAME "Linux" -#else -#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" -#endif - - -/* - * How and when control methods will be parsed - * The default action is to parse all methods at table load time to verify them, but delete the parse trees - * to conserve memory. Methods are parsed just in time before execution and the parse tree is deleted - * when execution completes. - */ -#define METHOD_PARSE_AT_INIT 0x0 /* Parse at table init, never delete the method parse tree */ -#define METHOD_PARSE_JUST_IN_TIME 0x1 /* Parse only when a method is invoked */ -#define METHOD_DELETE_AT_COMPLETION 0x2 /* Delete parse tree on method completion */ - -/* Default parsing configuration */ - -#define METHOD_PARSE_CONFIGURATION (METHOD_PARSE_JUST_IN_TIME | METHOD_DELETE_AT_COMPLETION) - /* Maximum objects in the various object caches */ @@ -87,15 +64,6 @@ #define MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */ #define MAX_WALK_CACHE_DEPTH 2 /* Objects for parse tree walks (method execution) */ -/* - * Name_space Table size - * - * All tables are the same size to simplify the implementation. - * Tables may be extended by allocating additional tables that - * are in turn linked together to form a chain of tables. - */ - -#define NS_TABLE_SIZE 4 /* String size constants */ @@ -164,14 +132,14 @@ /* Names within the namespace are 4 bytes long */ #define ACPI_NAME_SIZE 4 -#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 s8 for separator */ +#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 s8 for separator */ #define PATH_SEPARATOR '.' /* Constants used in searching for the RSDP in low memory */ -#define LO_RSDP_WINDOW_BASE (void *) 0 -#define HI_RSDP_WINDOW_BASE (void *) 0xE0000 +#define LO_RSDP_WINDOW_BASE 0 /* Physical Address */ +#define HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ #define LO_RSDP_WINDOW_SIZE 0x400 #define HI_RSDP_WINDOW_SIZE 0x20000 #define RSDP_SCAN_STEP 16 diff -urN linux-2.4.0-test12/drivers/acpi/include/acdebug.h linux-2.4.0-test12-lia/drivers/acpi/include/acdebug.h --- linux-2.4.0-test12/drivers/acpi/include/acdebug.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acdebug.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdebug.h - ACPI/AML debugger - * $Revision: 35 $ + * $Revision: 37 $ * *****************************************************************************/ @@ -205,6 +205,7 @@ void acpi_db_display_op ( + ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *origin, u32 num_opcodes); @@ -218,7 +219,12 @@ void acpi_db_display_opcode ( + ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op); + +void +acpi_db_decode_internal_object ( + ACPI_OPERAND_OBJECT *obj_desc); /* diff -urN linux-2.4.0-test12/drivers/acpi/include/acdispat.h linux-2.4.0-test12-lia/drivers/acpi/include/acdispat.h --- linux-2.4.0-test12/drivers/acpi/include/acdispat.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acdispat.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdispat.h - dispatcher (parser to interpreter interface) - * $Revision: 29 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -61,7 +61,11 @@ ACPI_WALK_STATE *walk_state); -/* dsregion - Op region support */ +/* dsopcode - support for late evaluation */ + +ACPI_STATUS +acpi_ds_get_field_unit_arguments ( + ACPI_OPERAND_OBJECT *obj_desc); ACPI_STATUS acpi_ds_get_region_arguments ( @@ -84,6 +88,13 @@ /* dsexec - Parser/Interpreter interface, method execution callbacks */ + +ACPI_STATUS +acpi_ds_get_predicate_value ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op, + u32 has_result_obj); + ACPI_STATUS acpi_ds_exec_begin_op ( u16 opcode, @@ -145,6 +156,18 @@ ACPI_WALK_STATE *state, ACPI_PARSE_OBJECT *op); +ACPI_STATUS +acpi_ds_load3_begin_op ( + u16 opcode, + ACPI_PARSE_OBJECT *op, + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT **out_op); + +ACPI_STATUS +acpi_ds_load3_end_op ( + ACPI_WALK_STATE *state, + ACPI_PARSE_OBJECT *op); + /* dsmthdat - method data (locals/args) */ @@ -284,6 +307,11 @@ /* dsregn - Parser/Interpreter interface - Op Region parsing */ ACPI_STATUS +acpi_ds_eval_field_unit_operands ( + ACPI_WALK_STATE *walk_state, + ACPI_PARSE_OBJECT *op); + +ACPI_STATUS acpi_ds_eval_region_operands ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op); @@ -297,7 +325,8 @@ u8 acpi_ds_is_result_used ( - ACPI_PARSE_OBJECT *op); + ACPI_PARSE_OBJECT *op, + ACPI_WALK_STATE *walk_state); void acpi_ds_delete_result_if_not_used ( diff -urN linux-2.4.0-test12/drivers/acpi/include/acenv.h linux-2.4.0-test12-lia/drivers/acpi/include/acenv.h --- linux-2.4.0-test12/drivers/acpi/include/acenv.h Fri Sep 15 21:37:23 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acenv.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acenv.h - Generation environment specific items - * $Revision: 53 $ + * $Revision: 65 $ * *****************************************************************************/ @@ -28,6 +28,35 @@ /* + * Configuration for ACPI Utilities + */ + +#ifdef _ACPI_DUMP_APP +#define ACPI_DEBUG +#define ACPI_APPLICATION +#define ENABLE_DEBUGGER +#define ACPI_USE_SYSTEM_CLIBRARY +#define PARSER_ONLY +#endif + +#ifdef _ACPI_EXEC_APP +#undef DEBUGGER_THREADING +#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED +#define ACPI_DEBUG +#define ACPI_APPLICATION +#define ENABLE_DEBUGGER +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + +#ifdef _ACPI_ASL_COMPILER +#define ACPI_DEBUG +#define ACPI_APPLICATION +#define ENABLE_DEBUGGER +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + + +/* * Environment configuration. The purpose of this file is to interface to the * local generation environment. * @@ -64,50 +93,35 @@ * */ - -/* - * Environment-specific configuration - */ +/*! [Begin] no source code translation */ #ifdef _LINUX +#include "aclinux.h" -#include -#include -#include -#include -#include - -/* Use native Linux string library */ - -#define ACPI_USE_SYSTEM_CLIBRARY - -/* Special functions */ - -#define strtoul simple_strtoul +#elif _AED_EFI +#include "acefi.h" -/* Linux clib doesn't to strupr, but we do. */ -char * -strupr(char *str); +#elif WIN32 +#include "acwin.h" -#else - -#ifdef _AED_EFI - -#include -#include -#include +#elif __FreeBSD__ +#include "acfreebsd.h" #else - /* All other environments */ #define ACPI_USE_STANDARD_HEADERS +/* Name of host operating system (returned by the _OS_ namespace object) */ + +#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" + #endif -#endif +/*! [End] no source code translation !*/ + /****************************************************************************** * * C library configuration @@ -218,132 +232,13 @@ /* * Handle platform- and compiler-specific assembly language differences. + * These should already have been defined by the platform includes above. * * Notes: * 1) Interrupt 3 is used to break into a debugger * 2) Interrupts are turned off during ACPI register setup */ - -#ifdef __GNUC__ - - -#ifdef __ia64__ - -/* Single threaded */ -#define ACPI_APPLICATION - -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() -#define wbinvd() - -/*! [Begin] no source code translation */ -#include - -/* PAL_HALT[_LIGHT] */ -#define halt() ia64_pal_halt_light() - -/* PAL_HALT */ -#define safe_halt() ia64_pal_halt(1) - -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - __asm__ volatile ("1: ld4 r29=%1\n" \ - ";;\n" \ - "mov ar.ccv=r29\n" \ - "mov r2=r29\n" \ - "shr.u r30=r29,1\n" \ - "and r29=-4,r29\n" \ - ";;\n" \ - "add r29=2,r29\n" \ - "and r30=1,r30\n" \ - ";;\n" \ - "add r29=r29,r30\n" \ - ";;\n" \ - "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ - ";;\n" \ - "cmp.eq p6,p7=r2,r30\n" \ - "(p7) br.dpnt.few 1b\n" \ - "cmp.gt p8,p9=3,r29\n" \ - ";;\n" \ - "(p8) mov %0=-1\n" \ - "(p9) mov %0=r0\n" \ - :"=r"(Acq):"m" __atomic_fool_gcc((GLptr)):"r2","r29","r30","memory"); \ - } while (0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - __asm__ volatile ("1: ld4 r29=%1\n" \ - ";;\n" \ - "mov ar.ccv=r29\n" \ - "mov r2=r29\n" \ - "and r29=-4,r29\n" \ - ";;\n" \ - "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ - ";;\n" \ - "cmp.eq p6,p7=r2,r30\n" \ - "(p7) br.dpnt.few 1b\n" \ - "and %0=1,r2\n" \ - ";;\n" \ - :"=r"(Acq):"m" __atomic_fool_gcc((GLptr)):"r2","r29","r30","memory"); \ - } while (0) -/*! [End] no source code translation !*/ - -#else /* DO IA32 */ - -#define ACPI_ASM_MACROS -#define causeinterrupt(level) -#define BREAKPOINT3 -#define disable() __cli() -#define enable() __sti() -#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") -#define wbinvd() - -/*! [Begin] no source code translation - * - * A brief explanation as GNU inline assembly is a bit hairy - * %0 is the output parameter in EAX ("=a") - * %1 and %2 are the input parameters in ECX ("c") - * and an immediate value ("i") respectively - * All actual register references are preceded with "%%" as in "%%edx" - * Immediate values in the assembly are preceded by "$" as in "$0x1" - * The final asm parameter are the operation altered non-output registers. - */ -#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "btsl $0x1,%%edx;" \ - "adcl $0x0,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "cmpb $0x3,%%dl;" \ - "sbbl %%eax,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ - } while(0) - -#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ - do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ - "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ - "lock; cmpxchgl %%edx,(%1);" \ - "jnz 1b;" \ - "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ - } while(0) -/*! [End] no source code translation !*/ - -#endif /* IA 32 */ -#endif /* __GNUC__ */ - - /* Unrecognized compiler, use defaults */ #ifndef ACPI_ASM_MACROS @@ -368,6 +263,16 @@ #define causeinterrupt(level) #define BREAKPOINT3 #endif + + +/****************************************************************************** + * + * Compiler-specific + * + *****************************************************************************/ + +/* this has been moved to compiler-specific headers, which are included from the + platform header. */ #endif /* __ACENV_H__ */ diff -urN linux-2.4.0-test12/drivers/acpi/include/acevents.h linux-2.4.0-test12-lia/drivers/acpi/include/acevents.h --- linux-2.4.0-test12/drivers/acpi/include/acevents.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acevents.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acevents.h - Event subcomponent prototypes and defines - * $Revision: 56 $ + * $Revision: 60 $ * *****************************************************************************/ @@ -27,6 +27,11 @@ #define __ACEVENTS_H__ +ACPI_STATUS +acpi_ev_initialize ( + void); + + /* * Acpi_evfixed - Fixed event handling */ @@ -104,7 +109,7 @@ acpi_ev_address_space_dispatch ( ACPI_OPERAND_OBJECT *region_obj, u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value); diff -urN linux-2.4.0-test12/drivers/acpi/include/acexcep.h linux-2.4.0-test12-lia/drivers/acpi/include/acexcep.h --- linux-2.4.0-test12/drivers/acpi/include/acexcep.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acexcep.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acexcep.h - Exception codes returned by the ACPI subsystem - * $Revision: 35 $ + * $Revision: 36 $ * *****************************************************************************/ @@ -89,6 +89,7 @@ #define AE_BAD_SIGNATURE (ACPI_STATUS) (0x0001 | AE_CODE_ACPI_TABLES) #define AE_BAD_HEADER (ACPI_STATUS) (0x0002 | AE_CODE_ACPI_TABLES) #define AE_BAD_CHECKSUM (ACPI_STATUS) (0x0003 | AE_CODE_ACPI_TABLES) +#define AE_BAD_VALUE (ACPI_STATUS) (0x0004 | AE_CODE_ACPI_TABLES) #define AE_CODE_TBL_MAX 0x0003 @@ -177,6 +178,7 @@ "AE_BAD_SIGNATURE", "AE_BAD_HEADER", "AE_BAD_CHECKSUM", + "AE_BAD_VALUE", }; static NATIVE_CHAR *acpi_gbl_exception_names_aml[] = diff -urN linux-2.4.0-test12/drivers/acpi/include/acgcc.h linux-2.4.0-test12-lia/drivers/acpi/include/acgcc.h --- linux-2.4.0-test12/drivers/acpi/include/acgcc.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acgcc.h Fri Nov 17 17:50:34 2000 @@ -0,0 +1,149 @@ +/****************************************************************************** + * + * Name: acgcc.h - GCC specific defines, etc. + * $Revision: 1 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACGCC_H__ +#define __ACGCC_H__ + +#define COMPILER_DEPENDENT_UINT64 unsigned long long + + +#ifdef __ia64__ +#define _IA64 + +/* Single threaded */ +#define ACPI_APPLICATION + +#define ACPI_ASM_MACROS +#define causeinterrupt(level) +#define BREAKPOINT3 +#define disable() __cli() +#define enable() __sti() +#define wbinvd() + +/*! [Begin] no source code translation */ + +#include + +#define halt() ia64_pal_halt_light() /* PAL_HALT[_LIGHT] */ +#define safe_halt() ia64_pal_halt(1) /* PAL_HALT */ + + +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + __asm__ volatile ("1: ld4 r29=%1\n" \ + ";;\n" \ + "mov ar.ccv=r29\n" \ + "mov r2=r29\n" \ + "shr.u r30=r29,1\n" \ + "and r29=-4,r29\n" \ + ";;\n" \ + "add r29=2,r29\n" \ + "and r30=1,r30\n" \ + ";;\n" \ + "add r29=r29,r30\n" \ + ";;\n" \ + "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ + ";;\n" \ + "cmp.eq p6,p7=r2,r30\n" \ + "(p7) br.dpnt.few 1b\n" \ + "cmp.gt p8,p9=3,r29\n" \ + ";;\n" \ + "(p8) mov %0=-1\n" \ + "(p9) mov %0=r0\n" \ + :"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \ + } while (0) + +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + __asm__ volatile ("1: ld4 r29=%1\n" \ + ";;\n" \ + "mov ar.ccv=r29\n" \ + "mov r2=r29\n" \ + "and r29=-4,r29\n" \ + ";;\n" \ + "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \ + ";;\n" \ + "cmp.eq p6,p7=r2,r30\n" \ + "(p7) br.dpnt.few 1b\n" \ + "and %0=1,r2\n" \ + ";;\n" \ + :"=r"(Acq):"m"(GLptr):"r2","r29","r30","memory"); \ + } while (0) +/*! [End] no source code translation !*/ + + +#else /* DO IA32 */ + + +#define ACPI_ASM_MACROS +#define causeinterrupt(level) +#define BREAKPOINT3 +#define disable() __cli() +#define enable() __sti() +#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") +#define wbinvd() + +/*! [Begin] no source code translation + * + * A brief explanation as GNU inline assembly is a bit hairy + * %0 is the output parameter in EAX ("=a") + * %1 and %2 are the input parameters in ECX ("c") + * and an immediate value ("i") respectively + * All actual register references are preceded with "%%" as in "%%edx" + * Immediate values in the assembly are preceded by "$" as in "$0x1" + * The final asm parameter are the operation altered non-output registers. + */ +#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + int dummy; \ + asm("1: movl (%1),%%eax;" \ + "movl %%eax,%%edx;" \ + "andl %2,%%edx;" \ + "btsl $0x1,%%edx;" \ + "adcl $0x0,%%edx;" \ + "lock; cmpxchgl %%edx,(%1);" \ + "jnz 1b;" \ + "cmpb $0x3,%%dl;" \ + "sbbl %%eax,%%eax" \ + :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \ + } while(0) + +#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ + do { \ + int dummy; \ + asm("1: movl (%1),%%eax;" \ + "movl %%eax,%%edx;" \ + "andl %2,%%edx;" \ + "lock; cmpxchgl %%edx,(%1);" \ + "jnz 1b;" \ + "andl $0x1,%%eax" \ + :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ + } while(0) + +/*! [End] no source code translation !*/ + +#endif /* IA 32 */ + +#endif /* __ACGCC_H__ */ diff -urN linux-2.4.0-test12/drivers/acpi/include/acglobal.h linux-2.4.0-test12-lia/drivers/acpi/include/acglobal.h --- linux-2.4.0-test12/drivers/acpi/include/acglobal.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acglobal.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acglobal.h - Declarations for global variables - * $Revision: 84 $ + * $Revision: 92 $ * *****************************************************************************/ @@ -74,13 +74,12 @@ * of each in the system. Each global points to the actual table. * */ -ACPI_EXTERN ROOT_SYSTEM_DESCRIPTOR_POINTER *acpi_gbl_RSDP; -ACPI_EXTERN ROOT_SYSTEM_DESCRIPTION_TABLE *acpi_gbl_RSDT; -ACPI_EXTERN FIRMWARE_ACPI_CONTROL_STRUCTURE *acpi_gbl_FACS; -ACPI_EXTERN FIXED_ACPI_DESCRIPTION_TABLE *acpi_gbl_FACP; -ACPI_EXTERN APIC_TABLE *acpi_gbl_APIC; -ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_DSDT; -ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_SBST; +ACPI_EXTERN RSDP_DESCRIPTOR *acpi_gbl_RSDP; +ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT; +ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; +ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_DSDT; +ACPI_EXTERN ACPI_COMMON_FACS *acpi_gbl_FACS; + /* * Since there may be multiple SSDTs and PSDTS, a single pointer is not * sufficient; Therefore, there isn't one! @@ -99,7 +98,6 @@ * (The table maps local handles to the real OS handles) */ ACPI_EXTERN ACPI_MUTEX_INFO acpi_gbl_acpi_mutex_info [NUM_MTX]; -extern ACPI_INIT_DATA acpi_gbl_acpi_init_data; /***************************************************************************** @@ -164,6 +162,7 @@ extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_system_flags; extern u32 acpi_gbl_startup_flags; +extern u8 acpi_gbl_decode_to8bit[]; /***************************************************************************** @@ -198,23 +197,8 @@ ****************************************************************************/ -ACPI_EXTERN u32 acpi_gbl_when_to_parse_methods; ACPI_EXTERN ACPI_WALK_LIST *acpi_gbl_current_walk_list; -/* Base of AML block, and pointer to current location in it */ - -ACPI_EXTERN u8 *acpi_gbl_Pcode_base; -ACPI_EXTERN u8 *acpi_gbl_Pcode; - -/* - * Length of AML block, and remaining length of current package. - */ -ACPI_EXTERN u32 acpi_gbl_Pcode_block_len; -ACPI_EXTERN u32 acpi_gbl_Pcode_len; - -ACPI_EXTERN u32 acpi_gbl_buf_seq; /* Counts allocated Buffer descriptors */ -ACPI_EXTERN u32 acpi_gbl_node_err; /* Indicate if inc_error should be called */ - /* * Handle to the last method found - used during pass1 of load */ @@ -240,10 +224,6 @@ ACPI_EXTERN ACPI_PARSE_OBJECT *acpi_gbl_parsed_namespace_root; -extern ACPI_OPCODE_INFO acpi_gbl_aml_op_info[]; -extern u8 acpi_gbl_aml_op_info_index[256]; - - /***************************************************************************** * * Hardware globals @@ -290,9 +270,10 @@ * ****************************************************************************/ +#ifdef ENABLE_DEBUGGER ACPI_EXTERN u8 acpi_gbl_method_executing; ACPI_EXTERN u8 acpi_gbl_db_terminate_threads; - +#endif /* Memory allocation metrics - Debug Only! */ diff -urN linux-2.4.0-test12/drivers/acpi/include/achware.h linux-2.4.0-test12-lia/drivers/acpi/include/achware.h --- linux-2.4.0-test12/drivers/acpi/include/achware.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/achware.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: achware.h -- hardware specific interfaces - * $Revision: 41 $ + * $Revision: 48 $ * *****************************************************************************/ @@ -31,15 +31,15 @@ ACPI_STATUS -acpi_hw_initialize( +acpi_hw_initialize ( void); ACPI_STATUS -acpi_hw_shutdown( +acpi_hw_shutdown ( void); ACPI_STATUS -acpi_hw_initialize_system_info( +acpi_hw_initialize_system_info ( void); ACPI_STATUS @@ -56,11 +56,37 @@ /* Register I/O Prototypes */ + u32 -acpi_hw_register_access ( +acpi_hw_register_bit_access ( NATIVE_UINT read_write, u8 use_lock, - u32 register_id, ... /* DWORD Value */); + u32 register_id, + ... /* DWORD Write Value */); + +u32 +acpi_hw_register_read ( + u8 use_lock, + u32 register_id); + +void +acpi_hw_register_write ( + u8 use_lock, + u32 register_id, + u32 value); + +u32 +acpi_hw_low_level_read ( + u32 width, + ACPI_GAS *reg, + u32 offset); + +void +acpi_hw_low_level_write ( + u32 width, + u32 value, + ACPI_GAS *reg, + u32 offset); void acpi_hw_clear_acpi_status ( @@ -125,6 +151,16 @@ acpi_hw_get_cx_info ( u32 cx_states[]); +ACPI_STATUS +acpi_hw_get_cx_handler ( + u32 cx_state, + ACPI_C_STATE_HANDLER *handler); + +ACPI_STATUS +acpi_hw_set_cx_handler ( + u32 cx_state, + ACPI_C_STATE_HANDLER handler); + /* Throttling Prototypes */ @@ -164,6 +200,10 @@ u32 acpi_hw_pmt_resolution ( void); + +ACPI_STATUS +acpi_get_timer ( + u32 *out_ticks); #endif /* __ACHWARE_H__ */ diff -urN linux-2.4.0-test12/drivers/acpi/include/acinterp.h linux-2.4.0-test12-lia/drivers/acpi/include/acinterp.h --- linux-2.4.0-test12/drivers/acpi/include/acinterp.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acinterp.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * $Revision: 79 $ + * $Revision: 85 $ * *****************************************************************************/ @@ -120,7 +120,9 @@ ACPI_STATUS acpi_aml_exec_create_field ( - u16 opcode, + u8 *aml_ptr, + u32 aml_length, + ACPI_NAMESPACE_NODE *node, ACPI_WALK_STATE *walk_state); ACPI_STATUS @@ -324,7 +326,8 @@ ACPI_STATUS acpi_aml_resolve_node_to_value ( - ACPI_NAMESPACE_NODE **stack_ptr); + ACPI_NAMESPACE_NODE **stack_ptr, + ACPI_WALK_STATE *walk_state); ACPI_STATUS acpi_aml_resolve_object_to_value ( @@ -440,6 +443,11 @@ acpi_aml_exit_interpreter ( void); +void +acpi_aml_truncate_for32bit_table ( + ACPI_OPERAND_OBJECT *obj_desc, + ACPI_WALK_STATE *walk_state); + u8 acpi_aml_validate_object_type ( ACPI_OBJECT_TYPE type); @@ -453,12 +461,8 @@ u8 locked); u32 -acpi_aml_buf_seq ( - void); - -u32 acpi_aml_digits_needed ( - u32 value, + ACPI_INTEGER value, u32 base); ACPI_STATUS @@ -467,6 +471,11 @@ NATIVE_CHAR *out_string); ACPI_STATUS +acpi_aml_unsigned_integer_to_string ( + ACPI_INTEGER value, + NATIVE_CHAR *out_string); + +ACPI_STATUS acpi_aml_build_copy_internal_package_object ( ACPI_OPERAND_OBJECT *source_obj, ACPI_OPERAND_OBJECT *dest_obj, @@ -480,7 +489,7 @@ ACPI_STATUS acpi_aml_system_memory_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -489,7 +498,7 @@ ACPI_STATUS acpi_aml_system_io_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -498,7 +507,7 @@ ACPI_STATUS acpi_aml_pci_config_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -507,7 +516,7 @@ ACPI_STATUS acpi_aml_embedded_controller_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -516,7 +525,7 @@ ACPI_STATUS acpi_aml_sm_bus_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, diff -urN linux-2.4.0-test12/drivers/acpi/include/aclinux.h linux-2.4.0-test12-lia/drivers/acpi/include/aclinux.h --- linux-2.4.0-test12/drivers/acpi/include/aclinux.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/include/aclinux.h Wed Nov 15 16:25:04 2000 @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * Name: aclinux.h - OS specific defines, etc. + * $Revision: 4 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACLINUX_H__ +#define __ACLINUX_H__ + + +#define ACPI_OS_NAME "Linux" + +#include +#include +#include +#include +#include +#include + +/* Linux uses GCC */ + +#include "acgcc.h" + +#undef DEBUGGER_THREADING +#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED + +/* Linux ia32 can't do int64 well */ +#ifndef _IA64 +#define ACPI_NO_INTEGER64_SUPPORT +#endif + +#if 0 + +/* Use native Linux string library */ + +#define ACPI_USE_SYSTEM_CLIBRARY + +/* Special functions */ + +#define strtoul simple_strtoul + +/* Linux clib doesn't to strupr, but we do. */ +char * +strupr(char *str); + +#endif /* 0 */ + +#endif /* __ACLINUX_H__ */ diff -urN linux-2.4.0-test12/drivers/acpi/include/aclocal.h linux-2.4.0-test12-lia/drivers/acpi/include/aclocal.h --- linux-2.4.0-test12/drivers/acpi/include/aclocal.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/aclocal.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 77 $ + * $Revision: 89 $ * *****************************************************************************/ @@ -125,7 +125,7 @@ /* TBD: [Restructure] get rid of the need for this! */ -#define TABLE_ID_DSDT (ACPI_OWNER_ID) 0xD1D1 +#define TABLE_ID_DSDT (ACPI_OWNER_ID) 0x8000 /***************************************************************************** * @@ -157,8 +157,8 @@ { u8 data_type; u8 type; /* Type associated with this name */ - u32 name; /* ACPI Name, always 4 chars per ACPI spec */ u16 owner_id; + u32 name; /* ACPI Name, always 4 chars per ACPI spec */ void *object; /* Pointer to attached ACPI object (optional) */ @@ -177,6 +177,7 @@ #define ANOBJ_AML_ATTACHMENT 0x1 #define ANOBJ_END_OF_PEER_LIST 0x2 +#define ANOBJ_DATA_WIDTH_32 0x4 /* Parent table is 64-bits */ /* @@ -190,6 +191,7 @@ ACPI_TABLE_HEADER *pointer; void *base_pointer; u8 *aml_pointer; + UINT64 physical_address; u32 aml_length; u32 length; u32 count; @@ -453,8 +455,7 @@ u32 parse_args; /* Grammar/Parse time arguments */ u32 runtime_args; /* Interpret time arguments */ - DEBUG_ONLY_MEMBERS ( - NATIVE_CHAR *name) /* op name (debug only) */ + DEBUG_ONLY_MEMBERS (NATIVE_CHAR *name) /* op name (debug only) */ } ACPI_OPCODE_INFO; @@ -481,7 +482,7 @@ DEBUG_ONLY_MEMBERS (\ NATIVE_CHAR op_name[16]) /* op name (debug only) */\ /* NON-DEBUG members below: */\ - ACPI_NAMESPACE_NODE *node;/* for use by interpreter */\ + ACPI_NAMESPACE_NODE *node; /* for use by interpreter */\ ACPI_PARSE_VALUE value; /* Value or args associated with the opcode */\ @@ -543,8 +544,9 @@ #define NEXT_OP_DOWNWARD 1 #define NEXT_OP_UPWARD 2 -#define WALK_METHOD 1 #define WALK_NON_METHOD 0 +#define WALK_METHOD 1 +#define WALK_METHOD_RESTART 2 typedef struct acpi_walk_state { @@ -557,7 +559,7 @@ u8 current_result; /* */ struct acpi_walk_state *next; /* Next Walk_state in list */ - ACPI_PARSE_OBJECT *origin; /* Start of walk */ + ACPI_PARSE_OBJECT *origin; /* Start of walk [Obsolete] */ /* TBD: Obsolete with removal of WALK procedure ? */ ACPI_PARSE_OBJECT *prev_op; /* Last op that was processed */ @@ -607,13 +609,32 @@ /* Info used by Acpi_ps_init_objects */ -typedef struct init_walk_info +typedef struct acpi_init_walk_info +{ + u16 method_count; + u16 op_region_count; + u16 field_count; + u16 op_region_init; + u16 field_init; + u16 object_count; + ACPI_TABLE_DESC *table_desc; + +} ACPI_INIT_WALK_INFO; + + +/* Info used by TBD */ + +typedef struct acpi_device_walk_info { - u32 method_count; - u32 op_region_count; + u32 flags; + u16 device_count; + u16 num_STA; + u16 num_INI; + u16 num_HID; + u16 num_PCI; ACPI_TABLE_DESC *table_desc; -} INIT_WALK_INFO; +} ACPI_DEVICE_WALK_INFO; /* TBD: [Restructure] Merge with struct above */ @@ -625,6 +646,14 @@ } ACPI_WALK_INFO; +typedef struct acpi_get_devices_info +{ + WALK_CALLBACK user_function; + void *context; + NATIVE_CHAR *hid; + +} ACPI_GET_DEVICES_INFO; + /***************************************************************************** * @@ -633,16 +662,23 @@ ****************************************************************************/ +/* PCI */ + +#define PCI_ROOT_HID_STRING "PNP0A03" +#define PCI_ROOT_HID_VALUE 0x030AD041 /* EISAID("PNP0A03") */ + + /* Sleep states */ -#define SLWA_DEBUG_LEVEL 4 -#define GTS_CALL 0 -#define GTS_WAKE 1 +#define SLWA_DEBUG_LEVEL 4 +#define GTS_CALL 0 +#define GTS_WAKE 1 /* Cx States */ -#define MAX_CX_STATE_LATENCY 0xFFFFFFFF -#define MAX_CX_STATES 4 +#define MAX_CX_STATE_LATENCY 0xFFFFFFFF +#define MAX_CX_STATES 4 + /* * The #define's and enum below establish an abstract way of identifying what @@ -650,66 +686,85 @@ * values as they are used in switch statements and offset calculations. */ -#define REGISTER_BLOCK_MASK 0xFF00 -#define BIT_IN_REGISTER_MASK 0x00FF -#define PM1_EVT 0x0100 -#define PM1_CONTROL 0x0200 -#define PM2_CONTROL 0x0300 -#define PM_TIMER 0x0400 -#define PROCESSOR_BLOCK 0x0500 -#define GPE0_STS_BLOCK 0x0600 -#define GPE0_EN_BLOCK 0x0700 -#define GPE1_STS_BLOCK 0x0800 -#define GPE1_EN_BLOCK 0x0900 - -enum -{ - /* PM1 status register ids */ +#define REGISTER_BLOCK_MASK 0xFF00 /* Register Block Id */ +#define BIT_IN_REGISTER_MASK 0x00FF /* Bit Id in the Register Block Id */ +#define BYTE_IN_REGISTER_MASK 0x00FF /* Register Offset in the Register Block */ - TMR_STS = (PM1_EVT | 0x01), - BM_STS, - GBL_STS, - PWRBTN_STS, - SLPBTN_STS, - RTC_STS, - WAK_STS, +#define REGISTER_BLOCK_ID(reg_id) (reg_id & REGISTER_BLOCK_MASK) +#define REGISTER_BIT_ID(reg_id) (reg_id & BIT_IN_REGISTER_MASK) +#define REGISTER_OFFSET(reg_id) (reg_id & BYTE_IN_REGISTER_MASK) - /* PM1 enable register ids */ +/* + * Access Rule + * To access a Register Bit: + * -> Use Bit Name (= Register Block Id | Bit Id) defined in the enum. + * + * To access a Register: + * -> Use Register Id (= Register Block Id | Register Offset) + */ - TMR_EN, - /* need to skip 1 enable number since there's no bus master enable register */ - GBL_EN = (PM1_EVT | 0x0A), - PWRBTN_EN, - SLPBTN_EN, - RTC_EN, - /* PM1 control register ids */ +/* + * Register Block Id + */ +#define PM1_STS 0x0100 +#define PM1_EN 0x0200 +#define PM1_CONTROL 0x0300 +#define PM2_CONTROL 0x0400 +#define PM_TIMER 0x0500 +#define PROCESSOR_BLOCK 0x0600 +#define GPE0_STS_BLOCK 0x0700 +#define GPE0_EN_BLOCK 0x0800 +#define GPE1_STS_BLOCK 0x0900 +#define GPE1_EN_BLOCK 0x0A00 +#define SMI_CMD_BLOCK 0x0B00 - SCI_EN = (PM1_CONTROL | 0x01), - BM_RLD, - GBL_RLS, - SLP_TYPE_A, - SLP_TYPE_B, - SLP_EN, +/* + * Address space bitmasks for mmio or io spaces + */ - /* PM2 control register ids */ +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 - ARB_DIS = (PM2_CONTROL | 0x01), +/* + * Control bit definitions + */ +#define TMR_STS (PM1_STS | 0x01) +#define BM_STS (PM1_STS | 0x02) +#define GBL_STS (PM1_STS | 0x03) +#define PWRBTN_STS (PM1_STS | 0x04) +#define SLPBTN_STS (PM1_STS | 0x05) +#define RTC_STS (PM1_STS | 0x06) +#define WAK_STS (PM1_STS | 0x07) - /* PM Timer register ids */ +#define TMR_EN (PM1_EN | 0x01) + /* no BM_EN */ +#define GBL_EN (PM1_EN | 0x03) +#define PWRBTN_EN (PM1_EN | 0x04) +#define SLPBTN_EN (PM1_EN | 0x05) +#define RTC_EN (PM1_EN | 0x06) +#define WAK_EN (PM1_EN | 0x07) - TMR_VAL = (PM_TIMER | 0x01), +#define SCI_EN (PM1_CONTROL | 0x01) +#define BM_RLD (PM1_CONTROL | 0x02) +#define GBL_RLS (PM1_CONTROL | 0x03) +#define SLP_TYPE_A (PM1_CONTROL | 0x04) +#define SLP_TYPE_B (PM1_CONTROL | 0x05) +#define SLP_EN (PM1_CONTROL | 0x06) - GPE0_STS = (GPE0_STS_BLOCK | 0x01), - GPE0_EN = (GPE0_EN_BLOCK | 0x01), +#define ARB_DIS (PM2_CONTROL | 0x01) - GPE1_STS = (GPE1_STS_BLOCK | 0x01), - GPE1_EN = (GPE0_EN_BLOCK | 0x01), +#define TMR_VAL (PM_TIMER | 0x01) - /* Last register value is one less than LAST_REG */ +#define GPE0_STS (GPE0_STS_BLOCK | 0x01) +#define GPE0_EN (GPE0_EN_BLOCK | 0x01) - LAST_REG -}; +#define GPE1_STS (GPE1_STS_BLOCK | 0x01) +#define GPE1_EN (GPE1_EN_BLOCK | 0x01) #define TMR_STS_MASK 0x0001 @@ -720,8 +775,9 @@ #define RTC_STS_MASK 0x0400 #define WAK_STS_MASK 0x8000 -#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK | PWRBTN_STS_MASK | \ - SLPBTN_STS_MASK | RTC_STS_MASK | WAK_STS_MASK) +#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK \ + | PWRBTN_STS_MASK | SLPBTN_STS_MASK \ + | RTC_STS_MASK | WAK_STS_MASK) #define TMR_EN_MASK 0x0001 #define GBL_EN_MASK 0x0020 @@ -736,6 +792,7 @@ #define SLP_EN_MASK 0x2000 #define ARB_DIS_MASK 0x0001 +#define TMR_VAL_MASK 0xFFFFFFFF #define GPE0_STS_MASK #define GPE0_EN_MASK @@ -747,16 +804,6 @@ #define ACPI_READ 1 #define ACPI_WRITE 2 -#define LOW_BYTE 0x00FF -#define ONE_BYTE 0x08 - -#ifndef SET - #define SET 1 -#endif -#ifndef CLEAR - #define CLEAR 0 -#endif - /* Plug and play */ @@ -796,24 +843,11 @@ /* MUST HAVES */ - -typedef enum -{ - DWORD_DEVICE_ID, - STRING_PTR_DEVICE_ID, - STRING_DEVICE_ID - -} DEVICE_ID_TYPE; +#define DEVICE_ID_LENGTH 0x09 typedef struct { - DEVICE_ID_TYPE type; - union - { - u32 number; - NATIVE_CHAR *string_ptr; - NATIVE_CHAR buffer[9]; - } data; + NATIVE_CHAR buffer[DEVICE_ID_LENGTH]; } DEVICE_ID; diff -urN linux-2.4.0-test12/drivers/acpi/include/acmacros.h linux-2.4.0-test12-lia/drivers/acpi/include/acmacros.h --- linux-2.4.0-test12/drivers/acpi/include/acmacros.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acmacros.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 48 $ + * $Revision: 56 $ * *****************************************************************************/ @@ -128,6 +128,11 @@ #define MUL_16(a) _MUL(a,4) #define MOD_16(a) _MOD(a,16) +/* + * Divide and Modulo + */ +#define ACPI_DIVIDE(n,d) ((n) / (d)) +#define ACPI_MODULO(n,d) ((n) % (d)) /* * Rounding macros (Power of two boundaries only) @@ -137,17 +142,35 @@ #define ROUND_UP(value,boundary) (((value) + ((boundary)-1)) & (~((boundary)-1))) #define ROUND_DOWN_TO_32_BITS(a) ROUND_DOWN(a,4) +#define ROUND_DOWN_TO_64_BITS(a) ROUND_DOWN(a,8) #define ROUND_DOWN_TO_NATIVE_WORD(a) ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY) #define ROUND_UP_TO_32_bITS(a) ROUND_UP(a,4) +#define ROUND_UP_TO_64_bITS(a) ROUND_UP(a,8) #define ROUND_UP_TO_NATIVE_WORD(a) ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY) +#define ROUND_PTR_UP_TO_4(a,b) ((b *)(((NATIVE_UINT)(a) + 3) & ~3)) +#define ROUND_PTR_UP_TO_8(a,b) ((b *)(((NATIVE_UINT)(a) + 7) & ~7)) + +#define ROUND_UP_TO_1_k(a) (((a) + 1023) >> 10) #ifdef DEBUG_ASSERT #undef DEBUG_ASSERT #endif +/* Macros for GAS addressing */ + +#define ACPI_PCI_DEVICE_MASK (UINT64) 0x0000FFFF00000000 +#define ACPI_PCI_FUNCTION_MASK (UINT64) 0x00000000FFFF0000 +#define ACPI_PCI_REGISTER_MASK (UINT64) 0x000000000000FFFF + +#define ACPI_PCI_FUNCTION(a) (u32) ((((a) & ACPI_PCI_FUNCTION_MASK) >> 16)) +#define ACPI_PCI_DEVICE(a) (u32) ((((a) & ACPI_PCI_DEVICE_MASK) >> 32)) +#define ACPI_PCI_REGISTER(a) (u32) (((a) & ACPI_PCI_REGISTER_MASK)) +#define ACPI_PCI_DEVFUN(a) (u32) ((ACPI_PCI_DEVICE(a) << 16) | ACPI_PCI_FUNCTION(a)) + + /* * An ACPI_HANDLE (which is actually an ACPI_NAMESPACE_NODE *) can appear in some contexts, * such as on ap_obj_stack, where a pointer to an ACPI_OPERAND_OBJECT can also @@ -216,14 +239,16 @@ #define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) #define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f)) -#define GET_CURRENT_ARG_TYPE(list) (list & 0x1F) -#define INCREMENT_ARG_LIST(list) (list >>= ARG_TYPE_WIDTH) +#define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) +#define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) /* * Reporting macros that are never compiled out */ +#define PARAM_LIST(pl) pl + /* * Error reporting. These versions add callers module and line#. Since * _THIS_MODULE gets compiled out when ACPI_DEBUG isn't defined, only @@ -232,23 +257,32 @@ #ifdef ACPI_DEBUG -#define REPORT_INFO(a) _report_info(_THIS_MODULE,__LINE__,_COMPONENT,a) -#define REPORT_ERROR(a) _report_error(_THIS_MODULE,__LINE__,_COMPONENT,a) -#define REPORT_WARNING(a) _report_warning(_THIS_MODULE,__LINE__,_COMPONENT,a) +#define REPORT_INFO(fp) {_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_ERROR(fp) {_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_WARNING(fp) {_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} #else -#define REPORT_INFO(a) _report_info("",__LINE__,_COMPONENT,a) -#define REPORT_ERROR(a) _report_error("",__LINE__,_COMPONENT,a) -#define REPORT_WARNING(a) _report_warning("",__LINE__,_COMPONENT,a) +#define REPORT_INFO(fp) {_report_info("ACPI",__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_ERROR(fp) {_report_error("ACPI",__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} +#define REPORT_WARNING(fp) {_report_warning("ACPI",__LINE__,_COMPONENT); \ + debug_print_raw PARAM_LIST(fp);} #endif /* Error reporting. These versions pass thru the module and line# */ -#define _REPORT_INFO(a,b,c,d) _report_info(a,b,c,d) -#define _REPORT_ERROR(a,b,c,d) _report_error(a,b,c,d) -#define _REPORT_WARNING(a,b,c,d) _report_warning(a,b,c,d) +#define _REPORT_INFO(a,b,c,fp) {_report_info(a,b,c); \ + debug_print_raw PARAM_LIST(fp);} +#define _REPORT_ERROR(a,b,c,fp) {_report_error(a,b,c); \ + debug_print_raw PARAM_LIST(fp);} +#define _REPORT_WARNING(a,b,c,fp) {_report_warning(a,b,c); \ + debug_print_raw PARAM_LIST(fp);} /* Buffer dump macros */ @@ -269,7 +303,7 @@ */ #define FUNCTION_TRACE(a) char * _proc_name = a;\ - function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a) + function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a) #define FUNCTION_TRACE_PTR(a,b) char * _proc_name = a;\ function_trace_ptr(_THIS_MODULE,__LINE__,_COMPONENT,a,(void *)b) #define FUNCTION_TRACE_U32(a,b) char * _proc_name = a;\ @@ -291,7 +325,7 @@ /* Conditional execution */ -#define DEBUG_EXEC(a) a; +#define DEBUG_EXEC(a) a #define NORMAL_EXEC(a) #define DEBUG_DEFINE(a) a; @@ -329,8 +363,6 @@ * */ -#define PARAM_LIST(pl) pl - #define TEST_DEBUG_SWITCH(lvl) if (((lvl) & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer)) #define DEBUG_PRINT(lvl,fp) TEST_DEBUG_SWITCH(lvl) {\ @@ -398,7 +430,7 @@ * DEBUG_PRINT stuff (set by ACPI_DEBUG) is on, or not. */ #ifdef ENABLE_DEBUGGER -#define DEBUGGER_EXEC(a) a; +#define DEBUGGER_EXEC(a) a #else #define DEBUGGER_EXEC(a) #endif @@ -412,7 +444,7 @@ #undef DEBUG_ONLY_MEMBERS #define DEBUG_ONLY_MEMBERS(a) #undef OP_INFO_ENTRY -#define OP_INFO_ENTRY(opcode,flags,name,Pargs,Iargs) {opcode,flags,Pargs,Iargs} +#define OP_INFO_ENTRY(flags,name,Pargs,Iargs) {flags,Pargs,Iargs} #endif @@ -431,5 +463,6 @@ #define ADD_OBJECT_NAME(a,b) #endif + #endif /* ACMACROS_H */ diff -urN linux-2.4.0-test12/drivers/acpi/include/acnamesp.h linux-2.4.0-test12-lia/drivers/acpi/include/acnamesp.h --- linux-2.4.0-test12/drivers/acpi/include/acnamesp.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acnamesp.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 94 $ + * $Revision: 98 $ * *****************************************************************************/ @@ -62,6 +62,36 @@ ACPI_STATUS +acpi_ns_load_namespace ( + void); + +ACPI_STATUS +acpi_ns_initialize_objects ( + void); + +ACPI_STATUS +acpi_ns_initialize_devices ( + u32 flags); + + +/* Namespace init - nsxfinit */ + +ACPI_STATUS +acpi_ns_init_one_device ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +ACPI_STATUS +acpi_ns_init_one_object ( + ACPI_HANDLE obj_handle, + u32 level, + void *context, + void **return_value); + + +ACPI_STATUS acpi_ns_walk_namespace ( OBJECT_TYPE_INTERNAL type, ACPI_HANDLE start_object, @@ -87,6 +117,11 @@ /* Namespace loading - nsload */ ACPI_STATUS +acpi_ns_one_complete_parse ( + u32 pass_number, + ACPI_TABLE_DESC *table_desc); + +ACPI_STATUS acpi_ns_parse_table ( ACPI_TABLE_DESC *table_desc, ACPI_NAMESPACE_NODE *scope); @@ -319,10 +354,6 @@ ACPI_NAMESPACE_NODE *node, OBJECT_TYPE_INTERNAL type, ACPI_NAMESPACE_NODE **ret_node); - -ACPI_NAMESPACE_NODE * -acpi_ns_create_node ( - u32 acpi_name); void acpi_ns_install_node ( diff -urN linux-2.4.0-test12/drivers/acpi/include/acobject.h linux-2.4.0-test12-lia/drivers/acpi/include/acobject.h --- linux-2.4.0-test12/drivers/acpi/include/acobject.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acobject.h Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only) - * $Revision: 71 $ + * $Revision: 75 $ * *****************************************************************************/ @@ -58,7 +58,7 @@ */ -#define ACPI_OBJECT_COMMON_HEADER /* Two 32-bit fields, one pointer, 8-bit flag */\ +#define ACPI_OBJECT_COMMON_HEADER /* 32-bits plus 8-bit flag */\ u8 data_type; /* To differentiate various internal objs */\ u8 type; /* ACPI_OBJECT_TYPE */\ u16 reference_count; /* For object deletion management */\ @@ -74,7 +74,7 @@ /* * Common bitfield for the field objects */ -#define ACPI_COMMON_FIELD_INFO /* Three 32-bit values */\ +#define ACPI_COMMON_FIELD_INFO /* Three 32-bit values plus 8*/\ u8 granularity;\ u16 length; \ u32 offset; /* Byte offset within containing object */\ @@ -111,7 +111,7 @@ { ACPI_OBJECT_COMMON_HEADER - u32 value; + ACPI_INTEGER value; } ACPI_OBJECT_NUMBER; @@ -155,8 +155,9 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO - u32 sequence; /* Container's sequence number */ + union acpi_operand_obj *extra; /* Pointer to executable AML (in field definition) */ + ACPI_NAMESPACE_NODE *node; /* containing object */ union acpi_operand_obj *container; /* Containing object (Buffer) */ } ACPI_OBJECT_FIELD_UNIT; @@ -218,16 +219,10 @@ u8 space_id; u32 length; - u32 address; - void *region_context; /* Region Specific data (Handler->Context - optional things like PCI _ADR) */ - - /* TBD: [Restructure] This field can go away when Pass3 is implemented */ - union acpi_operand_obj *method; /* Associated control method */ - + ACPI_PHYSICAL_ADDRESS address; + union acpi_operand_obj *extra; /* Pointer to executable AML (in region definition) */ union acpi_operand_obj *addr_handler; /* Handler for system notifies */ - ACPI_NAMESPACE_NODE *REGmethod; /* _REG method for this region (if any) */ ACPI_NAMESPACE_NODE *node; /* containing object */ union acpi_operand_obj *next; @@ -372,6 +367,27 @@ } ACPI_OBJECT_REFERENCE; +/* + * Extra object is used as additional storage for types that + * have AML code in their declarations (Term_args) that must be + * evaluated at run time. + * + * Currently: Region and Field_unit types + */ + +typedef struct /* EXTRA */ +{ + ACPI_OBJECT_COMMON_HEADER + u8 byte_fill1; + u16 word_fill1; + u32 pcode_length; + u8 *pcode; + ACPI_NAMESPACE_NODE *method_REG; /* _REG method for this region (if any) */ + void *region_context; /* Region-specific data */ + +} ACPI_OBJECT_EXTRA; + + /****************************************************************************** * * ACPI_OPERAND_OBJECT Descriptor - a giant union of all of the above @@ -401,6 +417,7 @@ ACPI_OBJECT_REFERENCE reference; ACPI_OBJECT_NOTIFY_HANDLER notify_handler; ACPI_OBJECT_ADDR_HANDLER addr_handler; + ACPI_OBJECT_EXTRA extra; } ACPI_OPERAND_OBJECT; diff -urN linux-2.4.0-test12/drivers/acpi/include/acoutput.h linux-2.4.0-test12-lia/drivers/acpi/include/acoutput.h --- linux-2.4.0-test12/drivers/acpi/include/acoutput.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acoutput.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acoutput.h -- debug output - * $Revision: 63 $ + * $Revision: 66 $ * *****************************************************************************/ @@ -60,6 +60,8 @@ #define DEBUGGER 0x00100000 #define ALL_COMPONENTS 0x001FFFFF +#define COMPONENT_DEFAULT (ALL_COMPONENTS) + /* Exception level -- used in the global "Debug_level" */ @@ -104,12 +106,12 @@ #define VERBOSE_TABLES 0x40000000 #define VERBOSE_EVENTS 0x80000000 -#define VERBOSE_ALL 0x70000000 +#define VERBOSE_ALL 0xF0000000 /* Defaults for Debug_level, debug and normal */ -#define DEBUG_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT | TRACE_TABLES | TRACE_IO) +#define DEBUG_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT) #define NORMAL_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT) #define DEBUG_ALL (VERBOSE_AML_DISASSEMBLE | TRACE_ALL | ACPI_ALL) diff -urN linux-2.4.0-test12/drivers/acpi/include/acparser.h linux-2.4.0-test12-lia/drivers/acpi/include/acparser.h --- linux-2.4.0-test12/drivers/acpi/include/acparser.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acparser.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: acparser.h - AML Parser subcomponent prototypes and defines - * $Revision: 46 $ + * $Revision: 47 $ * *****************************************************************************/ @@ -188,7 +188,8 @@ acpi_ps_pop_scope ( ACPI_PARSE_STATE *parser_state, ACPI_PARSE_OBJECT **op, - u32 *arg_list); + u32 *arg_list, + u32 *arg_count); ACPI_STATUS acpi_ps_push_scope ( diff -urN linux-2.4.0-test12/drivers/acpi/include/acpiosxf.h linux-2.4.0-test12-lia/drivers/acpi/include/acpiosxf.h --- linux-2.4.0-test12/drivers/acpi/include/acpiosxf.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acpiosxf.h Wed Nov 15 16:25:04 2000 @@ -112,7 +112,7 @@ ACPI_STATUS acpi_os_map_memory ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, u32 length, void **logical_address); @@ -187,6 +187,37 @@ void acpi_os_out32 ( ACPI_IO_ADDRESS out_port, + u32 value); + +/* + * Platform/Hardware independent physical memory interfaces + */ + +u8 +acpi_os_mem_in8 ( + ACPI_PHYSICAL_ADDRESS in_addr); + +u16 +acpi_os_mem_in16 ( + ACPI_PHYSICAL_ADDRESS in_addr); + +u32 +acpi_os_mem_in32 ( + ACPI_PHYSICAL_ADDRESS in_addr); + +void +acpi_os_mem_out8 ( + ACPI_PHYSICAL_ADDRESS out_addr, + u8 value); + +void +acpi_os_mem_out16 ( + ACPI_PHYSICAL_ADDRESS out_addr, + u16 value); + +void +acpi_os_mem_out32 ( + ACPI_PHYSICAL_ADDRESS out_addr, u32 value); diff -urN linux-2.4.0-test12/drivers/acpi/include/acpixf.h linux-2.4.0-test12-lia/drivers/acpi/include/acpixf.h --- linux-2.4.0-test12/drivers/acpi/include/acpixf.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/acpixf.h Wed Nov 15 16:25:04 2000 @@ -35,8 +35,12 @@ */ ACPI_STATUS -acpi_initialize ( - ACPI_INIT_DATA *init_data); +acpi_initialize_subsystem ( + void); + +ACPI_STATUS +acpi_enable_subsystem ( + u32 flags); ACPI_STATUS acpi_terminate ( @@ -65,8 +69,12 @@ */ ACPI_STATUS -acpi_load_firmware_tables ( - void); +acpi_find_root_pointer ( + ACPI_PHYSICAL_ADDRESS *rsdp_physical_address); + +ACPI_STATUS +acpi_load_tables ( + ACPI_PHYSICAL_ADDRESS rsdp_physical_address); ACPI_STATUS acpi_load_table ( @@ -94,10 +102,6 @@ */ ACPI_STATUS -acpi_load_namespace ( - void); - -ACPI_STATUS acpi_walk_namespace ( ACPI_OBJECT_TYPE type, ACPI_HANDLE start_object, @@ -107,6 +111,13 @@ void * *return_value); ACPI_STATUS +acpi_get_devices ( + NATIVE_CHAR *HID, + WALK_CALLBACK user_function, + void *context, + void **return_value); + +ACPI_STATUS acpi_get_name ( ACPI_HANDLE handle, u32 name_type, @@ -203,6 +214,14 @@ void *context); ACPI_STATUS +acpi_acquire_global_lock ( + void); + +ACPI_STATUS +acpi_release_global_lock ( + void); + +ACPI_STATUS acpi_remove_gpe_handler ( u32 gpe_number, GPE_HANDLER handler); @@ -259,11 +278,11 @@ ACPI_STATUS acpi_set_firmware_waking_vector ( - void *physical_address); + ACPI_PHYSICAL_ADDRESS physical_address); ACPI_STATUS acpi_get_firmware_waking_vector ( - void **physical_address); + ACPI_PHYSICAL_ADDRESS *physical_address); ACPI_STATUS acpi_get_processor_throttling_info ( diff -urN linux-2.4.0-test12/drivers/acpi/include/actables.h linux-2.4.0-test12-lia/drivers/acpi/include/actables.h --- linux-2.4.0-test12/drivers/acpi/include/actables.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actables.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actables.h - ACPI table management - * $Revision: 20 $ + * $Revision: 27 $ * *****************************************************************************/ @@ -37,19 +37,26 @@ u16 table_id, ACPI_TABLE_DESC **table_desc); - /* - * Acpi_tbfac - FACP, FACS utilities + * tbconvrt - Table conversion routines */ ACPI_STATUS -acpi_tb_get_table_facs ( - ACPI_TABLE_HEADER *buffer_ptr, +acpi_tb_convert_to_xsdt ( + ACPI_TABLE_DESC *table_info, + u32 *number_of_tables); + +ACPI_STATUS +acpi_tb_convert_table_fadt ( + void); + +ACPI_STATUS +acpi_tb_build_common_facs ( ACPI_TABLE_DESC *table_info); /* - * Acpi_tbget - Table "get" routines + * tbget - Table "get" routines */ ACPI_STATUS @@ -60,13 +67,22 @@ ACPI_STATUS acpi_tb_get_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, + ACPI_TABLE_HEADER *buffer_ptr, + ACPI_TABLE_DESC *table_info); + +ACPI_STATUS +acpi_tb_verify_rsdp ( + ACPI_PHYSICAL_ADDRESS RSDP_physical_address); + +ACPI_STATUS +acpi_tb_get_table_facs ( ACPI_TABLE_HEADER *buffer_ptr, ACPI_TABLE_DESC *table_info); /* - * Acpi_tbgetall - Get all firmware ACPI tables + * tbgetall - Get all firmware ACPI tables */ ACPI_STATUS @@ -76,7 +92,7 @@ /* - * Acpi_tbinstall - Table installation + * tbinstall - Table installation */ ACPI_STATUS @@ -96,7 +112,7 @@ /* - * Acpi_tbremove - Table removal and deletion + * tbremove - Table removal and deletion */ void @@ -107,17 +123,21 @@ acpi_tb_delete_acpi_table ( ACPI_TABLE_TYPE type); -ACPI_TABLE_DESC * +void acpi_tb_delete_single_table ( ACPI_TABLE_DESC *table_desc); +ACPI_TABLE_DESC * +acpi_tb_uninstall_table ( + ACPI_TABLE_DESC *table_desc); + void acpi_tb_free_acpi_tables_of_type ( ACPI_TABLE_DESC *table_info); /* - * Acpi_tbrsd - RSDP, RSDT utilities + * tbrsd - RSDP, RSDT utilities */ ACPI_STATUS @@ -135,7 +155,7 @@ /* - * Acpi_tbutils - common table utilities + * tbutils - common table utilities */ u8 @@ -144,7 +164,7 @@ ACPI_STATUS acpi_tb_map_acpi_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, u32 *size, void **logical_address); diff -urN linux-2.4.0-test12/drivers/acpi/include/actbl.h linux-2.4.0-test12-lia/drivers/acpi/include/actbl.h --- linux-2.4.0-test12/drivers/acpi/include/actbl.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actbl.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actbl.h - Table data structures defined in ACPI specification - * $Revision: 34 $ + * $Revision: 43 $ * *****************************************************************************/ @@ -31,32 +31,47 @@ * Values for description table header signatures */ -#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 FACP_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 SSDT_SIG "SSDT" /* Secondary System Description Table */ -#define SBST_SIG "SBST" /* Smart Battery Specification Table */ -#define BOOT_SIG "BOOT" /* Boot table */ +#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 BOOT_SIG "BOOT" /* Boot table */ -#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ +#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ /* values of Mapic.Model */ -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 /* values of Type in APIC_HEADER */ -#define APIC_PROC 0 -#define APIC_IO 1 +#define APIC_PROC 0 +#define APIC_IO 1 /* + * Common table types. The base code can remain + * constant if the underlying tables are changed + */ +#define RSDT_DESCRIPTOR RSDT_DESCRIPTOR_REV2 +#define XSDT_DESCRIPTOR XSDT_DESCRIPTOR_REV2 +#define FACS_DESCRIPTOR FACS_DESCRIPTOR_REV2 +#define FADT_DESCRIPTOR FADT_DESCRIPTOR_REV2 + + +#pragma pack(1) + +/* * Architecture-independent tables * The architecture dependent tables are in separate files */ @@ -66,10 +81,14 @@ NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ u8 checksum; /* to make sum of struct == 0 */ NATIVE_CHAR oem_id [6]; /* OEM identification */ - u8 reserved; /* reserved - must be zero */ - u32 rsdt_physical_address; /* physical address of RSDT */ + u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */ + u32 rsdt_physical_address; /* 32-bit physical address of RSDT */ + u32 length; /* XSDT Length in bytes including hdr */ + UINT64 xsdt_physical_address; /* 64-bit physical address of XSDT */ + u8 extended_checksum; /* Checksum of entire table */ + NATIVE_CHAR reserved [3]; /* reserved field must be 0 */ -} ROOT_SYSTEM_DESCRIPTOR_POINTER; +} RSDP_DESCRIPTOR; typedef struct /* ACPI common table header */ @@ -88,6 +107,15 @@ } ACPI_TABLE_HEADER; +typedef struct /* Common FACS for internal use */ +{ + u32 *global_lock; + UINT64 *firmware_waking_vector; + u8 vector_width; + +} ACPI_COMMON_FACS; + + typedef struct /* APIC Table */ { ACPI_TABLE_HEADER header; /* table header */ @@ -146,6 +174,9 @@ } SMART_BATTERY_DESCRIPTION_TABLE; +#pragma pack() + + /* * ACPI Table information. We save the table address, length, * and type of memory allocation (mapped or allocated) for each @@ -175,16 +206,12 @@ } ACPI_TABLE_SUPPORT; - /* * Get the architecture-specific tables */ -#ifdef IA64 -#include "actbl64.h" -#else -#include "actbl32.h" -#endif - +#include "actbl1.h" /* Acpi 1.0 table defintions */ +#include "actbl71.h" /* Acpi 0.71 IA-64 Extension table defintions */ +#include "actbl2.h" /* Acpi 2.0 table definitions */ #endif /* __ACTBL_H__ */ diff -urN linux-2.4.0-test12/drivers/acpi/include/actbl1.h linux-2.4.0-test12-lia/drivers/acpi/include/actbl1.h --- linux-2.4.0-test12/drivers/acpi/include/actbl1.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actbl1.h Wed Nov 15 16:25:04 2000 @@ -0,0 +1,123 @@ +/****************************************************************************** + * + * Name: actbl1.h - ACPI 1.0 tables + * $Revision: 15 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL1_H__ +#define __ACTBL1_H__ + +#pragma pack(1) + +/*************************************/ +/* ACPI Specification Rev 1.0 for */ +/* the Root System Description Table */ +/*************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + u32 table_offset_entry [1]; /* Array of pointers to other */ + /* ACPI tables */ +} RSDT_DESCRIPTOR_REV1; + + +/***************************************/ +/* ACPI Specification Rev 1.0 for */ +/* the Firmware ACPI Control Structure */ +/***************************************/ +typedef struct +{ + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 firmware_waking_vector; /* ACPI OS waking vector */ + u32 global_lock; /* Global Lock */ + u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ + u32 reserved1 : 31; /* must be 0 */ + u8 resverved3 [40]; /* reserved - must be zero */ + +} FACS_DESCRIPTOR_REV1; + + +/************************************/ +/* ACPI Specification Rev 1.0 for */ +/* the Fixed ACPI Description Table */ +/************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* table header */ + u32 firmware_ctrl; /* Physical address of FACS */ + u32 dsdt; /* Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 reserved1; /* reserved */ + u16 sci_int; /* System vector of SCI interrupt */ + u32 smi_cmd; /* Port address of SMI command port */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ + u8 reserved2; /* reserved - must be zero */ + u32 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ + u32 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ + u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u32 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ + u32 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 reserved3; /* reserved */ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u16 flush_size; /* Size of area read to flush caches */ + u16 flush_stride; /* Stride used in flushing caches */ + u8 duty_offset; /* bit location of duty cycle field in p_cnt reg */ + u8 duty_width; /* bit width of duty cycle field in p_cnt reg */ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u8 reserved4; /* reserved */ + u8 reserved4a; /* reserved */ + u8 reserved4b; /* reserved */ + u32 wb_invd : 1; /* wbinvd instruction works properly */ + u32 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */ + u32 proc_c1 : 1; /* all processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ + u32 reserved5 : 23; /* reserved - must be zero */ + +} FADT_DESCRIPTOR_REV1; + +#pragma pack() + +#endif /* __ACTBL1_H__ */ + + diff -urN linux-2.4.0-test12/drivers/acpi/include/actbl2.h linux-2.4.0-test12-lia/drivers/acpi/include/actbl2.h --- linux-2.4.0-test12/drivers/acpi/include/actbl2.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actbl2.h Wed Nov 15 16:25:04 2000 @@ -0,0 +1,189 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * $Revision: 19 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + +/**************************************/ +/* Prefered Power Management Profiles */ +/**************************************/ +#define PM_UNSPECIFIED 0 +#define PM_DESKTOP 1 +#define PM_MOBILE 2 +#define PM_WORKSTATION 3 +#define PM_ENTERPRISE_SERVER 4 +#define PM_SOHO_SERVER 5 +#define PM_APPLIANCE_PC 6 + +/*********************************************/ +/* ACPI Boot Arch Flags, See spec Table 5-10 */ +/*********************************************/ +#define BAF_LEGACY_DEVICES 0x0001 +#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 + +#define FADT2_REVISION_ID 3 + +#pragma pack(1) + +/*************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Root System Description Table */ +/*************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + u32 table_offset_entry [1]; /* Array of pointers to */ + /* other tables' headers */ +} RSDT_DESCRIPTOR_REV2; + + +/********************************************/ +/* ACPI Specification Rev 2.0 for the */ +/* Extended System Description Table (XSDT) */ +/********************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + UINT64 table_offset_entry [1]; /* Array of pointers to */ + /* other tables' headers */ +} XSDT_DESCRIPTOR_REV2; + +/***************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Firmware ACPI Control Structure */ +/***************************************/ +typedef struct +{ + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */ + u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */ + u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ + u32 reserved1 : 31; /* must be 0 */ + UINT64 Xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */ + u8 version; /* Version of this table */ + u8 reserved3 [31]; /* reserved - must be zero */ + +} FACS_DESCRIPTOR_REV2; + + +/***************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Generic Address Structure (GAS) */ +/***************************************/ +typedef struct +{ + u8 address_space_id; /* Address space where struct or register exists. */ + u8 register_bit_width; /* Size in bits of given register */ + u8 register_bit_offset; /* Bit offset within the register */ + u8 reserved; /* Must be 0 */ + UINT64 address; /* 64-bit address of struct or register */ + +} ACPI_GAS; + + +/************************************/ +/* ACPI Specification Rev 2.0 for */ +/* the Fixed ACPI Description Table */ +/************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* table header */ + u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ + u32 V1_dsdt; /* 32-bit physical address of DSDT */ + u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ + u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ + u16 sci_int; /* System vector of SCI interrupt */ + u32 smi_cmd; /* Port address of SMI command port */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ + u8 pstate_cnt; /* processor performance state control*/ + u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ + u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ + u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u32 V1_gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ + u32 V1_gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u16 flush_size; /* number of flush strides that need to be read */ + u16 flush_stride; /* Processor's memory cache line width, in bytes */ + u8 duty_offset; /* Processor’s duty cycle index in processor's P_CNT reg*/ + u8 duty_width; /* Processor’s duty cycle value bit width in P_CNT register.*/ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ + u8 reserved2; /* reserved */ + u32 wb_invd : 1; /* wbinvd instruction works properly */ + u32 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */ + u32 proc_c1 : 1; /* all processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ + u32 dock_cap : 1; /* Supports Docking */ + u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/ + u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed. */ + u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices.*/ + u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */ + /* must be executed after writing the SLP_TYPx register. */ + u32 reserved6 : 18; /* reserved - must be zero */ + + ACPI_GAS reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the Reset_register port to reset the system. */ + u8 reserved7[3]; /* These three bytes must be zero */ + UINT64 Xfirmware_ctrl; /* 64-bit physical address of FACS */ + UINT64 Xdsdt; /* 64-bit physical address of DSDT */ + ACPI_GAS Xpm1a_evt_blk; /* Extended Power Mgt 1a Acpi_event Reg Blk address */ + ACPI_GAS Xpm1b_evt_blk; /* Extended Power Mgt 1b Acpi_event Reg Blk address */ + ACPI_GAS Xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ + ACPI_GAS Xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ + ACPI_GAS Xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ + ACPI_GAS Xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ + ACPI_GAS Xgpe0blk; /* Extended General Purpose Acpi_event 0 Reg Blk address */ + ACPI_GAS Xgpe1_blk; /* Extended General Purpose Acpi_event 1 Reg Blk address */ + +} FADT_DESCRIPTOR_REV2; + + +#pragma pack() + +#endif /* __ACTBL2_H__ */ + diff -urN linux-2.4.0-test12/drivers/acpi/include/actbl32.h linux-2.4.0-test12-lia/drivers/acpi/include/actbl32.h --- linux-2.4.0-test12/drivers/acpi/include/actbl32.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actbl32.h Wed Dec 31 16:00:00 1969 @@ -1,115 +0,0 @@ -/****************************************************************************** - * - * Name: actbl32.h - ACPI tables specific to IA32 - * $Revision: 11 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __ACTBL32_H__ -#define __ACTBL32_H__ - - -/* IA32 Root System Description Table */ - -typedef struct -{ - ACPI_TABLE_HEADER header; /* Table header */ - void *table_offset_entry [1]; /* Array of pointers to other */ - /* tables' headers */ -} ROOT_SYSTEM_DESCRIPTION_TABLE; - - -/* IA32 Firmware ACPI Control Structure */ - -typedef struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 firmware_waking_vector; /* ACPI OS waking vector */ - u32 global_lock; /* Global Lock */ - u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u8 resverved3 [40]; /* reserved - must be zero */ - -} FIRMWARE_ACPI_CONTROL_STRUCTURE; - - -/* IA32 Fixed ACPI Description Table */ - -typedef struct -{ - ACPI_TABLE_HEADER header; /* table header */ - ACPI_TBLPTR firmware_ctrl; /* Physical address of FACS */ - ACPI_TBLPTR dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 reserved1; /* reserved */ - u16 sci_int; /* System vector of SCI interrupt */ - ACPI_IO_ADDRESS smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ - u8 reserved2; /* reserved - must be zero */ - ACPI_IO_ADDRESS pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - ACPI_IO_ADDRESS pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - ACPI_IO_ADDRESS pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - ACPI_IO_ADDRESS pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - ACPI_IO_ADDRESS pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - ACPI_IO_ADDRESS pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - ACPI_IO_ADDRESS gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - ACPI_IO_ADDRESS gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 reserved3; /* reserved */ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Size of area read to flush caches */ - u16 flush_stride; /* Stride used in flushing caches */ - u8 duty_offset; /* bit location of duty cycle field in p_cnt reg */ - u8 duty_width; /* bit width of duty cycle field in p_cnt reg */ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u8 reserved4; /* reserved */ - u8 reserved4a; /* reserved */ - u8 reserved4b; /* reserved */ - u32 wb_invd : 1; /* wbinvd instruction works properly */ - u32 wb_invd_flush : 1; /* wbinvd flushes but does not invalidate */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 reserved5 : 23; /* reserved - must be zero */ - -} FIXED_ACPI_DESCRIPTION_TABLE; - - -#endif /* __ACTBL32_H__ */ - - diff -urN linux-2.4.0-test12/drivers/acpi/include/actbl64.h linux-2.4.0-test12-lia/drivers/acpi/include/actbl64.h --- linux-2.4.0-test12/drivers/acpi/include/actbl64.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actbl64.h Wed Dec 31 16:00:00 1969 @@ -1,115 +0,0 @@ -/****************************************************************************** - * - * Name: actbl64.h - ACPI tables specific to IA64 - * $Revision: 12 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __ACTBL64_H__ -#define __ACTBL64_H__ - - -typedef UINT64 IO_ADDRESS; /* Only for clarity in declarations */ - - -/* IA64 Root System Description Table */ - -typedef struct -{ - ACPI_TABLE_HEADER header; /* Table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - void *table_offset_entry [1]; /* Array of pointers to other */ - /* tables' headers */ -} ROOT_SYSTEM_DESCRIPTION_TABLE; - - -/* IA64 Firmware ACPI Control Structure */ - -typedef struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 reserved4; /* must be 0 */ - UINT64 firmware_waking_vector; /* ACPI OS waking vector */ - UINT64 global_lock; /* Global Lock */ - u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u8 resverved3 [28]; /* reserved - must be zero */ - -} FIRMWARE_ACPI_CONTROL_STRUCTURE; - - -/* IA64 Fixed ACPI Description Table */ - -typedef struct -{ - ACPI_TABLE_HEADER header; /* table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - ACPI_TBLPTR firmware_ctrl; /* Physical address of FACS */ - ACPI_TBLPTR dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 address_space; /* Address Space Bitmask */ - u16 sci_int; /* System vector of SCI interrupt */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ - u8 reserved2; /* reserved - must be zero */ - UINT64 smi_cmd; /* Port address of SMI command port */ - UINT64 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ - UINT64 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ - UINT64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - UINT64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - UINT64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - UINT64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - UINT64 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ - UINT64 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 reserved3; /* reserved */ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u8 reserved4; /* reserved */ - u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ - u32 reserved5 : 1; /* reserved - must be zero */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 dock_cap : 1; /* Supports Docking */ - u32 reserved6 : 22; /* reserved - must be zero */ - -} FIXED_ACPI_DESCRIPTION_TABLE; - - -#endif /* __ACTBL64_H__ */ - diff -urN linux-2.4.0-test12/drivers/acpi/include/actbl71.h linux-2.4.0-test12-lia/drivers/acpi/include/actbl71.h --- linux-2.4.0-test12/drivers/acpi/include/actbl71.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actbl71.h Wed Nov 15 16:25:04 2000 @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 + * This file includes tables specific to this + * specification revision. + * $Revision: 7 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ACTBL71_H__ +#define __ACTBL71_H__ + +/* 0.71 FADT Address_space data item bitmasks defines */ +/* If the associated bit is zero then it is in memory space else in io space */ +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 + +/* Only for clarity in declarations */ +typedef UINT64 IO_ADDRESS; + +#pragma pack(1) + +typedef struct /* Root System Descriptor Pointer */ +{ + NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + NATIVE_CHAR oem_id [6]; /* OEM identification */ + u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ + UINT64 rsdt_physical_address; /* 64-bit physical address of RSDT */ +} RSDP_DESCRIPTOR_REV071; + + +/*****************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Root System Description Table */ +/*****************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* Table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + UINT64 table_offset_entry [1]; /* Array of pointers to other */ + /* tables' headers */ +} RSDT_DESCRIPTOR_REV071; + + +/*******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Firmware ACPI Control Structure */ +/*******************************************/ +typedef struct +{ + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 reserved4; /* must be 0 */ + UINT64 firmware_waking_vector; /* ACPI OS waking vector */ + UINT64 global_lock; /* Global Lock */ + u32 S4_bios_f : 1; /* Indicates if S4_bIOS support is present */ + u32 reserved1 : 31; /* must be 0 */ + u8 reserved3 [28]; /* reserved - must be zero */ + +} FACS_DESCRIPTOR_REV071; + + +/******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Fixed ACPI Description Table */ +/******************************************/ +typedef struct +{ + ACPI_TABLE_HEADER header; /* table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + UINT64 firmware_ctrl; /* 64-bit Physical address of FACS */ + UINT64 dsdt; /* 64-bit Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 address_space; /* Address Space Bitmask */ + u16 sci_int; /* System vector of SCI interrupt */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4_bios_req; /* Value to write to SMI CMD to enter S4_bIOS state */ + u8 reserved2; /* reserved - must be zero */ + UINT64 smi_cmd; /* Port address of SMI command port */ + UINT64 pm1a_evt_blk; /* Port address of Power Mgt 1a Acpi_event Reg Blk */ + UINT64 pm1b_evt_blk; /* Port address of Power Mgt 1b Acpi_event Reg Blk */ + UINT64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + UINT64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + UINT64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + UINT64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + UINT64 gpe0blk; /* Port addr of General Purpose Acpi_event 0 Reg Blk */ + UINT64 gpe1_blk; /* Port addr of General Purpose Acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte Length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte Length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 reserved3; /* reserved */ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u8 reserved4; /* reserved */ + u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ + u32 reserved5 : 1; /* reserved - must be zero */ + u32 proc_c1 : 1; /* all processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ + u32 dock_cap : 1; /* Supports Docking */ + u32 reserved6 : 22; /* reserved - must be zero */ + +} FADT_DESCRIPTOR_REV071; + +#pragma pack() + +#endif /* __ACTBL71_H__ */ + diff -urN linux-2.4.0-test12/drivers/acpi/include/actypes.h linux-2.4.0-test12-lia/drivers/acpi/include/actypes.h --- linux-2.4.0-test12/drivers/acpi/include/actypes.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/actypes.h Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 131 $ + * $Revision: 152 $ * *****************************************************************************/ @@ -48,9 +48,6 @@ * UCHAR Character. 1 byte unsigned value. */ -#ifdef __ia64__ -#define _IA64 -#endif #ifdef _IA64 /* @@ -70,6 +67,7 @@ typedef NATIVE_UINT ACPI_TBLPTR; typedef UINT64 ACPI_IO_ADDRESS; +typedef UINT64 ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000008 @@ -85,6 +83,7 @@ typedef unsigned char UCHAR; typedef unsigned int UINT16; typedef long INT32; +typedef int INT16; typedef unsigned long UINT32; typedef UINT16 NATIVE_UINT; @@ -92,10 +91,17 @@ typedef UINT32 ACPI_TBLPTR; typedef UINT32 ACPI_IO_ADDRESS; +typedef UINT32 ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000002 #define _HW_ALIGNMENT_SUPPORT +/* + * (16-bit only) internal integers must be 32-bits, so + * 64-bit integers cannot be supported + */ +#define ACPI_NO_INTEGER64_SUPPORT + #else /* @@ -107,18 +113,21 @@ typedef unsigned short UINT16; typedef int INT32; typedef unsigned int UINT32; +typedef COMPILER_DEPENDENT_UINT64 UINT64; typedef UINT32 NATIVE_UINT; typedef INT32 NATIVE_INT; typedef NATIVE_UINT ACPI_TBLPTR; typedef UINT32 ACPI_IO_ADDRESS; +typedef UINT64 ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000004 #define _HW_ALIGNMENT_SUPPORT - #endif + + /* * Miscellaneous common types */ @@ -132,8 +141,10 @@ * Data type ranges */ -#define ACPI_UCHAR_MAX (UCHAR) 0xFF +#define ACPI_UINT8_MAX (UINT8) 0xFF +#define ACPI_UINT16_MAX (UINT16) 0xFFFF #define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF +#define ACPI_UINT64_MAX (UINT64) 0xFFFFFFFFFFFFFFFF #ifdef DEFINE_ALTERNATE_TYPES @@ -144,6 +155,7 @@ typedef UINT8 u8; typedef UINT16 u16; typedef UINT32 u32; +typedef UINT64 u64; #endif /*! [End] no source code translation !*/ @@ -178,11 +190,46 @@ /* + * Acpi integer width. In ACPI version 1, integers are + * 32 bits. In ACPI version 2, integers are 64 bits. + * Note that this pertains to the ACPI integer type only, not + * other integers used in the implementation of the ACPI CA + * subsystem. + */ +#ifdef ACPI_NO_INTEGER64_SUPPORT + +/* 32-bit Integers */ + +typedef u32 ACPI_INTEGER; +#define ACPI_INTEGER_MAX ACPI_UINT32_MAX; +#define ACPI_INTEGER_BIT_SIZE 32 + +#else + +/* 64-bit Integers */ + +typedef UINT64 ACPI_INTEGER; +#define ACPI_INTEGER_MAX ACPI_UINT64_MAX; +#define ACPI_INTEGER_BIT_SIZE 64 + +#endif + + +/* * Constants with special meanings */ #define ACPI_ROOT_OBJECT (ACPI_HANDLE)(-1) +#define ACPI_FULL_INITIALIZATION 0x00 +#define ACPI_NO_ADDRESS_SPACE_INIT 0x01 +#define ACPI_NO_HARDWARE_INIT 0x02 +#define ACPI_NO_EVENT_INIT 0x04 +#define ACPI_NO_ACPI_ENABLE 0x08 +#define ACPI_NO_DEVICE_INIT 0x10 +#define ACPI_NO_PCI_INIT 0x20 +#define ACPI_NO_OBJECT_INIT 0x40 + /* * Sleep state constants @@ -204,17 +251,14 @@ typedef u32 ACPI_TABLE_TYPE; #define ACPI_TABLE_RSDP (ACPI_TABLE_TYPE) 0 -#define ACPI_TABLE_APIC (ACPI_TABLE_TYPE) 1 -#define ACPI_TABLE_DSDT (ACPI_TABLE_TYPE) 2 -#define ACPI_TABLE_FACP (ACPI_TABLE_TYPE) 3 -#define ACPI_TABLE_FACS (ACPI_TABLE_TYPE) 4 -#define ACPI_TABLE_PSDT (ACPI_TABLE_TYPE) 5 -#define ACPI_TABLE_RSDT (ACPI_TABLE_TYPE) 6 -#define ACPI_TABLE_SSDT (ACPI_TABLE_TYPE) 7 -#define ACPI_TABLE_SBST (ACPI_TABLE_TYPE) 8 -#define ACPI_TABLE_BOOT (ACPI_TABLE_TYPE) 9 -#define ACPI_TABLE_MAX 9 -#define NUM_ACPI_TABLES 10 +#define ACPI_TABLE_DSDT (ACPI_TABLE_TYPE) 1 +#define ACPI_TABLE_FADT (ACPI_TABLE_TYPE) 2 +#define ACPI_TABLE_FACS (ACPI_TABLE_TYPE) 3 +#define ACPI_TABLE_PSDT (ACPI_TABLE_TYPE) 4 +#define ACPI_TABLE_SSDT (ACPI_TABLE_TYPE) 5 +#define ACPI_TABLE_XSDT (ACPI_TABLE_TYPE) 6 +#define ACPI_TABLE_MAX 6 +#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1) /* @@ -266,25 +310,28 @@ #define INTERNAL_TYPE_ALIAS 21 /* 0x15 */ #define INTERNAL_TYPE_NOTIFY 22 /* 0x16 */ #define INTERNAL_TYPE_ADDRESS_HANDLER 23 /* 0x17 */ +#define INTERNAL_TYPE_RESOURCE 24 /* 0x18 */ -#define INTERNAL_TYPE_NODE_MAX 23 + +#define INTERNAL_TYPE_NODE_MAX 24 /* These are pseudo-types because there are never any namespace nodes with these types */ -#define INTERNAL_TYPE_DEF_FIELD_DEFN 24 /* 0x18 Name, Byte_const, multiple Field_element */ -#define INTERNAL_TYPE_BANK_FIELD_DEFN 25 /* 0x19 2 Name,DWord_const,Byte_const,multi Field_element */ -#define INTERNAL_TYPE_INDEX_FIELD_DEFN 26 /* 0x1A 2 Name, Byte_const, multiple Field_element */ -#define INTERNAL_TYPE_IF 27 /* 0x1B Op_code, multiple Code */ -#define INTERNAL_TYPE_ELSE 28 /* 0x1C multiple Code */ -#define INTERNAL_TYPE_WHILE 29 /* 0x1D Op_code, multiple Code */ -#define INTERNAL_TYPE_SCOPE 30 /* 0x1E Name, multiple Node */ -#define INTERNAL_TYPE_DEF_ANY 31 /* 0x1F type is Any, suppress search of enclosing scopes */ -#define INTERNAL_TYPE_METHOD_ARGUMENT 32 /* 0x20 */ -#define INTERNAL_TYPE_METHOD_LOCAL_VAR 33 /* 0x21 */ +#define INTERNAL_TYPE_DEF_FIELD_DEFN 25 /* 0x19 Name, Byte_const, multiple Field_element */ +#define INTERNAL_TYPE_BANK_FIELD_DEFN 26 /* 0x1A 2 Name,DWord_const,Byte_const,multi Field_element */ +#define INTERNAL_TYPE_INDEX_FIELD_DEFN 27 /* 0x1B 2 Name, Byte_const, multiple Field_element */ +#define INTERNAL_TYPE_IF 28 /* 0x1C Op_code, multiple Code */ +#define INTERNAL_TYPE_ELSE 29 /* 0x1D multiple Code */ +#define INTERNAL_TYPE_WHILE 30 /* 0x1E Op_code, multiple Code */ +#define INTERNAL_TYPE_SCOPE 31 /* 0x1F Name, multiple Node */ +#define INTERNAL_TYPE_DEF_ANY 32 /* 0x20 type is Any, suppress search of enclosing scopes */ +#define INTERNAL_TYPE_METHOD_ARGUMENT 33 /* 0x21 */ +#define INTERNAL_TYPE_METHOD_LOCAL_VAR 34 /* 0x22 */ +#define INTERNAL_TYPE_EXTRA 35 /* 0x23 */ -#define INTERNAL_TYPE_MAX 33 +#define INTERNAL_TYPE_MAX 35 -#define INTERNAL_TYPE_INVALID 34 +#define INTERNAL_TYPE_INVALID 36 #define ACPI_TYPE_NOT_FOUND 0xFF /* @@ -339,6 +386,7 @@ */ typedef u32 ACPI_EVENT_STATUS; +#define ACPI_EVENT_FLAG_DISABLED (ACPI_EVENT_STATUS) 0x00 #define ACPI_EVENT_FLAG_ENABLED (ACPI_EVENT_STATUS) 0x01 #define ACPI_EVENT_FLAG_SET (ACPI_EVENT_STATUS) 0x02 @@ -373,7 +421,7 @@ struct { ACPI_OBJECT_TYPE type; - u32 value; /* The actual number */ + ACPI_INTEGER value; /* The actual number */ } number; struct @@ -553,7 +601,7 @@ typedef ACPI_STATUS (*ADDRESS_SPACE_HANDLER) ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -596,11 +644,8 @@ #define ACPI_COMMON_OBJ_INFO \ ACPI_OBJECT_TYPE type; /* ACPI object type */ \ - ACPI_NAME name; /* ACPI object Name */ \ - /* TBD: [Restructure] Do we want or need these next two??*/ \ - ACPI_HANDLE parent; /* Parent object */ \ - ACPI_HANDLE children; /* Linked list of children */ \ - u32 valid /* ????? */ + ACPI_NAME name /* ACPI object Name */ + typedef struct { @@ -612,12 +657,10 @@ { ACPI_COMMON_OBJ_INFO; - /* - * TBD: [Restructure]: a HID or a _UID can return either a number or a string - */ + u32 valid; /* Are the next bits legit? */ NATIVE_CHAR hardware_id [9]; /* _HID value if any */ NATIVE_CHAR unique_id[9]; /* _UID value if any */ - u32 address; /* _ADR value if any */ + ACPI_INTEGER address; /* _ADR value if any */ u32 current_status; /* _STA value */ } ACPI_DEVICE_INFO; @@ -634,7 +677,7 @@ typedef struct { - u8 *mapped_physical_address; + UINT64 mapped_physical_address; u8 *mapped_logical_address; u32 mapped_length; } MEM_HANDLER_CONTEXT; @@ -940,6 +983,8 @@ #define RESOURCE_LENGTH 12 #define RESOURCE_LENGTH_NO_DATA 8 +#define NEXT_RESOURCE(res) (RESOURCE*)((u8*) res + res->length) + /* * END: Definitions for Resource Attributes */ @@ -949,7 +994,7 @@ */ typedef struct { - u32 address; + ACPI_INTEGER address; u32 pin; u32 source_index; NATIVE_CHAR source[1]; diff -urN linux-2.4.0-test12/drivers/acpi/include/amlcode.h linux-2.4.0-test12-lia/drivers/acpi/include/amlcode.h --- linux-2.4.0-test12/drivers/acpi/include/amlcode.h Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/include/amlcode.h Wed Nov 15 16:25:04 2000 @@ -3,7 +3,7 @@ * Name: amlcode.h - Definitions for AML, as included in "definition blocks" * Declarations and definitions contained herein are derived * directly from the ACPI specification. - * $Revision: 39 $ + * $Revision: 40 $ * *****************************************************************************/ @@ -42,9 +42,11 @@ #define AML_WORD_OP (u16) 0x0b #define AML_DWORD_OP (u16) 0x0c #define AML_STRING_OP (u16) 0x0d +#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */ #define AML_SCOPE_OP (u16) 0x10 #define AML_BUFFER_OP (u16) 0x11 #define AML_PACKAGE_OP (u16) 0x12 +#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */ #define AML_METHOD_OP (u16) 0x14 #define AML_DUAL_NAME_PREFIX (u16) 0x2e #define AML_MULTI_NAME_PREFIX_OP (u16) 0x2f @@ -90,6 +92,8 @@ #define AML_FIND_SET_LEFT_BIT_OP (u16) 0x81 #define AML_FIND_SET_RIGHT_BIT_OP (u16) 0x82 #define AML_DEREF_OF_OP (u16) 0x83 +#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */ +#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */ #define AML_NOTIFY_OP (u16) 0x86 #define AML_SIZE_OF_OP (u16) 0x87 #define AML_INDEX_OP (u16) 0x88 @@ -99,12 +103,20 @@ #define AML_BYTE_FIELD_OP (u16) 0x8c #define AML_BIT_FIELD_OP (u16) 0x8d #define AML_TYPE_OP (u16) 0x8e +#define AML_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */ #define AML_LAND_OP (u16) 0x90 #define AML_LOR_OP (u16) 0x91 #define AML_LNOT_OP (u16) 0x92 #define AML_LEQUAL_OP (u16) 0x93 #define AML_LGREATER_OP (u16) 0x94 #define AML_LLESS_OP (u16) 0x95 +#define AML_BUFF_OP (u16) 0x96 /* ACPI 2.0 */ +#define AML_DEC_STR_OP (u16) 0x97 /* ACPI 2.0 */ +#define AML_HEX_STR_OP (u16) 0x98 /* ACPI 2.0 */ +#define AML_INT_OP (u16) 0x99 /* ACPI 2.0 */ +#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */ +#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */ +#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */ #define AML_IF_OP (u16) 0xa0 #define AML_ELSE_OP (u16) 0xa1 #define AML_WHILE_OP (u16) 0xa2 @@ -125,6 +137,7 @@ #define AML_SHIFT_LEFT_BIT_OP (u16) 0x5b11 #define AML_COND_REF_OF_OP (u16) 0x5b12 #define AML_CREATE_FIELD_OP (u16) 0x5b13 +#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */ #define AML_LOAD_OP (u16) 0x5b20 #define AML_STALL_OP (u16) 0x5b21 #define AML_SLEEP_OP (u16) 0x5b22 @@ -147,6 +160,7 @@ #define AML_THERMAL_ZONE_OP (u16) 0x5b85 #define AML_INDEX_FIELD_OP (u16) 0x5b86 #define AML_BANK_FIELD_OP (u16) 0x5b87 +#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */ /* Bogus opcodes (they are actually two separate opcodes) */ @@ -276,6 +290,21 @@ #define OPTYPE_RETURN 21 #define OPTYPE_BOGUS 22 + + +/* Predefined Operation Region Space_iDs */ + +typedef enum +{ + REGION_MEMORY = 0, + REGION_IO, + REGION_PCI_CONFIG, + REGION_EC, + REGION_SMBUS, + REGION_CMOS, + REGION_PCI_BAR + +} AML_REGION_TYPES; /* Comparison operation codes for Match_op operator */ diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/Makefile linux-2.4.0-test12-lia/drivers/acpi/interpreter/Makefile --- linux-2.4.0-test12/drivers/acpi/interpreter/Makefile Fri Sep 15 18:21:44 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amconfig.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amconfig.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amconfig.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amconfig.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 23 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -51,7 +51,7 @@ * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_exec_load_table ( ACPI_OPERAND_OBJECT *rgn_desc, ACPI_HANDLE *ddb_handle) @@ -139,12 +139,17 @@ /* Add the table to the namespace */ - status = acpi_load_namespace (); - if (ACPI_FAILURE (status)) { + /* TBD: [Restructure] - change to whatever new interface is appropriate */ +/* + Status = Acpi_load_namespace (); + if (ACPI_FAILURE (Status)) { +*/ /* TBD: [Errors] Unload the table on failure ? */ - - goto cleanup; +/* + goto Cleanup; } +*/ + /* TBD: [Investigate] we need a pointer to the table desc */ @@ -179,7 +184,7 @@ * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_exec_unload_table ( ACPI_HANDLE ddb_handle) { @@ -219,7 +224,7 @@ /* Delete the table itself */ - acpi_tb_delete_single_table (table_info->installed_desc); + acpi_tb_uninstall_table (table_info->installed_desc); /* Delete the table descriptor (Ddb_handle) */ diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amcreate.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amcreate.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amcreate.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amcreate.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amcreate - Named object creation - * $Revision: 44 $ + * $Revision: 50 $ * *****************************************************************************/ @@ -66,198 +66,55 @@ * ******************************************************************************/ + ACPI_STATUS acpi_aml_exec_create_field ( - u16 opcode, + u8 *aml_ptr, + u32 aml_length, + ACPI_NAMESPACE_NODE *node, ACPI_WALK_STATE *walk_state) { - ACPI_OPERAND_OBJECT *res_desc = NULL; - ACPI_OPERAND_OBJECT *cnt_desc = NULL; - ACPI_OPERAND_OBJECT *off_desc = NULL; - ACPI_OPERAND_OBJECT *src_desc = NULL; - ACPI_OPERAND_OBJECT *field_desc; - ACPI_OPERAND_OBJECT *obj_desc; - OBJECT_TYPE_INTERNAL res_type; ACPI_STATUS status; - u32 num_operands = 3; - u32 offset; - u32 bit_offset; - u16 bit_count; - u8 type_found; - - - /* Resolve the operands */ - - status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state); - - /* Get the operands */ - - status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state); - if (AML_CREATE_FIELD_OP == opcode) { - num_operands = 4; - status |= acpi_ds_obj_stack_pop_object (&cnt_desc, walk_state); - } + ACPI_OPERAND_OBJECT *obj_desc; + ACPI_OPERAND_OBJECT *tmp_desc; - status |= acpi_ds_obj_stack_pop_object (&off_desc, walk_state); - status |= acpi_ds_obj_stack_pop_object (&src_desc, walk_state); - if (ACPI_FAILURE (status)) { - /* Invalid parameters on object stack */ + /* Create the region descriptor */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_FIELD_UNIT); + if (!obj_desc) { + status = AE_NO_MEMORY; goto cleanup; } + /* Construct the field object */ - offset = off_desc->number.value; - - - /* - * If Res_desc is a Name, it will be a direct name pointer after - * Acpi_aml_resolve_operands() - */ - - if (!VALID_DESCRIPTOR_TYPE (res_desc, ACPI_DESC_TYPE_NAMED)) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - + obj_desc->field_unit.access = (u8) ACCESS_ANY_ACC; + obj_desc->field_unit.lock_rule = (u8) GLOCK_NEVER_LOCK; + obj_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE; /* - * Setup the Bit offsets and counts, according to the opcode + * Allocate a method object for this field unit */ - switch (opcode) - { - - /* Def_create_bit_field */ - - case AML_BIT_FIELD_OP: - - /* Offset is in bits, Field is a bit */ - - bit_offset = offset; - bit_count = 1; - break; - - - /* Def_create_byte_field */ - - case AML_BYTE_FIELD_OP: - - /* Offset is in bytes, field is a byte */ - - bit_offset = 8 * offset; - bit_count = 8; - break; - - - /* Def_create_word_field */ - - case AML_WORD_FIELD_OP: - - /* Offset is in bytes, field is a word */ - - bit_offset = 8 * offset; - bit_count = 16; - break; - - - /* Def_create_dWord_field */ - - case AML_DWORD_FIELD_OP: - - /* Offset is in bytes, field is a dword */ - - bit_offset = 8 * offset; - bit_count = 32; - break; - - - /* Def_create_field */ - - case AML_CREATE_FIELD_OP: - - /* Offset is in bits, count is in bits */ - - bit_offset = offset; - bit_count = (u16) cnt_desc->number.value; - break; - - - default: - - status = AE_AML_BAD_OPCODE; + obj_desc->field_unit.extra = acpi_cm_create_internal_object ( + INTERNAL_TYPE_EXTRA); + if (!obj_desc->field_unit.extra) { + status = AE_NO_MEMORY; goto cleanup; } - /* - * Setup field according to the object type + * Remember location in AML stream of the field unit + * opcode and operands -- since the buffer and index + * operands must be evaluated. */ - switch (src_desc->common.type) - { - - /* Source_buff := Term_arg=>Buffer */ - - case ACPI_TYPE_BUFFER: - - if (bit_offset + (u32) bit_count > - (8 * (u32) src_desc->buffer.length)) - { - status = AE_AML_BUFFER_LIMIT; - goto cleanup; - } - - - /* Allocate an object for the field */ - - field_desc = acpi_cm_create_internal_object (ACPI_TYPE_FIELD_UNIT); - if (!field_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - /* Construct the field object */ - - field_desc->field_unit.access = (u8) ACCESS_ANY_ACC; - field_desc->field_unit.lock_rule = (u8) GLOCK_NEVER_LOCK; - field_desc->field_unit.update_rule = (u8) UPDATE_PRESERVE; - field_desc->field_unit.length = bit_count; - field_desc->field_unit.bit_offset = (u8) (bit_offset % 8); - field_desc->field_unit.offset = DIV_8 (bit_offset); - field_desc->field_unit.container = src_desc; - field_desc->field_unit.sequence = src_desc->buffer.sequence; - - /* An additional reference for Src_desc */ - - acpi_cm_add_reference (src_desc); - - break; - - - /* Improper object type */ - - default: - - type_found = src_desc->common.type; - - if ((type_found > (u8) INTERNAL_TYPE_REFERENCE) || - !acpi_cm_valid_object_type (type_found)) - - - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } + obj_desc->field_unit.extra->extra.pcode = aml_ptr; + obj_desc->field_unit.extra->extra.pcode_length = aml_length; + obj_desc->field_unit.node = node; - if (AML_CREATE_FIELD_OP == opcode) { - /* Delete object descriptor unique to Create_field */ - - acpi_cm_remove_reference (cnt_desc); - cnt_desc = NULL; - } - /* * This operation is supposed to cause the destination Name to refer * to the defined Field_unit -- it must not store the constructed @@ -268,11 +125,9 @@ * reference before calling Acpi_aml_exec_store(). */ - res_type = acpi_ns_get_type (res_desc); - /* Type of Name's existing value */ - switch (res_type) + switch (acpi_ns_get_type (node)) { case ACPI_TYPE_FIELD_UNIT: @@ -282,21 +137,21 @@ case INTERNAL_TYPE_DEF_FIELD: case INTERNAL_TYPE_INDEX_FIELD: - obj_desc = acpi_ns_get_attached_object (res_desc); - if (obj_desc) { + tmp_desc = acpi_ns_get_attached_object (node); + if (tmp_desc) { /* * There is an existing object here; delete it and zero out the * object field within the Node */ - acpi_cm_remove_reference (obj_desc); - acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) res_desc, NULL, + acpi_cm_remove_reference (tmp_desc); + acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) node, NULL, ACPI_TYPE_ANY); } /* Set the type to ANY (or the store below will fail) */ - ((ACPI_NAMESPACE_NODE *) res_desc)->type = ACPI_TYPE_ANY; + ((ACPI_NAMESPACE_NODE *) node)->type = ACPI_TYPE_ANY; break; @@ -309,32 +164,29 @@ /* Store constructed field descriptor in result location */ - status = acpi_aml_exec_store (field_desc, res_desc, walk_state); + status = acpi_aml_exec_store (obj_desc, (ACPI_OPERAND_OBJECT *) node, walk_state); /* * If the field descriptor was not physically stored (or if a failure * above), we must delete it */ - if (field_desc->common.reference_count <= 1) { - acpi_cm_remove_reference (field_desc); + if (obj_desc->common.reference_count <= 1) { + acpi_cm_remove_reference (obj_desc); } -cleanup: + return (AE_OK); - /* Always delete the operands */ - acpi_cm_remove_reference (off_desc); - acpi_cm_remove_reference (src_desc); +cleanup: - if (AML_CREATE_FIELD_OP == opcode) { - acpi_cm_remove_reference (cnt_desc); - } + /* Delete region object and method subobject */ - /* On failure, delete the result descriptor */ + if (obj_desc) { + /* Remove deletes both objects! */ - if (ACPI_FAILURE (status)) { - acpi_cm_remove_reference (res_desc); /* Result descriptor */ + acpi_cm_remove_reference (obj_desc); + obj_desc = NULL; } return (status); @@ -547,7 +399,7 @@ ACPI_WALK_STATE *walk_state) { ACPI_STATUS status; - ACPI_OPERAND_OBJECT *obj_desc_region; + ACPI_OPERAND_OBJECT *obj_desc; ACPI_NAMESPACE_NODE *node; @@ -560,8 +412,7 @@ * Should this return an error, or should we just keep * going? How do we handle the OEM region handlers? */ - - REPORT_WARNING ("Unable to decode the Region_space"); + REPORT_WARNING (("Invalid Address_space type %X\n", region_space)); } @@ -571,8 +422,8 @@ /* Create the region descriptor */ - obj_desc_region = acpi_cm_create_internal_object (ACPI_TYPE_REGION); - if (!obj_desc_region) { + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_REGION); + if (!obj_desc) { status = AE_NO_MEMORY; goto cleanup; } @@ -580,32 +431,34 @@ /* * Allocate a method object for this region. */ - obj_desc_region->region.method = acpi_cm_create_internal_object ( - ACPI_TYPE_METHOD); - if (!obj_desc_region->region.method) { + + obj_desc->region.extra = acpi_cm_create_internal_object ( + INTERNAL_TYPE_EXTRA); + if (!obj_desc->region.extra) { status = AE_NO_MEMORY; goto cleanup; } - /* Init the region from the operands */ - - obj_desc_region->region.space_id = (u8) region_space; - obj_desc_region->region.address = 0; - obj_desc_region->region.length = 0; - /* * Remember location in AML stream of address & length * operands since they need to be evaluated at run time. */ - obj_desc_region->region.method->method.pcode = aml_ptr; - obj_desc_region->region.method->method.pcode_length = aml_length; + + obj_desc->region.extra->extra.pcode = aml_ptr; + obj_desc->region.extra->extra.pcode_length = aml_length; + + /* Init the region from the operands */ + + obj_desc->region.space_id = (u8) region_space; + obj_desc->region.address = 0; + obj_desc->region.length = 0; /* Install the new region object in the parent Node */ - obj_desc_region->region.node = node; + obj_desc->region.node = node; - status = acpi_ns_attach_object (node, obj_desc_region, + status = acpi_ns_attach_object (node, obj_desc, (u8) ACPI_TYPE_REGION); if (ACPI_FAILURE (status)) { @@ -617,7 +470,7 @@ * Namespace is NOT locked at this point. */ - status = acpi_ev_initialize_region (obj_desc_region, FALSE); + status = acpi_ev_initialize_region (obj_desc, FALSE); if (ACPI_FAILURE (status)) { /* @@ -635,11 +488,11 @@ if (ACPI_FAILURE (status)) { /* Delete region object and method subobject */ - if (obj_desc_region) { + if (obj_desc) { /* Remove deletes both objects! */ - acpi_cm_remove_reference (obj_desc_region); - obj_desc_region = NULL; + acpi_cm_remove_reference (obj_desc); + obj_desc = NULL; } } diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amdump.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amdump.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amdump.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amdump.c Wed Dec 31 16:00:00 1969 @@ -1,41 +0,0 @@ -/****************************************************************************** - * - * Module Name: amdump - Interpreter debug output routines - * $Revision: 90 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acinterp.h" -#include "amlcode.h" -#include "acnamesp.h" -#include "actables.h" - -#define _COMPONENT INTERPRETER - MODULE_NAME ("amdump") - - -/* - * The following routines are used for debug output only - */ - - diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amdyadic.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amdyadic.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amdyadic.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amdyadic.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators - * $Revision: 63 $ + * $Revision: 67 $ * *****************************************************************************/ @@ -106,7 +106,7 @@ /* Dispatch the notify to the appropriate handler */ - acpi_ev_notify_dispatch (node, val_desc->number.value); + acpi_ev_notify_dispatch (node, (u32) val_desc->number.value); break; default: @@ -117,7 +117,8 @@ default: - REPORT_ERROR ("Acpi_aml_exec_dyadic1: Unknown dyadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic1: Unknown dyadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; } @@ -162,7 +163,6 @@ ACPI_OPERAND_OBJECT *ret_desc = NULL; ACPI_OPERAND_OBJECT *ret_desc2 = NULL; ACPI_STATUS status = AE_OK; - u32 remainder; u32 num_operands = 3; NATIVE_CHAR *new_buf; @@ -276,8 +276,9 @@ case AML_DIVIDE_OP: - if ((u32) 0 == obj_desc2->number.value) { - REPORT_ERROR ("Aml_exec_dyadic2_r/Divide_op: Divide by zero"); + if (!obj_desc2->number.value) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Divide_op: Divide by zero\n")); status = AE_AML_DIVIDE_BY_ZERO; goto cleanup; @@ -289,14 +290,15 @@ goto cleanup; } - remainder = obj_desc->number.value % - obj_desc2->number.value; - ret_desc->number.value = remainder; + /* Remainder (modulo) */ + + ret_desc->number.value = ACPI_MODULO (obj_desc->number.value, + obj_desc2->number.value); /* Result (what we used to call the quotient) */ - ret_desc2->number.value = obj_desc->number.value / - obj_desc2->number.value; + ret_desc2->number.value = ACPI_DIVIDE (obj_desc->number.value, + obj_desc2->number.value); break; @@ -360,7 +362,7 @@ obj_desc2->string.length + 1); if (!new_buf) { REPORT_ERROR - ("Aml_exec_dyadic2_r/Concat_op: String allocation failure"); + (("Aml_exec_dyadic2_r/Concat_op: String allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; } @@ -389,7 +391,7 @@ obj_desc2->buffer.length); if (!new_buf) { REPORT_ERROR - ("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure"); + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); status = AE_NO_MEMORY; goto cleanup; } @@ -412,7 +414,7 @@ default: - REPORT_ERROR ("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode %X\n", opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -548,7 +550,7 @@ default: - REPORT_ERROR ("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode %X\n", opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -560,7 +562,7 @@ */ if (status == AE_TIME) { - ret_desc->number.value = (u32)(-1); /* TRUE, op timed out */ + ret_desc->number.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */ status = AE_OK; } @@ -695,7 +697,7 @@ default: - REPORT_ERROR ("Acpi_aml_exec_dyadic2: Unknown dyadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_dyadic2: Unknown dyadic opcode %X\n", opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; break; @@ -705,7 +707,7 @@ /* Set return value to logical TRUE (all ones) or FALSE (zero) */ if (lboolean) { - ret_desc->number.value = 0xffffffff; + ret_desc->number.value = ACPI_INTEGER_MAX; } else { ret_desc->number.value = 0; diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amfield.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amfield.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amfield.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amfield.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amfield - ACPI AML (p-code) execution - field manipulation - * $Revision: 70 $ + * $Revision: 73 $ * *****************************************************************************/ @@ -105,7 +105,7 @@ /* - * If the address and length have not been previously evaluated, + * If the Region Address and Length have not been previously evaluated, * evaluate them and save the results. */ if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) { @@ -116,6 +116,16 @@ } } + + if ((obj_desc->common.type == ACPI_TYPE_FIELD_UNIT) && + (!(obj_desc->common.flags & AOPOBJ_DATA_VALID))) + { + /* + * Field Buffer and Index have not been previously evaluated, + */ + return (AE_AML_INTERNAL); + } + if (rgn_desc->region.length < (obj_desc->field.offset & ~((u32) field_byte_width - 1)) + field_byte_width) @@ -213,7 +223,16 @@ actual_byte_length = buffer_length; if (buffer_length > byte_field_length) { actual_byte_length = byte_field_length; + } + + /* TBD: should these round down to a power of 2? */ + + if (DIV_8(bit_granularity) > byte_field_length) { + bit_granularity = MUL_8(byte_field_length); + } + if (byte_granularity > byte_field_length) { + byte_granularity = byte_field_length; } diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amfldio.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amfldio.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amfldio.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amfldio.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amfldio - Aml Field I/O - * $Revision: 26 $ + * $Revision: 30 $ * *****************************************************************************/ @@ -59,7 +59,7 @@ { ACPI_STATUS status; ACPI_OPERAND_OBJECT *rgn_desc = NULL; - u32 address; + ACPI_PHYSICAL_ADDRESS address; u32 local_value = 0; u32 field_byte_width; @@ -318,7 +318,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_write_field_data ( ACPI_OPERAND_OBJECT *obj_desc, u32 field_byte_offset, @@ -327,7 +327,7 @@ { ACPI_STATUS status = AE_OK; ACPI_OPERAND_OBJECT *rgn_desc = NULL; - u32 address; + ACPI_PHYSICAL_ADDRESS address; u32 field_byte_width; @@ -379,7 +379,7 @@ * ****************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_write_field_data_with_update_rule ( ACPI_OPERAND_OBJECT *obj_desc, u32 mask, diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/ammisc.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/ammisc.c --- linux-2.4.0-test12/drivers/acpi/interpreter/ammisc.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/ammisc.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: ammisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 67 $ + * $Revision: 70 $ * *****************************************************************************/ @@ -100,6 +100,7 @@ /* If we get back from the OS call, we might as well keep going. */ + REPORT_WARNING (("An AML \"fatal\" Opcode (Fatal_op) was executed\n")); return (AE_OK); } @@ -223,7 +224,7 @@ ret_desc->reference.op_code = AML_INDEX_OP; ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD; ret_desc->reference.object = obj_desc; - ret_desc->reference.offset = idx_desc->number.value; + ret_desc->reference.offset = (u32) idx_desc->number.value; status = acpi_aml_exec_store (ret_desc, res_desc, walk_state); } @@ -320,7 +321,7 @@ goto cleanup; } - index = start_desc->number.value; + index = (u32) start_desc->number.value; if (index >= (u32) pkg_desc->package.count) { status = AE_AML_PACKAGE_LIMIT; goto cleanup; diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/ammonad.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/ammonad.c --- linux-2.4.0-test12/drivers/acpi/interpreter/ammonad.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/ammonad.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: ammonad - ACPI AML (p-code) execution for monadic operators - * $Revision: 79 $ + * $Revision: 83 $ * *****************************************************************************/ @@ -51,7 +51,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_get_object_reference ( ACPI_OPERAND_OBJECT *obj_desc, ACPI_OPERAND_OBJECT **ret_desc, @@ -180,7 +180,7 @@ case AML_SLEEP_OP: - acpi_aml_system_do_suspend (obj_desc->number.value); + acpi_aml_system_do_suspend ((u32) obj_desc->number.value); break; @@ -188,7 +188,7 @@ case AML_STALL_OP: - acpi_aml_system_do_stall (obj_desc->number.value); + acpi_aml_system_do_stall ((u32) obj_desc->number.value); break; @@ -196,7 +196,8 @@ default: - REPORT_ERROR ("Acpi_aml_exec_monadic1: Unknown monadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_monadic1: Unknown monadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; break; @@ -294,11 +295,10 @@ ret_desc->number.value = obj_desc->number.value; /* - * Acpi x1.94 spec, Chapter 16 describes Integer as a 32-bit - * little endian unsigned value, so this boundry condition - * is valid. + * Acpi specification describes Integer type as a little + * endian unsigned value, so this boundry condition is valid. */ - for (res_val = 0; ret_desc->number.value && res_val < 32; ++res_val) { + for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { ret_desc->number.value >>= 1; } @@ -313,16 +313,16 @@ ret_desc->number.value = obj_desc->number.value; /* - * Acpi x1.94 spec, Chapter 16 describes Integer as a 32-bit - * little endian unsigned value, so this boundry condition - * is valid. + * Acpi specification describes Integer type as a little + * endian unsigned value, so this boundry condition is valid. */ - for (res_val = 0; ret_desc->number.value && res_val < 32; ++res_val) { + for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { ret_desc->number.value <<= 1; } - /* Since returns must be 1-based, subtract from 33 */ - ret_desc->number.value = res_val == 0 ? 0 : 33 - res_val; + /* Since returns must be 1-based, subtract from 33 (65) */ + + ret_desc->number.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val; break; @@ -330,6 +330,8 @@ case AML_FROM_BCD_OP: + /* TBD: for ACPI 2.0, expand to 64 bits */ + d0 = (u32) (obj_desc->number.value & 15); d1 = (u32) (obj_desc->number.value >> 4 & 15); d2 = (u32) (obj_desc->number.value >> 8 & 15); @@ -348,6 +350,7 @@ case AML_TO_BCD_OP: + /* TBD: for ACPI 2.0, expand to 64 bits */ if (obj_desc->number.value > 9999) { status = AE_AML_NUMERIC_OVERFLOW; @@ -355,10 +358,10 @@ } ret_desc->number.value - = obj_desc->number.value % 10 - + (obj_desc->number.value / 10 % 10 << 4) - + (obj_desc->number.value / 100 % 10 << 8) - + (obj_desc->number.value / 1000 % 10 << 12); + = ACPI_MODULO (obj_desc->number.value, 10) + + (ACPI_MODULO (ACPI_DIVIDE (obj_desc->number.value, 10), 10) << 4) + + (ACPI_MODULO (ACPI_DIVIDE (obj_desc->number.value, 100), 10) << 8) + + (ACPI_MODULO (ACPI_DIVIDE (obj_desc->number.value, 1000), 10) << 12); break; @@ -401,7 +404,7 @@ /* The object exists in the namespace, return TRUE */ - ret_desc->number.value = (u32) -1; + ret_desc->number.value = ACPI_INTEGER_MAX goto cleanup; break; @@ -466,7 +469,8 @@ default: - REPORT_ERROR ("Acpi_aml_exec_monadic2_r: Unknown monadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_monadic2_r: Unknown monadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -523,7 +527,7 @@ ACPI_STATUS resolve_status; ACPI_STATUS status; u32 type; - u32 value; + ACPI_INTEGER value; /* Attempt to resolve the operands */ @@ -693,7 +697,8 @@ default: - REPORT_ERROR ("Acpi_aml_exec_monadic2/Type_op:internal error: Unknown Reference subtype"); + REPORT_ERROR (("Acpi_aml_exec_monadic2/Type_op: Internal error - Unknown Reference subtype %X\n", + obj_desc->reference.op_code)); status = AE_AML_INTERNAL; goto cleanup; } @@ -946,7 +951,8 @@ default: - REPORT_ERROR ("Acpi_aml_exec_monadic2: Internal error, unknown monadic opcode"); + REPORT_ERROR (("Acpi_aml_exec_monadic2: Unknown monadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amnames.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amnames.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amnames.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amnames.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amnames - interpreter/scanner name load/execute - * $Revision: 70 $ + * $Revision: 71 $ * *****************************************************************************/ @@ -90,7 +90,7 @@ name_string = acpi_cm_allocate (size_needed); if (!name_string) { - REPORT_ERROR ("Aml_allocate_name_string: name allocation failure"); + REPORT_ERROR (("Aml_allocate_name_string: name allocation failure\n")); return (NULL); } @@ -380,8 +380,8 @@ if (AE_CTRL_PENDING == status && has_prefix) { /* Ran out of segments after processing a prefix */ - REPORT_ERROR ("Ran out of segments after processing a prefix"); - + REPORT_ERROR ( + ("Aml_do_name: Malformed Name at %p\n", name_string)); status = AE_AML_BAD_NAME; } diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amprep.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amprep.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amprep.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amprep.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 67 $ + * $Revision: 68 $ * *****************************************************************************/ @@ -48,7 +48,7 @@ * ******************************************************************************/ -u32 +static u32 acpi_aml_decode_field_access_type ( u32 access) { @@ -97,7 +97,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_aml_prep_common_field_object ( ACPI_OPERAND_OBJECT *obj_desc, u8 field_flags, diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amregion.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amregion.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amregion.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amregion.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amregion - ACPI default Op_region (address space) handlers - * $Revision: 35 $ + * $Revision: 40 $ * *****************************************************************************/ @@ -58,7 +58,7 @@ ACPI_STATUS acpi_aml_system_memory_space_handler ( u32 function, - u32 address, /* TBD: [Future] Should this be A POINTER for 64-bit support? */ + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -98,8 +98,8 @@ * 2) Address beyond the current mapping? */ - if (((u8 *) address < mem_info->mapped_physical_address) || - (((u8 *) address + length) > + if ((address < mem_info->mapped_physical_address) || + ((address + length) > (mem_info->mapped_physical_address + mem_info->mapped_length))) { /* @@ -118,13 +118,15 @@ /* Create a new mapping starting at the address given */ - status = acpi_os_map_memory ((void *) address, SYSMEM_REGION_WINDOW_SIZE, + status = acpi_os_map_memory (address, SYSMEM_REGION_WINDOW_SIZE, (void **) &mem_info->mapped_logical_address); if (ACPI_FAILURE (status)) { return (status); } - mem_info->mapped_physical_address = (u8 *) address; + /* TBD: should these pointers go to 64-bit in all cases ? */ + + mem_info->mapped_physical_address = address; mem_info->mapped_length = SYSMEM_REGION_WINDOW_SIZE; } @@ -134,8 +136,10 @@ * access */ + /* TBD: should these pointers go to 64-bit in all cases ? */ + logical_addr_ptr = mem_info->mapped_logical_address + - ((u8 *) address - mem_info->mapped_physical_address); + (address - mem_info->mapped_physical_address); /* Perform the memory read or write */ @@ -212,7 +216,7 @@ ACPI_STATUS acpi_aml_system_io_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, @@ -304,7 +308,7 @@ ACPI_STATUS acpi_aml_pci_config_space_handler ( u32 function, - u32 address, + ACPI_PHYSICAL_ADDRESS address, u32 bit_width, u32 *value, void *handler_context, diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amresnte.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amresnte.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amresnte.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amresnte.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amresnte - AML Interpreter object resolution - * $Revision: 21 $ + * $Revision: 24 $ * *****************************************************************************/ @@ -65,7 +65,9 @@ ACPI_STATUS acpi_aml_resolve_node_to_value ( - ACPI_NAMESPACE_NODE **stack_ptr) + ACPI_NAMESPACE_NODE **stack_ptr, + ACPI_WALK_STATE *walk_state) + { ACPI_STATUS status = AE_OK; ACPI_OPERAND_OBJECT *val_desc = NULL; @@ -76,7 +78,7 @@ u8 locked; u8 attached_aml_pointer = FALSE; u8 aml_opcode = 0; - u32 temp_val; + ACPI_INTEGER temp_val; OBJECT_TYPE_INTERNAL object_type; @@ -174,7 +176,6 @@ obj_desc = val_desc; acpi_cm_add_reference (obj_desc); - break; @@ -211,90 +212,18 @@ case ACPI_TYPE_NUMBER: /* - * An ACPI_TYPE_NUMBER can be either an object or an AML pointer + * The Node has an attached internal object, make sure that it's a + * number */ - if (attached_aml_pointer) { - /* - * The attachment points into the AML stream, get the number from - * there. The actual number is based upon the AML opcode - * - * Note: Word_op and DWord_op will not work properly if the - * processor's endianness does not match the AML's. - */ - - switch (aml_opcode) - { - - case AML_ZERO_OP: - - temp_val = 0; - break; - - - case AML_ONE_OP: - - temp_val = 1; - break; - - - case AML_ONES_OP: - - temp_val = 0xFFFFFFFF; - break; - - - case AML_BYTE_OP: - - temp_val = (u32) ((u8 *) val_desc)[1]; - break; - - - case AML_WORD_OP: - - MOVE_UNALIGNED16_TO_32 (&temp_val, &((u8 *) val_desc)[1]); - break; - - - case AML_DWORD_OP: - - MOVE_UNALIGNED32_TO_32 (&temp_val, &((u8 *) val_desc)[1]); - break; - - - default: - - return (AE_AML_BAD_OPCODE); - - } /* switch */ - - - /* Create and initialize a new object */ - - obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); - if (!obj_desc) { - return (AE_NO_MEMORY); - } - - obj_desc->number.value = temp_val; + if (ACPI_TYPE_NUMBER != val_desc->common.type) { + return (AE_AML_OPERAND_TYPE); } - else { - /* - * The Node has an attached internal object, make sure that it's a - * number - */ - - if (ACPI_TYPE_NUMBER != val_desc->common.type) { - return (AE_AML_OPERAND_TYPE); - } - - /* Return an additional reference to the object */ - - obj_desc = val_desc; - acpi_cm_add_reference (obj_desc); - } + /* Return an additional reference to the object */ + obj_desc = val_desc; + acpi_cm_add_reference (obj_desc); break; @@ -331,7 +260,7 @@ * Fill in the object specific details */ if (ACPI_TYPE_BUFFER == object_type) { - obj_desc->buffer.pointer = acpi_cm_callocate(val_desc->field.length); + obj_desc->buffer.pointer = acpi_cm_callocate (val_desc->field.length); if (!obj_desc->buffer.pointer) { acpi_cm_remove_reference(obj_desc); return (AE_NO_MEMORY); @@ -339,18 +268,15 @@ obj_desc->buffer.length = val_desc->field.length; - status = acpi_aml_access_named_field (ACPI_READ, - (ACPI_HANDLE) node, - obj_desc->buffer.pointer, - obj_desc->buffer.length); + status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node, + obj_desc->buffer.pointer, obj_desc->buffer.length); if (ACPI_FAILURE (status)) { return (status); } } else { - status = acpi_aml_access_named_field (ACPI_READ, - (ACPI_HANDLE) node, + status = acpi_aml_access_named_field (ACPI_READ, (ACPI_HANDLE) node, &temp_val, sizeof (temp_val)); if (ACPI_FAILURE (status)) { @@ -384,8 +310,7 @@ /* perform the update */ status = acpi_aml_access_named_field (ACPI_WRITE, - val_desc->bank_field.bank_select, - &val_desc->bank_field.value, + val_desc->bank_field.bank_select, &val_desc->bank_field.value, sizeof (val_desc->bank_field.value)); acpi_aml_release_global_lock (locked); @@ -404,6 +329,8 @@ return (status); } + /* Create an object for the result */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); if (!obj_desc) { return (AE_NO_MEMORY); @@ -431,10 +358,10 @@ locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule); /* Perform the update */ + status = acpi_aml_access_named_field (ACPI_WRITE, - val_desc->index_field.index, - &val_desc->index_field.value, - sizeof (val_desc->index_field.value)); + val_desc->index_field.index, &val_desc->index_field.value, + sizeof (val_desc->index_field.value)); acpi_aml_release_global_lock (locked); @@ -444,13 +371,14 @@ /* Read Data value */ - status = acpi_aml_access_named_field (ACPI_READ, - val_desc->index_field.data, - &temp_val, sizeof (temp_val)); + status = acpi_aml_access_named_field (ACPI_READ, val_desc->index_field.data, + &temp_val, sizeof (temp_val)); if (ACPI_FAILURE (status)) { return (status); } + /* Create an object for the result */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); if (!obj_desc) { return (AE_NO_MEMORY); @@ -471,6 +399,8 @@ break; } + /* Create object for result */ + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_ANY); if (!obj_desc) { return (AE_NO_MEMORY); @@ -504,11 +434,61 @@ acpi_cm_add_reference (obj_desc); break; + /* TYPE_Any is untyped, and thus there is no object associated with it */ case ACPI_TYPE_ANY: return (AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ + break; + + + /* + * The only named references allowed are named constants + * + * e.g. Name (\OSFL, Ones) + */ + case INTERNAL_TYPE_REFERENCE: + + switch (val_desc->reference.op_code) + { + + case AML_ZERO_OP: + + temp_val = 0; + break; + + + case AML_ONE_OP: + + temp_val = 1; + break; + + + case AML_ONES_OP: + + temp_val = ACPI_INTEGER_MAX; + break; + + + default: + + return (AE_AML_BAD_OPCODE); + } + + /* Create object for result */ + + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + if (!obj_desc) { + return (AE_NO_MEMORY); + } + + obj_desc->number.value = temp_val; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (obj_desc, walk_state); + break; /* Default case is for unknown types */ diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amresolv.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amresolv.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amresolv.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amresolv.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amresolv - AML Interpreter object resolution - * $Revision: 74 $ + * $Revision: 77 $ * *****************************************************************************/ @@ -69,7 +69,14 @@ status = AE_AML_NO_OPERAND; } - else if (!field_desc->field_unit.container) { + if (!(field_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_field_unit_arguments (field_desc); + if (ACPI_FAILURE (status)) { + return (status); + } + } + + if (!field_desc->field_unit.container) { status = AE_AML_INTERNAL; } @@ -77,12 +84,6 @@ status = AE_AML_OPERAND_TYPE; } - else if (field_desc->field_unit.sequence - != field_desc->field_unit.container->buffer.sequence) - { - status = AE_AML_INTERNAL; - } - else if (!result_desc) { status = AE_AML_INTERNAL; } @@ -114,7 +115,7 @@ mask = ((u32) 1 << field_desc->field_unit.length) - (u32) 1; } else { - mask = 0xFFFFFFFF; + mask = ACPI_UINT32_MAX; } result_desc->number.type = (u8) ACPI_TYPE_NUMBER; @@ -186,7 +187,7 @@ */ if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) { - status = acpi_aml_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr); + status = acpi_aml_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr, walk_state); } @@ -340,7 +341,11 @@ case AML_ONES_OP: stack_desc->common.type = (u8) ACPI_TYPE_NUMBER; - stack_desc->number.value = 0xFFFFFFFF; + stack_desc->number.value = ACPI_INTEGER_MAX; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (stack_desc, walk_state); break; diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amstoren.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amstoren.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amstoren.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amstoren.c Wed Nov 15 16:25:04 2000 @@ -3,7 +3,7 @@ * * Module Name: amstoren - AML Interpreter object store support, * Store to Node (namespace object) - * $Revision: 21 $ + * $Revision: 23 $ * *****************************************************************************/ @@ -430,10 +430,20 @@ case ACPI_TYPE_FIELD_UNIT: + + /* + * If the Field Buffer and Index have not been previously evaluated, + * evaluate them and save the results. + */ + if (!(dest_desc->common.flags & AOPOBJ_DATA_VALID)) { + status = acpi_ds_get_field_unit_arguments (dest_desc); + if (ACPI_FAILURE (status)) { + return (status); + } + } + if ((!dest_desc->field_unit.container || - ACPI_TYPE_BUFFER != dest_desc->field_unit.container->common.type || - dest_desc->field_unit.sequence != - dest_desc->field_unit.container->buffer.sequence)) + ACPI_TYPE_BUFFER != dest_desc->field_unit.container->common.type)) { status = AE_AML_INTERNAL; goto clean_up_and_bail_out; @@ -487,7 +497,12 @@ case ACPI_TYPE_NUMBER: + dest_desc->number.value = val_desc->number.value; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (dest_desc, walk_state); break; diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amstorob.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amstorob.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amstorob.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amstorob.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amstorob - AML Interpreter object store support, store to object - * $Revision: 16 $ + * $Revision: 17 $ * *****************************************************************************/ @@ -294,6 +294,10 @@ case ACPI_TYPE_NUMBER: dest_desc->number.value = val_desc->number.value; + + /* Truncate value if we are executing from a 32-bit ACPI table */ + + acpi_aml_truncate_for32bit_table (dest_desc, walk_state); break; default: diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amsystem.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amsystem.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amsystem.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amsystem.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amsystem - Interface to OS services - * $Revision: 51 $ + * $Revision: 52 $ * *****************************************************************************/ @@ -202,7 +202,7 @@ } status = acpi_aml_system_wait_semaphore (obj_desc->mutex.semaphore, - time_desc->number.value); + (u32) time_desc->number.value); return (status); } @@ -299,7 +299,7 @@ if (obj_desc) { status = acpi_aml_system_wait_semaphore (obj_desc->event.semaphore, - time_desc->number.value); + (u32) time_desc->number.value); } diff -urN linux-2.4.0-test12/drivers/acpi/interpreter/amutils.c linux-2.4.0-test12-lia/drivers/acpi/interpreter/amutils.c --- linux-2.4.0-test12/drivers/acpi/interpreter/amutils.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/interpreter/amutils.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amutils - interpreter/scanner utilities - * $Revision: 53 $ + * $Revision: 63 $ * *****************************************************************************/ @@ -131,24 +131,44 @@ /******************************************************************************* * - * FUNCTION: Acpi_aml_buf_seq + * FUNCTION: Acpi_aml_truncate_for32bit_table * - * RETURN: The next buffer descriptor sequence number + * PARAMETERS: Obj_desc - Object to be truncated + * Walk_state - Current walk state + * (A method must be executing) * - * DESCRIPTION: Provide a unique sequence number for each Buffer descriptor - * allocated during the interpreter's existence. These numbers - * are used to relate Field_unit descriptors to the Buffers - * within which the fields are defined. + * RETURN: none * - * Just increment the global counter and return it. + * DESCRIPTION: Truncate a number to 32-bits if the currently executing method + * belongs to a 32-bit ACPI table. * ******************************************************************************/ -u32 -acpi_aml_buf_seq (void) +void +acpi_aml_truncate_for32bit_table ( + ACPI_OPERAND_OBJECT *obj_desc, + ACPI_WALK_STATE *walk_state) { - return (++acpi_gbl_buf_seq); + /* + * Object must be a valid number and we must be executing + * a control method + */ + + if ((!obj_desc) || + (obj_desc->common.type != ACPI_TYPE_NUMBER) || + (!walk_state->method_node)) + { + return; + } + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + /* + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper 32-bit field + */ + obj_desc->number.value &= (UINT64) ACPI_UINT32_MAX; + } } @@ -242,20 +262,18 @@ u32 acpi_aml_digits_needed ( - u32 val, + ACPI_INTEGER val, u32 base) { u32 num_digits = 0; if (base < 1) { - /* impossible base */ - - REPORT_ERROR ("Aml_digits_needed: Impossible base"); + REPORT_ERROR (("Aml_digits_needed: Internal error - Invalid base\n")); } else { - for (num_digits = 1 + (val < 0) ; val /= base ; ++num_digits) { ; } + for (num_digits = 1 + (val < 0); (val = ACPI_DIVIDE (val,base)); ++num_digits) { ; } } return (num_digits); @@ -268,11 +286,11 @@ * * PARAMETERS: Value - Value to be converted * - * RETURN: Convert a 32-bit value to big-endian (swap the bytes) + * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) * ******************************************************************************/ -u32 +static u32 _ntohl ( u32 value) { @@ -307,7 +325,7 @@ * PARAMETERS: Numeric_id - EISA ID to be converted * Out_string - Where to put the converted string (8 bytes) * - * RETURN: Convert a numeric EISA ID to string representation + * DESCRIPTION: Convert a numeric EISA ID to string representation * ******************************************************************************/ @@ -337,6 +355,39 @@ /******************************************************************************* * + * FUNCTION: Acpi_aml_unsigned_integer_to_string + * + * PARAMETERS: Value - Value to be converted + * Out_string - Where to put the converted string (8 bytes) + * + * RETURN: Convert a number to string representation + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_unsigned_integer_to_string ( + ACPI_INTEGER value, + NATIVE_CHAR *out_string) +{ + u32 count; + u32 digits_needed; + + + digits_needed = acpi_aml_digits_needed (value, 10); + + out_string[digits_needed] = '\0'; + + for (count = digits_needed; count > 0; count--) { + out_string[count-1] = (NATIVE_CHAR) ('0' + (ACPI_MODULO (value, 10))); + value = ACPI_DIVIDE (value, 10); + } + + return (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_aml_build_copy_internal_package_object * * PARAMETERS: *Source_obj - Pointer to the source package object @@ -376,8 +427,8 @@ level_ptr = ©_level[0]; current_depth = 0; - dest_obj->common.type = source_obj->common.type; - dest_obj->package.count = source_obj->package.count; + dest_obj->common.type = source_obj->common.type; + dest_obj->package.count = source_obj->package.count; /* @@ -391,7 +442,7 @@ if (!dest_obj->package.elements) { /* Package vector allocation failure */ - REPORT_ERROR ("Aml_build_copy_internal_package_object: Package vector allocation failure"); + REPORT_ERROR (("Aml_build_copy_internal_package_object: Package vector allocation failure\n")); return (AE_NO_MEMORY); } @@ -400,8 +451,8 @@ while (1) { this_index = level_ptr->index; - this_dest_obj = (ACPI_OPERAND_OBJECT *) level_ptr->dest_obj->package.elements[this_index]; - this_source_obj = (ACPI_OPERAND_OBJECT *) level_ptr->source_obj->package.elements[this_index]; + this_dest_obj = (ACPI_OPERAND_OBJECT *) level_ptr->dest_obj->package.elements[this_index]; + this_source_obj = (ACPI_OPERAND_OBJECT *) level_ptr->source_obj->package.elements[this_index]; if (IS_THIS_OBJECT_TYPE (this_source_obj, ACPI_TYPE_PACKAGE)) { /* diff -urN linux-2.4.0-test12/drivers/acpi/ksyms.c linux-2.4.0-test12-lia/drivers/acpi/ksyms.c --- linux-2.4.0-test12/drivers/acpi/ksyms.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/ksyms.c Wed Nov 15 16:25:04 2000 @@ -0,0 +1,92 @@ +/* + * ksyms.c - ACPI exported symbols + * + * Copyright (C) 2000 Andrew Grover + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include "acpi.h" +#include "acdebug.h" + +extern int acpi_in_debugger; + +#define _COMPONENT OS_DEPENDENT + MODULE_NAME ("symbols") + +#ifdef ENABLE_DEBUGGER +EXPORT_SYMBOL(acpi_in_debugger); +EXPORT_SYMBOL(acpi_db_user_commands); +#endif + +EXPORT_SYMBOL(acpi_os_free); +EXPORT_SYMBOL(acpi_os_breakpoint); +EXPORT_SYMBOL(acpi_os_printf); +EXPORT_SYMBOL(acpi_os_callocate); +EXPORT_SYMBOL(acpi_os_sleep); +EXPORT_SYMBOL(acpi_os_sleep_usec); +EXPORT_SYMBOL(acpi_os_in8); +EXPORT_SYMBOL(acpi_os_out8); +EXPORT_SYMBOL(acpi_os_queue_for_execution); + +EXPORT_SYMBOL(acpi_dbg_layer); +EXPORT_SYMBOL(acpi_dbg_level); +EXPORT_SYMBOL(function_exit); +EXPORT_SYMBOL(function_trace); +EXPORT_SYMBOL(function_status_exit); +EXPORT_SYMBOL(function_value_exit); +EXPORT_SYMBOL(debug_print_raw); +EXPORT_SYMBOL(debug_print_prefix); + +EXPORT_SYMBOL(acpi_cm_strncmp); +EXPORT_SYMBOL(acpi_cm_memcpy); +EXPORT_SYMBOL(acpi_cm_memset); + +EXPORT_SYMBOL(acpi_get_handle); +EXPORT_SYMBOL(acpi_get_parent); +EXPORT_SYMBOL(acpi_get_type); +EXPORT_SYMBOL(acpi_get_name); +EXPORT_SYMBOL(acpi_get_object_info); +EXPORT_SYMBOL(acpi_get_next_object); +EXPORT_SYMBOL(acpi_evaluate_object); + +EXPORT_SYMBOL(acpi_install_notify_handler); +EXPORT_SYMBOL(acpi_remove_notify_handler); +EXPORT_SYMBOL(acpi_install_gpe_handler); +EXPORT_SYMBOL(acpi_remove_gpe_handler); +EXPORT_SYMBOL(acpi_install_address_space_handler); +EXPORT_SYMBOL(acpi_remove_address_space_handler); + +EXPORT_SYMBOL(acpi_get_current_resources); +EXPORT_SYMBOL(acpi_get_possible_resources); +EXPORT_SYMBOL(acpi_set_current_resources); + +EXPORT_SYMBOL(acpi_enable_event); +EXPORT_SYMBOL(acpi_disable_event); +EXPORT_SYMBOL(acpi_clear_event); + +EXPORT_SYMBOL(acpi_get_processor_throttling_info); +EXPORT_SYMBOL(acpi_get_processor_throttling_state); +EXPORT_SYMBOL(acpi_set_processor_throttling_state); + +EXPORT_SYMBOL(acpi_get_processor_cx_info); +EXPORT_SYMBOL(acpi_set_processor_sleep_state); +EXPORT_SYMBOL(acpi_processor_sleep); diff -urN linux-2.4.0-test12/drivers/acpi/namespace/Makefile linux-2.4.0-test12-lia/drivers/acpi/namespace/Makefile --- linux-2.4.0-test12/drivers/acpi/namespace/Makefile Fri Sep 15 18:21:44 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsaccess.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsaccess.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsaccess.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsaccess.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 108 $ + * $Revision: 113 $ * ******************************************************************************/ @@ -87,8 +87,6 @@ IMODE_LOAD_PASS2, NS_NO_UPSEARCH, NULL, &new_node); - if (ACPI_FAILURE (status) || - (!new_node)) /* * Name entered successfully. @@ -122,7 +120,7 @@ case ACPI_TYPE_NUMBER: obj_desc->number.value = - (u32) STRTOUL (init_val->val, NULL, 10); + (ACPI_INTEGER) STRTOUL (init_val->val, NULL, 10); break; @@ -138,11 +136,7 @@ */ obj_desc->string.pointer = acpi_cm_allocate ( (obj_desc->string.length + 1)); - if (!obj_desc->string.pointer) { - REPORT_ERROR ("Initial value string" - "allocation failure"); - acpi_cm_remove_reference (obj_desc); status = AE_NO_MEMORY; goto unlock_and_exit; @@ -190,7 +184,8 @@ default: - REPORT_ERROR ("Unsupported initial type value"); + REPORT_ERROR (("Unsupported initial type value %X\n", + init_val->type)); acpi_cm_remove_reference (obj_desc); obj_desc = NULL; continue; @@ -254,6 +249,9 @@ OBJECT_TYPE_INTERNAL type_to_check_for; OBJECT_TYPE_INTERNAL this_search_type; + DEBUG_ONLY_MEMBERS (u32 i) + + if (!return_node) { return (AE_BAD_PARAMETER); } @@ -379,8 +377,7 @@ if (!this_node) { /* Current scope has no parent scope */ - REPORT_ERROR ("Too many parent prefixes (^) - reached root"); - + REPORT_ERROR (("Too many parent prefixes (^) - reached root\n")); return (AE_NOT_FOUND); } @@ -467,25 +464,29 @@ * If 1) This is the last segment (Num_segments == 0) * 2) and looking for a specific type * (Not checking for TYPE_ANY) - * 3) which is not a local type (TYPE_DEF_ANY) - * 4) which is not a local type (TYPE_SCOPE) - * 5) which is not a local type (TYPE_INDEX_FIELD_DEFN) - * 6) and type of object is known (not TYPE_ANY) - * 7) and object does not match request + * 3) Which is not an alias + * 4) which is not a local type (TYPE_DEF_ANY) + * 5) which is not a local type (TYPE_SCOPE) + * 6) which is not a local type (TYPE_INDEX_FIELD_DEFN) + * 7) and type of object is known (not TYPE_ANY) + * 8) and object does not match request * * Then we have a type mismatch. Just warn and ignore it. */ if ((num_segments == 0) && (type_to_check_for != ACPI_TYPE_ANY) && + (type_to_check_for != INTERNAL_TYPE_ALIAS) && (type_to_check_for != INTERNAL_TYPE_DEF_ANY) && (type_to_check_for != INTERNAL_TYPE_SCOPE) && (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) && - (this_node->type != ACPI_TYPE_ANY) && - (this_node->type != type_to_check_for)) + (this_node->type != ACPI_TYPE_ANY) && + (this_node->type != type_to_check_for)) { /* Complain about a type mismatch */ - REPORT_WARNING ("Type mismatch"); + REPORT_WARNING ( + ("Ns_lookup: %4.4s, type 0x%X, checking for type 0x%X\n", + &simple_name, this_node->type, type_to_check_for)); } /* diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsalloc.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsalloc.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsalloc.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsalloc.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 41 $ + * $Revision: 42 $ * ******************************************************************************/ @@ -434,7 +434,7 @@ * ******************************************************************************/ -void +static void acpi_ns_remove_reference ( ACPI_NAMESPACE_NODE *node) { diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsdump.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsdump.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsdump.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsdump.c Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/****************************************************************************** - * - * Module Name: nsdump - table dumping routines for debug - * $Revision: 78 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acinterp.h" -#include "acnamesp.h" -#include "actables.h" - - -#define _COMPONENT NAMESPACE - MODULE_NAME ("nsdump") - - diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nseval.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nseval.c --- linux-2.4.0-test12/drivers/acpi/namespace/nseval.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nseval.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 76 $ + * $Revision: 79 $ * ******************************************************************************/ @@ -99,7 +99,7 @@ /* Lookup the name in the namespace */ - scope_info.scope.node = prefix_node->child; + scope_info.scope.node = prefix_node; status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_NO_UPSEARCH, NULL, &node); @@ -432,28 +432,14 @@ } /* - * Just copy from the original to the return object + * Just copy from the original to the return object + * + * TBD: [Future] - need a low-level object copy that handles + * the reference count automatically. (Don't want to copy it) */ - switch (node->type) - { - case ACPI_TYPE_PROCESSOR: - obj_desc->processor.proc_id = val_desc->processor.proc_id; - obj_desc->processor.address = val_desc->processor.address; - obj_desc->processor.sys_handler = val_desc->processor.sys_handler; - obj_desc->processor.drv_handler = val_desc->processor.drv_handler; - obj_desc->processor.addr_handler = val_desc->processor.addr_handler; - - break; - - case ACPI_TYPE_POWER: - obj_desc->power_resource.system_level = val_desc->power_resource.system_level; - obj_desc->power_resource.resource_order = val_desc->power_resource.resource_order; - obj_desc->power_resource.sys_handler = val_desc->power_resource.sys_handler; - obj_desc->power_resource.drv_handler = val_desc->power_resource.drv_handler; - - break; - } + MEMCPY (obj_desc, val_desc, sizeof (ACPI_OPERAND_OBJECT)); + obj_desc->common.reference_count = 1; } @@ -483,9 +469,17 @@ * NOTE: we can get away with passing in NULL for a walk state * because Obj_desc is guaranteed to not be a reference to either * a method local or a method argument + * + * Even though we do not technically need to use the interpreter + * for this, we must enter it because we could hit an opregion. + * The opregion access code assumes it is in the interpreter. */ + acpi_aml_enter_interpreter(); + status = acpi_aml_resolve_to_value (&obj_desc, NULL); + + acpi_aml_exit_interpreter(); } /* diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsinit.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsinit.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsinit.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsinit.c Wed Nov 15 16:25:04 2000 @@ -0,0 +1,354 @@ +/****************************************************************************** + * + * Module Name: nsinit - namespace initialization + * $Revision: 5 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "acnamesp.h" +#include "acdispat.h" + +#define _COMPONENT NAMESPACE + MODULE_NAME ("nsinit") + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_initialize_objects + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Walk the entire namespace and perform any necessary + * initialization on the objects found therein + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_initialize_objects ( + void) +{ + ACPI_STATUS status; + ACPI_INIT_WALK_INFO info; + + + info.field_count = 0; + info.field_init = 0; + info.op_region_count = 0; + info.op_region_init = 0; + info.object_count = 0; + + + /* Walk entire namespace from the supplied root */ + + status = acpi_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, acpi_ns_init_one_object, + &info, NULL); + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_ns_initialize_devices + * + * PARAMETERS: None + * + * RETURN: ACPI_STATUS + * + * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices. + * This means running _INI on all present devices. + * + * Also: Install PCI config space handler for all PCI root bridges. + * A PCI root bridge is found by searching for devices containing + * a HID with the value EISAID("PNP0A03") + * + *****************************************************************************/ + +ACPI_STATUS +acpi_ns_initialize_devices ( + u32 flags) +{ + ACPI_STATUS status; + ACPI_DEVICE_WALK_INFO info; + + + info.flags = flags; + info.device_count = 0; + info.num_STA = 0; + info.num_INI = 0; + info.num_HID = 0; + info.num_PCI = 0; + + + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + FALSE, acpi_ns_init_one_device, &info, NULL); + + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_init_one_object + * + * PARAMETERS: Obj_handle - Node + * Level - Current nesting level + * Context - Points to a init info struct + * Return_value - Not used + * + * RETURN: Status + * + * DESCRIPTION: Callback from Acpi_walk_namespace. Invoked for every object + * within the namespace. + * + * Currently, the only objects that require initialization are: + * 1) Methods + * 2) Op Regions + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_init_one_object ( + ACPI_HANDLE obj_handle, + u32 level, + void *context, + void **return_value) +{ + OBJECT_TYPE_INTERNAL type; + ACPI_STATUS status; + ACPI_INIT_WALK_INFO *info = (ACPI_INIT_WALK_INFO *) context; + ACPI_NAMESPACE_NODE *node = (ACPI_NAMESPACE_NODE *) obj_handle; + ACPI_OPERAND_OBJECT *obj_desc; + + + info->object_count++; + + + /* And even then, we are only interested in a few object types */ + + type = acpi_ns_get_type (obj_handle); + obj_desc = node->object; + if (!obj_desc) { + return (AE_OK); + } + + switch (type) + { + + case ACPI_TYPE_REGION: + + info->op_region_count++; + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + break; + } + + info->op_region_init++; + status = acpi_ds_get_region_arguments (obj_desc); + break; + + + case ACPI_TYPE_FIELD_UNIT: + + info->field_count++; + if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { + break; + } + + info->field_init++; + status = acpi_ds_get_field_unit_arguments (obj_desc); + break; + + default: + break; + } + + /* + * We ignore errors from above, and always return OK, since + * we don't want to abort the walk on a single error. + */ + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_ns_init_one_device + * + * PARAMETERS: The usual "I'm a namespace callback" stuff + * + * RETURN: ACPI_STATUS + * + * DESCRIPTION: This is called once per device soon after ACPI is enabled + * to initialize each device. It determines if the device is + * present, and if so, calls _INI. + * + *****************************************************************************/ + +ACPI_STATUS +acpi_ns_init_one_device ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_OPERAND_OBJECT *ret_obj = NULL; + ACPI_NAMESPACE_NODE *node; + u32 flags; + ACPI_DEVICE_WALK_INFO *info = (ACPI_DEVICE_WALK_INFO *) context; + + + info->device_count++; + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + + node = acpi_ns_convert_handle_to_entry (obj_handle); + if (!node) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + /* + * Run _STA to determine if we can run _INI on the device. + */ + + status = acpi_cm_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (status); + } + + info->num_STA++; + + if (!(flags & 0x01)) { + /* don't look at children of a not present device */ + return(AE_CTRL_DEPTH); + } + + /* + * The device is present. Run _INI. + */ + + status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL); + if (AE_NOT_FOUND == status) { + /* No _INI means device requires no initialization */ + } + + else if (ACPI_FAILURE (status)) { + return (status); + } + + else { + info->num_INI++; + } + + + /* + * Examine the HID of the device. _HID can be an executable + * control method -- it simply has to return a string or number + * containing the HID. + */ + + if (ret_obj) { + acpi_cm_remove_reference (ret_obj); + } + + ret_obj = NULL; + status = acpi_ns_evaluate_relative (obj_handle, "_HID", NULL, &ret_obj); + if (AE_NOT_FOUND == status) { + /* No _HID --> Can't be a PCI root bridge */ + return (AE_OK); + } + + if (ACPI_FAILURE (status)) { + return (status); + } + + info->num_HID++; + + + /* + * Found an _HID object. + * Check for a PCI Root Bridge. We need to install the PCI_CONFIG space + * handler on all PCI Root Bridges found within the namespace + * + * A PCI Root Bridge has an HID with the value EISAID("PNP0A03") + * The HID can be either a number or a string. + */ + + switch (ret_obj->common.type) + { + case ACPI_TYPE_NUMBER: + + if (ret_obj->number.value != PCI_ROOT_HID_VALUE) { + goto cleanup; + } + + break; + + case ACPI_TYPE_STRING: + + if (STRNCMP (ret_obj->string.pointer, PCI_ROOT_HID_STRING, + sizeof (PCI_ROOT_HID_STRING))) + { + goto cleanup; + } + + break; + + default: + + goto cleanup; + } + + + /* + * We found a valid PCI_ROOT_HID. + * The parent of the HID entry is the PCI device; Install the default PCI + * handler for this PCI device. + */ + + info->num_PCI++; + + if (!(info->flags & ACPI_NO_PCI_INIT)) { + status = acpi_install_address_space_handler (obj_handle, + ADDRESS_SPACE_PCI_CONFIG, + ACPI_DEFAULT_HANDLER, NULL, NULL); + } + +cleanup: + + if (ret_obj) { + acpi_cm_remove_reference (ret_obj); + } + + return (status); +} + + diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsload.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsload.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsload.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsload.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 28 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -37,6 +37,123 @@ MODULE_NAME ("nsload") +/****************************************************************************** + * + * FUNCTION: Acpi_load_namespace + * + * PARAMETERS: Display_aml_during_load + * + * RETURN: Status + * + * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. + * (DSDT points to either the BIOS or a buffer.) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_load_namespace ( + void) +{ + ACPI_STATUS status; + + + /* There must be at least a DSDT installed */ + + if (acpi_gbl_DSDT == NULL) { + return (AE_NO_ACPI_TABLES); + } + + + /* + * Load the namespace. The DSDT is required, + * but the SSDT and PSDT tables are optional. + */ + + status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Ignore exceptions from these */ + + acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); + acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ns_one_parse_pass + * + * PARAMETERS: + * + * RETURN: Status + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_ns_one_complete_parse ( + u32 pass_number, + ACPI_TABLE_DESC *table_desc) +{ + ACPI_PARSE_DOWNWARDS descending_callback; + ACPI_PARSE_UPWARDS ascending_callback; + ACPI_PARSE_OBJECT *parse_root; + ACPI_STATUS status; + + + switch (pass_number) + { + case 1: + descending_callback = acpi_ds_load1_begin_op; + ascending_callback = acpi_ds_load1_end_op; + break; + + case 2: + descending_callback = acpi_ds_load2_begin_op; + ascending_callback = acpi_ds_load2_end_op; + break; + + case 3: + descending_callback = acpi_ds_exec_begin_op; + ascending_callback = acpi_ds_exec_end_op; + break; + + default: + return (AE_BAD_PARAMETER); + } + + /* Create and init a Root Node */ + + parse_root = acpi_ps_alloc_op (AML_SCOPE_OP); + if (!parse_root) { + return (AE_NO_MEMORY); + } + + ((ACPI_PARSE2_OBJECT *) parse_root)->name = ACPI_ROOT_NAME; + + + /* Pass 1: Parse everything except control method bodies */ + + status = acpi_ps_parse_aml (parse_root, + table_desc->aml_pointer, + table_desc->aml_length, + ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, + NULL, NULL, NULL, + descending_callback, + ascending_callback); + + acpi_ps_delete_parse_tree (parse_root); + + return (status); +} + + /******************************************************************************* * * FUNCTION: Acpi_ns_parse_table @@ -69,32 +186,11 @@ * performs another complete parse of the AML.. */ - /* Create and init a Root Node */ - - acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!acpi_gbl_parsed_namespace_root) { - return (AE_NO_MEMORY); - } - - ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME; - - - /* Pass 1: Parse everything except control method bodies */ - - status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root, - table_desc->aml_pointer, - table_desc->aml_length, - ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, - NULL, NULL, NULL, - acpi_ds_load1_begin_op, - acpi_ds_load1_end_op); - + status = acpi_ns_one_complete_parse (1, table_desc); if (ACPI_FAILURE (status)) { return (status); } - acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root); - /* * AML Parse, pass 2 @@ -106,34 +202,11 @@ * parse objects are all cached. */ - /* Create and init a Root Node */ - - acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP); - if (!acpi_gbl_parsed_namespace_root) { - return (AE_NO_MEMORY); - } - - ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME; - - - /* Pass 2: Resolve forward references */ - - status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root, - table_desc->aml_pointer, - table_desc->aml_length, - ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE, - NULL, NULL, NULL, - acpi_ds_load2_begin_op, - acpi_ds_load2_end_op); - + status = acpi_ns_one_complete_parse (2, table_desc); if (ACPI_FAILURE (status)) { return (status); } - acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root); - acpi_gbl_parsed_namespace_root = NULL; - - return (status); } @@ -147,8 +220,7 @@ * * RETURN: Status * - * DESCRIPTION: Mainline of the AML load/dump subsystem. Sets up the - * input engine, calls handler for outermost object type. + * DESCRIPTION: Load one ACPI table into the namespace * ****************************************************************************/ @@ -247,13 +319,6 @@ } table_desc->table_id = TABLE_ID_DSDT; - - /* Initialize the root of the namespace tree */ - - status = acpi_ns_root_initialize (); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } /* Now load the single DSDT */ diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsnames.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsnames.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsnames.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsnames.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 48 $ + * $Revision: 49 $ * ******************************************************************************/ @@ -86,7 +86,7 @@ name_buffer = acpi_cm_callocate (size + 1); if (!name_buffer) { - REPORT_ERROR ("Ns_get_table_pathname: allocation failure"); + REPORT_ERROR (("Ns_get_table_pathname: allocation failure\n")); return (NULL); } diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsobject.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsobject.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsobject.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsobject.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: nsobject - Utilities for objects attached to namespace * table entries - * $Revision: 44 $ + * $Revision: 47 $ * ******************************************************************************/ @@ -73,29 +73,28 @@ if (!acpi_gbl_root_node) { /* Name space not initialized */ - REPORT_ERROR ("Ns_attach_object: Name space not initialized"); + REPORT_ERROR (("Ns_attach_object: Namespace not initialized\n")); return (AE_NO_NAMESPACE); } if (!node) { /* Invalid handle */ - REPORT_ERROR ("Ns_attach_object: Null Named_obj handle"); + REPORT_ERROR (("Ns_attach_object: Null Named_obj handle\n")); return (AE_BAD_PARAMETER); } if (!object && (ACPI_TYPE_ANY != type)) { /* Null object */ - REPORT_ERROR ("Ns_attach_object: Null object, but type" - "not ACPI_TYPE_ANY"); + REPORT_ERROR (("Ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n")); return (AE_BAD_PARAMETER); } if (!VALID_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED)) { /* Not a name handle */ - REPORT_ERROR ("Ns_attach_object: Invalid handle"); + REPORT_ERROR (("Ns_attach_object: Invalid handle\n")); return (AE_BAD_PARAMETER); } @@ -355,7 +354,6 @@ if (!handle) { /* handle invalid */ - REPORT_WARNING ("Ns_get_attached_object: Null handle"); return (NULL); } diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nssearch.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nssearch.c --- linux-2.4.0-test12/drivers/acpi/namespace/nssearch.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nssearch.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nssearch - Namespace search - * $Revision: 57 $ + * $Revision: 59 $ * ******************************************************************************/ @@ -169,7 +169,7 @@ * ******************************************************************************/ -ACPI_STATUS +static ACPI_STATUS acpi_ns_search_parent_tree ( u32 target_name, ACPI_NAMESPACE_NODE *node, @@ -270,7 +270,7 @@ /* Parameter validation */ if (!node || !target_name || !return_node) { - REPORT_ERROR ("Ns_search_and_enter: bad (null)parameter"); + REPORT_ERROR (("Ns_search_and_enter: bad (null) parameter\n")); return (AE_BAD_PARAMETER); } @@ -278,7 +278,7 @@ /* Name must consist of printable characters */ if (!acpi_cm_valid_acpi_name (target_name)) { - REPORT_ERROR ("Ns_search_and_enter: Bad character in ACPI Name"); + REPORT_ERROR (("Ns_search_and_enter: Bad character in ACPI Name\n")); return (AE_BAD_CHARACTER); } diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsutils.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsutils.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsutils.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsutils.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing * parents and siblings and Scope manipulation - * $Revision: 69 $ + * $Revision: 72 $ * *****************************************************************************/ @@ -93,7 +93,7 @@ { if (!handle) { - REPORT_WARNING ("Ns_get_type: Null handle"); + REPORT_WARNING (("Ns_get_type: Null handle\n")); return (ACPI_TYPE_ANY); } @@ -120,7 +120,7 @@ if (!acpi_cm_valid_object_type (type)) { /* Type code out of range */ - REPORT_WARNING ("Ns_local: Invalid Object Type"); + REPORT_WARNING (("Ns_local: Invalid Object Type\n")); return (NSP_NORMAL); } @@ -150,9 +150,10 @@ { NATIVE_CHAR *result = NULL; NATIVE_CHAR *internal_name; - u32 num_segments; + u32 num_segments = 0; u8 fully_qualified = FALSE; u32 i; + u32 num_carats = 0; if ((!external_name) || @@ -178,6 +179,16 @@ external_name++; } + else { + /* + * Handle Carat prefixes + */ + + while (*external_name == '^') { + num_carats++; + external_name++; + } + } /* * Determine the number of ACPI name "segments" by counting @@ -186,17 +197,19 @@ * + 1, and zero separators is ok. */ - num_segments = 1; - for (i = 0; external_name[i]; i++) { - if (acpi_ns_valid_path_separator (external_name[i])) { - num_segments++; + if (*external_name) { + num_segments = 1; + for (i = 0; external_name[i]; i++) { + if (acpi_ns_valid_path_separator (external_name[i])) { + num_segments++; + } } } /* We need a segment to store the internal version of the name */ - internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4); + internal_name = acpi_cm_callocate ((ACPI_NAME_SIZE * num_segments) + 4 + num_carats); if (!internal_name) { return (AE_NO_MEMORY); } @@ -206,14 +219,49 @@ if (fully_qualified) { internal_name[0] = '\\'; - internal_name[1] = AML_MULTI_NAME_PREFIX_OP; - internal_name[2] = (char) num_segments; - result = &internal_name[3]; + + if (num_segments <= 1) { + result = &internal_name[1]; + } + else if (num_segments == 2) { + internal_name[1] = AML_DUAL_NAME_PREFIX; + result = &internal_name[2]; + } + else { + internal_name[1] = AML_MULTI_NAME_PREFIX_OP; + internal_name[2] = (char) num_segments; + result = &internal_name[3]; + } + } + else { - internal_name[0] = AML_MULTI_NAME_PREFIX_OP; - internal_name[1] = (char) num_segments; - result = &internal_name[2]; + /* + * Not fully qualified. + * Handle Carats first, then append the name segments + */ + + i = 0; + if (num_carats) { + for (i = 0; i < num_carats; i++) { + internal_name[i] = '^'; + } + } + + if (num_segments == 1) { + result = &internal_name[i]; + } + + else if (num_segments == 2) { + internal_name[i] = AML_DUAL_NAME_PREFIX; + result = &internal_name[i+1]; + } + + else { + internal_name[i] = AML_MULTI_NAME_PREFIX_OP; + internal_name[i+1] = (char) num_segments; + result = &internal_name[i+2]; + } } @@ -271,6 +319,157 @@ /**************************************************************************** * + * FUNCTION: Acpi_ns_externalize_name + * + * PARAMETERS: *Internal_name - Internal representation of name + * **Converted_name - Where to return the resulting + * external representation of name + * + * RETURN: Status + * + * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) + * to its external form (e.g. "\_PR_.CPU0") + * + ****************************************************************************/ + +ACPI_STATUS +acpi_ns_externalize_name ( + u32 internal_name_length, + char *internal_name, + u32 *converted_name_length, + char **converted_name) +{ + u32 prefix_length = 0; + u32 names_index = 0; + u32 names_count = 0; + u32 i = 0; + u32 j = 0; + + + if (!internal_name_length || + !internal_name || + !converted_name_length || + !converted_name) + { + return (AE_BAD_PARAMETER); + } + + + /* + * Check for a prefix (one '\' | one or more '^'). + */ + switch (internal_name[0]) + { + case '\\': + prefix_length = 1; + break; + + case '^': + for (i = 0; i < internal_name_length; i++) { + if (internal_name[i] != '^') { + prefix_length = i + 1; + } + } + + if (i == internal_name_length) { + prefix_length = i; + } + + break; + } + + /* + * Check for object names. Note that there could be 0-255 of these + * 4-byte elements. + */ + if (prefix_length < internal_name_length) { + switch (internal_name[prefix_length]) + { + + /* 4-byte names */ + + case AML_MULTI_NAME_PREFIX_OP: + names_index = prefix_length + 2; + names_count = (u32) internal_name[prefix_length + 1]; + break; + + + /* two 4-byte names */ + + case AML_DUAL_NAME_PREFIX: + names_index = prefix_length + 1; + names_count = 2; + break; + + + /* Null_name */ + + case 0: + names_index = 0; + names_count = 0; + break; + + + /* one 4-byte name */ + + default: + names_index = prefix_length; + names_count = 1; + break; + } + } + + /* + * Calculate the length of Converted_name, which equals the length + * of the prefix, length of all object names, length of any required + * punctuation ('.') between object names, plus the NULL terminator. + */ + *converted_name_length = prefix_length + (4 * names_count) + + ((names_count > 0) ? (names_count - 1) : 0) + 1; + + /* + * Check to see if we're still in bounds. If not, there's a problem + * with Internal_name (invalid format). + */ + if (*converted_name_length > internal_name_length) { + REPORT_ERROR (("Ns_externalize_name: Invalid internal name\n")); + return (AE_BAD_PATHNAME); + } + + /* + * Build Converted_name... + */ + + (*converted_name) = acpi_cm_callocate (*converted_name_length); + if (!(*converted_name)) { + return (AE_NO_MEMORY); + } + + j = 0; + + for (i = 0; i < prefix_length; i++) { + (*converted_name)[j++] = internal_name[i]; + } + + if (names_count > 0) { + for (i = 0; i < names_count; i++) { + if (i > 0) { + (*converted_name)[j++] = '.'; + } + + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + (*converted_name)[j++] = internal_name[names_index++]; + } + } + + return (AE_OK); +} + + +/**************************************************************************** + * * FUNCTION: Acpi_ns_convert_handle_to_entry * * PARAMETERS: Handle - Handle to be converted to an Node @@ -425,7 +624,7 @@ if (!acpi_cm_valid_object_type (type)) { /* type code out of range */ - REPORT_WARNING ("Ns_opens_scope: Invalid Object Type"); + REPORT_WARNING (("Ns_opens_scope: Invalid Object Type\n")); return (NSP_NORMAL); } diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsxfname.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsxfname.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsxfname.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsxfname.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: nsxfname - Public interfaces to the ACPI subsystem * ACPI Namespace oriented interfaces - * $Revision: 64 $ + * $Revision: 72 $ * *****************************************************************************/ @@ -38,60 +38,6 @@ MODULE_NAME ("nsxfname") -/****************************************************************************** - * - * FUNCTION: Acpi_load_namespace - * - * PARAMETERS: Display_aml_during_load - * - * RETURN: Status - * - * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. - * (DSDT points to either the BIOS or a buffer.) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_load_namespace ( - void) -{ - ACPI_STATUS status; - - - /* There must be at least a DSDT installed */ - - if (acpi_gbl_DSDT == NULL) { - return (AE_NO_ACPI_TABLES); - } - - - /* - * Load the namespace. The DSDT is required, - * but the SSDT and PSDT tables are optional. - */ - - status = acpi_ns_load_table_by_type (ACPI_TABLE_DSDT); - if (ACPI_FAILURE (status)) { - return (status); - } - - /* Ignore exceptions from these */ - - acpi_ns_load_table_by_type (ACPI_TABLE_SSDT); - acpi_ns_load_table_by_type (ACPI_TABLE_PSDT); - - - /* - * Install the default Op_region handlers, ignore the return - * code right now. - */ - - acpi_ev_install_default_address_space_handlers (); - - return (status); -} - - /**************************************************************************** * * FUNCTION: Acpi_get_handle @@ -117,7 +63,7 @@ ACPI_HANDLE *ret_handle) { ACPI_STATUS status; - ACPI_NAMESPACE_NODE *node; + ACPI_NAMESPACE_NODE *node = NULL; ACPI_NAMESPACE_NODE *prefix_node = NULL; @@ -128,13 +74,12 @@ if (parent) { acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - node = acpi_ns_convert_handle_to_entry (parent); - if (!node) { + prefix_node = acpi_ns_convert_handle_to_entry (parent); + if (!prefix_node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - prefix_node = node->child; acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); } @@ -149,8 +94,7 @@ /* * Find the Node and convert to the user format */ - node = NULL; - status = acpi_ns_get_node (pathname, prefix_node, &node); + status = acpi_ns_get_node (pathname, node, &node); *ret_handle = NULL; if(ACPI_SUCCESS(status)) { @@ -253,42 +197,41 @@ * * RETURN: Status * - * DESCRIPTION: Returns information about an object as gleaned from running - * several standard control methods. + * DESCRIPTION: Returns information about an object as gleaned from the + * namespace node and possibly by running several standard + * control methods (Such as in the case of a device.) * ******************************************************************************/ ACPI_STATUS acpi_get_object_info ( - ACPI_HANDLE device, + ACPI_HANDLE handle, ACPI_DEVICE_INFO *info) { DEVICE_ID hid; DEVICE_ID uid; ACPI_STATUS status; u32 device_status = 0; - u32 address = 0; - ACPI_NAMESPACE_NODE *device_node; + ACPI_INTEGER address = 0; + ACPI_NAMESPACE_NODE *node; /* Parameter validation */ - if (!device || !info) { + if (!handle || !info) { return (AE_BAD_PARAMETER); } acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); - device_node = acpi_ns_convert_handle_to_entry (device); - if (!device_node) { + node = acpi_ns_convert_handle_to_entry (handle); + if (!node) { acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - info->type = device_node->type; - info->name = device_node->name; - info->parent = acpi_ns_convert_entry_to_handle ( - acpi_ns_get_parent_object (device_node)); + info->type = node->type; + info->name = node->name; acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); @@ -300,34 +243,30 @@ } - /* Get extra info for ACPI devices */ + /* + * Get extra info for ACPI devices only. Run the + * _HID, _UID, _STA, and _ADR methods. Note: none + * of these methods are required, so they may or may + * not be present. The Info->Valid bits are used + * to indicate which methods ran successfully. + */ info->valid = 0; /* Execute the _HID method and save the result */ - status = acpi_cm_execute_HID (device_node, &hid); + status = acpi_cm_execute_HID (node, &hid); if (ACPI_SUCCESS (status)) { - if (hid.type == STRING_PTR_DEVICE_ID) { - STRCPY (info->hardware_id, hid.data.string_ptr); - } - else { - STRCPY (info->hardware_id, hid.data.buffer); - } + STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id)); info->valid |= ACPI_VALID_HID; } /* Execute the _UID method and save the result */ - status = acpi_cm_execute_UID (device_node, &uid); + status = acpi_cm_execute_UID (node, &uid); if (ACPI_SUCCESS (status)) { - if (hid.type == STRING_PTR_DEVICE_ID) { - STRCPY (info->unique_id, uid.data.string_ptr); - } - else { - STRCPY (info->unique_id, uid.data.buffer); - } + STRCPY (info->unique_id, uid.buffer); info->valid |= ACPI_VALID_UID; } @@ -337,7 +276,7 @@ * _STA is not always present */ - status = acpi_cm_execute_STA (device_node, &device_status); + status = acpi_cm_execute_STA (node, &device_status); if (ACPI_SUCCESS (status)) { info->current_status = device_status; info->valid |= ACPI_VALID_STA; @@ -349,7 +288,7 @@ */ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, - device_node, &address); + node, &address); if (ACPI_SUCCESS (status)) { info->address = address; diff -urN linux-2.4.0-test12/drivers/acpi/namespace/nsxfobj.c linux-2.4.0-test12-lia/drivers/acpi/namespace/nsxfobj.c --- linux-2.4.0-test12/drivers/acpi/namespace/nsxfobj.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/namespace/nsxfobj.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 65 $ + * $Revision: 74 $ * ******************************************************************************/ @@ -28,6 +28,7 @@ #include "acpi.h" #include "acinterp.h" #include "acnamesp.h" +#include "acdispat.h" #define _COMPONENT NAMESPACE @@ -484,6 +485,8 @@ * Max_depth - Depth to which search is to reach * User_function - Called when an object of "Type" is found * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early * * RETURNS Return value from the User_function if terminated early. * Otherwise, returns NULL. @@ -544,3 +547,151 @@ } +/******************************************************************************* + * + * FUNCTION: Acpi_ns_get_device_callback + * + * PARAMETERS: Callback from Acpi_get_device + * + * RETURN: Status + * + * DESCRIPTION: Takes callbacks from Walk_namespace and filters out all non- + * present devices, or if they specified a HID, it filters based + * on that. + * + ******************************************************************************/ + +static ACPI_STATUS +acpi_ns_get_device_callback ( + ACPI_HANDLE obj_handle, + u32 nesting_level, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_NAMESPACE_NODE *node; + u32 flags; + DEVICE_ID device_id; + ACPI_GET_DEVICES_INFO *info; + + + info = context; + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + + node = acpi_ns_convert_handle_to_entry (obj_handle); + if (!node) { + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); + } + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + /* + * Run _STA to determine if device is present + */ + + status = acpi_cm_execute_STA (node, &flags); + if (ACPI_FAILURE (status)) { + return (status); + } + + if (!(flags & 0x01)) { + /* don't return at the device or children of the device if not there */ + + return (AE_CTRL_DEPTH); + } + + /* + * Filter based on device HID + */ + if (info->hid != NULL) { + status = acpi_cm_execute_HID (node, &device_id); + + if (status == AE_NOT_FOUND) { + return (AE_OK); + } + + else if (ACPI_FAILURE (status)) { + return (status); + } + + if (STRNCMP (device_id.buffer, info->hid, sizeof (device_id.buffer)) != 0) { + return (AE_OK); + } + } + + info->user_function (obj_handle, nesting_level, info->context, return_value); + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_get_devices + * + * PARAMETERS: HID - HID to search for. Can be NULL. + * User_function - Called when a matching object is found + * Context - Passed to user function + * Return_value - Location where return value of + * User_function is put if terminated early + * + * RETURNS Return value from the User_function if terminated early. + * Otherwise, returns NULL. + * + * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, + * starting (and ending) at the object specified by Start_handle. + * The User_function is called whenever an object that matches + * the type parameter is found. If the user function returns + * a non-zero value, the search is terminated immediately and this + * value is returned to the caller. + * + * This is a wrapper for Walk_namespace, but the callback performs + * additional filtering. Please see Acpi_get_device_callback. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_get_devices ( + NATIVE_CHAR *HID, + WALK_CALLBACK user_function, + void *context, + void **return_value) +{ + ACPI_STATUS status; + ACPI_GET_DEVICES_INFO info; + + + /* Parameter validation */ + + if (!user_function) { + return (AE_BAD_PARAMETER); + } + + /* + * We're going to call their callback from OUR callback, so we need + * to know what it is, and their context parameter. + */ + info.context = context; + info.user_function = user_function; + info.hid = HID; + + /* + * Lock the namespace around the walk. + * The namespace will be unlocked/locked around each call + * to the user function - since this function + * must be allowed to make Acpi calls itself. + */ + + acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, + NS_WALK_UNLOCK, + acpi_ns_get_device_callback, &info, + return_value); + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + + return (status); +} \ No newline at end of file diff -urN linux-2.4.0-test12/drivers/acpi/os.c linux-2.4.0-test12-lia/drivers/acpi/os.c --- linux-2.4.0-test12/drivers/acpi/os.c Fri Sep 22 14:21:17 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/os.c Sat Nov 18 04:03:14 2000 @@ -2,6 +2,8 @@ * os.c - OS-dependent functions * * Copyright (C) 2000 Andrew Henroid + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,34 +20,69 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include + #include #include #include #include #include #include -#include +#include +#include #include +#include #include "acpi.h" +#ifndef CONFIG_ACPI_KERNEL_CONFIG_ONLY #include "driver.h" +#endif #define _COMPONENT OS_DEPENDENT MODULE_NAME ("os") +#ifdef CONFIG_ACPI_KERNEL_CONFIG +#include "osconf.h" + +struct acpi_osd acpi_osd_rt = { + /* these are runtime osd entries that differ from boottime entries */ + acpi_os_allocate_rt, + acpi_os_callocate_rt, + acpi_os_free_rt, + acpi_os_queue_for_execution_rt, + acpi_os_read_pci_cfg_byte_rt, + acpi_os_read_pci_cfg_word_rt, + acpi_os_read_pci_cfg_dword_rt, + acpi_os_write_pci_cfg_byte_rt, + acpi_os_write_pci_cfg_word_rt, + acpi_os_write_pci_cfg_dword_rt +}; +#else +#define acpi_os_allocate_rt acpi_os_allocate +#define acpi_os_callocate_rt acpi_os_callocate +#define acpi_os_free_rt acpi_os_free +#define acpi_os_queue_for_execution_rt acpi_os_queue_for_execution +#define acpi_os_read_pci_cfg_byte_rt acpi_os_read_pci_cfg_byte +#define acpi_os_read_pci_cfg_word_rt acpi_os_read_pci_cfg_word +#define acpi_os_read_pci_cfg_dword_rt acpi_os_read_pci_cfg_dword +#define acpi_os_write_pci_cfg_byte_rt acpi_os_write_pci_cfg_byte +#define acpi_os_write_pci_cfg_word_rt acpi_os_write_pci_cfg_word +#define acpi_os_write_pci_cfg_dword_rt acpi_os_write_pci_cfg_dword +#endif + static int acpi_irq_irq = 0; static OSD_HANDLER acpi_irq_handler = NULL; static void *acpi_irq_context = NULL; -char * -strupr(char *str) -{ - char *s = str; - while (*s) { - *s = TOUPPER(*s); - s++; - } - return str; -} +#ifdef ENABLE_DEBUGGER + +#include + +/* stuff for debugger support */ +int acpi_in_debugger = 0; +extern NATIVE_CHAR line_buf[80]; + +#endif + ACPI_STATUS acpi_os_initialize(void) @@ -79,18 +116,28 @@ { static char buffer[512]; int size = vsprintf(buffer, fmt, args); + +#ifdef ENABLE_DEBUGGER + if (acpi_in_debugger) { + kdb_printf("%s", buffer); + } else { + printk("%s", buffer); + } +#else printk("%s", buffer); +#endif + return size; } void * -acpi_os_allocate(u32 size) +acpi_os_allocate_rt(u32 size) { return kmalloc(size, GFP_KERNEL); } void * -acpi_os_callocate(u32 size) +acpi_os_callocate_rt(u32 size) { void *ptr = acpi_os_allocate(size); if (ptr) @@ -99,14 +146,19 @@ } void -acpi_os_free(void *ptr) +acpi_os_free_rt(void *ptr) { kfree(ptr); } ACPI_STATUS -acpi_os_map_memory(void *phys, u32 size, void **virt) +acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, u32 size, void **virt) { + if (phys > ULONG_MAX) { + printk(KERN_ERR "ACPI: Cannot map memory that high\n"); + return AE_ERROR; + } + if ((unsigned long) phys < virt_to_phys(high_memory)) { *virt = phys_to_virt((unsigned long) phys); return AE_OK; @@ -132,6 +184,101 @@ (*acpi_irq_handler)(acpi_irq_context); } + +#ifdef CONFIG_ACPI_KERNEL_CONFIG +struct irqaction acpiirqaction; +/* + * codes from request_irq and free_irq. + */ +ACPI_STATUS +acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) +{ + struct irqaction *act; + int retval; + + if (irq >= NR_IRQS) { + printk("ACPI: install SCI handler fail: invalid irq%d\n", irq); + return AE_ERROR; + } + + if (!handler) { + printk("ACPI: install SCI handler fail: invalid handler\n"); + return AE_ERROR; + } + + act = & acpiirqaction; + + acpi_irq_irq = irq; + acpi_irq_handler = handler; + acpi_irq_context = context; + + act->handler = acpi_irq; + act->flags = SA_INTERRUPT | SA_SHIRQ; + act->mask = 0; + act->name = "acpi"; + act->next = NULL; + act->dev_id = acpi_irq; + + retval = setup_irq(irq, act); + if (retval) { + printk("ACPI: install SCI handler fail: setup_irq\n"); + acpi_irq_handler = NULL; + return AE_ERROR; + } + printk("ACPI: install SCI %d handler pass\n", irq); + + return AE_OK; +} + +ACPI_STATUS +acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + if (!acpi_irq_handler) + return AE_OK; + + if (irq != acpi_irq_irq) return AE_ERROR; + + acpi_irq_handler = NULL; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != acpi_irq) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + desc->handler->shutdown(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + +#ifdef CONFIG_SMP + /* Wait to make sure it's not being used on another CPU */ + while (desc->status & IRQ_INPROGRESS) + barrier(); +#endif + return AE_OK; + } + printk("ACPI: Trying to free free IRQ%d\n",irq); + spin_unlock_irqrestore(&desc->lock,flags); + return AE_OK; + } + + return AE_OK; +} + +#else ACPI_STATUS acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) { @@ -158,6 +305,7 @@ } return AE_OK; } +#endif /* * Running in interpreter thread context, safe to sleep @@ -212,12 +360,48 @@ outl(val, port); } +UINT8 +acpi_os_mem_in8 (ACPI_PHYSICAL_ADDRESS phys_addr) +{ + return (*(u8*) phys_addr); +} + +UINT16 +acpi_os_mem_in16 (ACPI_PHYSICAL_ADDRESS phys_addr) +{ + return (*(u16*) phys_addr); +} + +UINT32 +acpi_os_mem_in32 (ACPI_PHYSICAL_ADDRESS phys_addr) +{ + return (*(u32*) phys_addr); +} + +void +acpi_os_mem_out8 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT8 value) +{ + *(u8*) phys_addr = value; +} + +void +acpi_os_mem_out16 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT16 value) +{ + *(u16*) phys_addr = value; +} + +void +acpi_os_mem_out32 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT32 value) +{ + *(u32*) phys_addr = value; +} + ACPI_STATUS -acpi_os_read_pci_cfg_byte( - u32 bus, - u32 func, - u32 addr, - u8 * val) +acpi_os_read_pci_cfg_byte_rt( + u32 bus, + u32 func, + u32 addr, + u8 * val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -227,11 +411,11 @@ } ACPI_STATUS -acpi_os_read_pci_cfg_word( - u32 bus, - u32 func, - u32 addr, - u16 * val) +acpi_os_read_pci_cfg_word_rt( + u32 bus, + u32 func, + u32 addr, + u16 * val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -241,11 +425,11 @@ } ACPI_STATUS -acpi_os_read_pci_cfg_dword( - u32 bus, - u32 func, - u32 addr, - u32 * val) +acpi_os_read_pci_cfg_dword_rt( + u32 bus, + u32 func, + u32 addr, + u32 * val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -255,11 +439,11 @@ } ACPI_STATUS -acpi_os_write_pci_cfg_byte( - u32 bus, - u32 func, - u32 addr, - u8 val) +acpi_os_write_pci_cfg_byte_rt( + u32 bus, + u32 func, + u32 addr, + u8 val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -269,11 +453,11 @@ } ACPI_STATUS -acpi_os_write_pci_cfg_word( - u32 bus, - u32 func, - u32 addr, - u16 val) +acpi_os_write_pci_cfg_word_rt( + u32 bus, + u32 func, + u32 addr, + u16 val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -283,11 +467,11 @@ } ACPI_STATUS -acpi_os_write_pci_cfg_dword( - u32 bus, - u32 func, - u32 addr, - u32 val) +acpi_os_write_pci_cfg_dword_rt( + u32 bus, + u32 func, + u32 addr, + u32 val) { int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); @@ -301,13 +485,17 @@ */ ACPI_STATUS -acpi_os_queue_for_execution( - u32 priority, - OSD_EXECUTION_CALLBACK callback, - void *context) +acpi_os_queue_for_execution_rt( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context) { +#ifndef CONFIG_ACPI_KERNEL_CONFIG_ONLY if (acpi_run(callback, context)) return AE_ERROR; +#else + (*callback)(context); +#endif return AE_OK; } @@ -318,7 +506,8 @@ ACPI_STATUS acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle) { - *handle = (ACPI_HANDLE) 0; + /* a hack to fake out sems until we implement them */ + *handle = (ACPI_HANDLE) handle; return AE_OK; } @@ -362,6 +551,19 @@ u32 acpi_os_get_line(NATIVE_CHAR *buffer) { + +#ifdef ENABLE_DEBUGGER + if (acpi_in_debugger) { + u32 chars; + + kdb_read(buffer, sizeof(line_buf)); + + /* remove the CR kdb includes */ + chars = strlen(buffer) - 1; + buffer[chars] = '\0'; + } +#endif + return 0; } diff -urN linux-2.4.0-test12/drivers/acpi/osconf.c linux-2.4.0-test12-lia/drivers/acpi/osconf.c --- linux-2.4.0-test12/drivers/acpi/osconf.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/osconf.c Fri Nov 17 17:42:44 2000 @@ -0,0 +1,333 @@ +/* + * osconf.c - ACPI OS-dependent functions for Kernel Boot/Configuration time + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acpi.h" +#include "osconf.h" + + +static void * __init acpi_os_allocate_bt(u32 size); +static void * __init acpi_os_callocate_bt(u32 size); +static void __init acpi_os_free_bt(void *ptr); + +static ACPI_STATUS __init +acpi_os_queue_for_execution_bt( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context + ); + +static ACPI_STATUS __init +acpi_os_read_pci_cfg_byte_bt( u32 segbus, u32 func, u32 addr, u8 * val); + +static ACPI_STATUS __init +acpi_os_read_pci_cfg_word_bt( u32 segbus, u32 func, u32 addr, u16 * val); + +static ACPI_STATUS __init +acpi_os_read_pci_cfg_dword_bt( u32 segbus, u32 func, u32 addr, u32 * val); + +static ACPI_STATUS __init +acpi_os_write_pci_cfg_byte_bt( u32 segbus, u32 func, u32 addr, u8 val); + +static ACPI_STATUS __init +acpi_os_write_pci_cfg_word_bt( u32 segbus, u32 func, u32 addr, u16 val); + +static ACPI_STATUS __init +acpi_os_write_pci_cfg_dword_bt( u32 segbus, u32 func, u32 addr, u32 val); + + +static struct acpi_osd *acpi_osd; +extern struct acpi_osd acpi_osd_rt; +static struct acpi_osd acpi_osd_bt __initdata = { + /* these are boottime osd entries that differ from runtime entries */ + acpi_os_allocate_bt, + acpi_os_callocate_bt, + acpi_os_free_bt, + acpi_os_queue_for_execution_bt, + acpi_os_read_pci_cfg_byte_bt, + acpi_os_read_pci_cfg_word_bt, + acpi_os_read_pci_cfg_dword_bt, + acpi_os_write_pci_cfg_byte_bt, + acpi_os_write_pci_cfg_word_bt, + acpi_os_write_pci_cfg_dword_bt +}; + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_BM_PROFILE +static void __init +acpi_cf_bm_statistics( void ); +#endif + +void __init +acpi_os_bind_osd(int acpi_phase) +{ + switch (acpi_phase) { + case ACPI_CF_PHASE_BOOTTIME: + acpi_osd = &acpi_osd_bt; + printk("Acpi cfg:bind to Boot time Acpi OSD\n"); + break; + case ACPI_CF_PHASE_RUNTIME: + default: + acpi_osd = &acpi_osd_rt; + printk("Acpi cfg:bind to Run time Acpi OSD\n"); +#ifdef CONFIG_ACPI_KERNEL_CONFIG_BM_PROFILE + acpi_cf_bm_statistics(); +#endif + break; + } +} + +void * +acpi_os_allocate(u32 size) +{ + return acpi_osd->allocate(size); +} + +void * +acpi_os_callocate(u32 size) +{ + return acpi_osd->callocate(size); +} + +void +acpi_os_free(void *ptr) +{ + acpi_osd->free(ptr); + return; +} + + +ACPI_STATUS +acpi_os_queue_for_execution( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context) +{ + return acpi_osd->queue_for_exec(priority, callback, context); +} + + +ACPI_STATUS +acpi_os_read_pci_cfg_byte( u32 segbus, u32 func, u32 addr, u8 * val) +{ + return acpi_osd->read_pci_cfg_byte(segbus, func, addr, val); +} + + +ACPI_STATUS +acpi_os_read_pci_cfg_word( u32 segbus, u32 func, u32 addr, u16 * val) +{ + return acpi_osd->read_pci_cfg_word(segbus, func, addr, val); +} + + +ACPI_STATUS +acpi_os_read_pci_cfg_dword( u32 segbus, u32 func, u32 addr, u32 * val) +{ + return acpi_osd->read_pci_cfg_dword(segbus, func, addr, val); +} + + +ACPI_STATUS +acpi_os_write_pci_cfg_byte( u32 segbus, u32 func, u32 addr, u8 val) +{ + return acpi_osd->write_pci_cfg_byte(segbus, func, addr, val); +} + + +ACPI_STATUS +acpi_os_write_pci_cfg_word( u32 segbus, u32 func, u32 addr, u16 val) +{ + return acpi_osd->write_pci_cfg_word(segbus, func, addr, val); +} + + +ACPI_STATUS +acpi_os_write_pci_cfg_dword( u32 segbus, u32 func, u32 addr, u32 val) +{ + return acpi_osd->write_pci_cfg_dword(segbus, func, addr, val); +} + + + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_BM_PROFILE +/* + * Let's profile bootmem usage to see how much we consume. J.I. + */ +static unsigned long bm_alloc_size __initdata = 0; +static unsigned long bm_alloc_size_max __initdata = 0; +static unsigned long bm_alloc_count_max __initdata = 0; +static unsigned long bm_free_count_max __initdata = 0; + +static void __init +acpi_cf_bm_checkin(void *ptr, u32 size) +{ + bm_alloc_count_max++; + bm_alloc_size += size; + if (bm_alloc_size > bm_alloc_size_max) + bm_alloc_size_max = bm_alloc_size; +}; + +static void __init +acpi_cf_bm_checkout(void *ptr, u32 size) +{ + bm_free_count_max++; + bm_alloc_size -= size; +}; + +static void __init +acpi_cf_bm_statistics( void ) +{ + printk("Acpi cfg:bm_alloc_size_max =%ld bytes\n", bm_alloc_size_max); + printk("Acpi cfg:bm_alloc_count_max=%ld\n", bm_alloc_count_max); + printk("Acpi cfg:bm_free_count_max =%ld\n", bm_free_count_max); +} +#endif + + +static void * __init +acpi_os_allocate_bt(u32 size) +{ + void *ptr; + + size += sizeof(unsigned long); + ptr = alloc_bootmem(size); + + if (ptr) { +#ifdef CONFIG_ACPI_KERNEL_CONFIG_BM_PROFILE + acpi_cf_bm_checkin(ptr, size); +#endif + *((unsigned long *)ptr) = (unsigned long)size; + ptr += sizeof(unsigned long); + } + + return ptr; +} + +static void * __init +acpi_os_callocate_bt(u32 size) +{ + void *ptr = acpi_os_allocate_bt(size); + + return ptr; +} + +static void __init +acpi_os_free_bt(void *ptr) +{ + unsigned long size; + + ptr -= sizeof(size); + size = *((unsigned long *)ptr); + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_BM_PROFILE + acpi_cf_bm_checkout(ptr, (unsigned long)size); +#endif + //if (size) + free_bootmem (__pa((unsigned long)ptr), (u32)size); +} + + +static ACPI_STATUS __init +acpi_os_queue_for_execution_bt( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context) +{ + /* + * run callback immediately + */ + (*callback)(context); + return AE_OK; +} + + +static ACPI_STATUS __init +acpi_os_read_pci_cfg_byte_bt( u32 segbus, u32 func, u32 addr, u8 * val) +{ + unsigned int devfn; + s64 status; + u64 lval; + + devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS((segbus & 0xffff), devfn, addr), 1, &lval); + *val = lval; + + return status; +} + + +static ACPI_STATUS __init +acpi_os_read_pci_cfg_word_bt( u32 segbus, u32 func, u32 addr, u16 * val) +{ + unsigned int devfn; + s64 status; + u64 lval; + + devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS((segbus & 0xffff), devfn, addr), 2, &lval); + *val = lval; + + return status; +} + + +static ACPI_STATUS __init +acpi_os_read_pci_cfg_dword_bt( u32 segbus, u32 func, u32 addr, u32 * val) +{ + unsigned int devfn; + s64 status; + u64 lval; + + devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + status = ia64_sal_pci_config_read(PCI_CONFIG_ADDRESS((segbus & 0xffff), devfn, addr), 4, &lval); + *val = lval; + + return status; +} + + +static ACPI_STATUS __init +acpi_os_write_pci_cfg_byte_bt( u32 segbus, u32 func, u32 addr, u8 val) +{ + unsigned int devfn; + + devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS((segbus & 0xffff), devfn, addr), 1, val); +} + + +static ACPI_STATUS __init +acpi_os_write_pci_cfg_word_bt( u32 segbus, u32 func, u32 addr, u16 val) +{ + unsigned int devfn; + + devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS((segbus & 0xffff), devfn, addr), 2, val); +} + + +static ACPI_STATUS __init +acpi_os_write_pci_cfg_dword_bt( u32 segbus, u32 func, u32 addr, u32 val) +{ + unsigned int devfn; + + devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + return ia64_sal_pci_config_write(PCI_CONFIG_ADDRESS((segbus & 0xffff), devfn, addr), 4, val); +} + + diff -urN linux-2.4.0-test12/drivers/acpi/osconf.h linux-2.4.0-test12-lia/drivers/acpi/osconf.h --- linux-2.4.0-test12/drivers/acpi/osconf.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/osconf.h Tue Oct 31 16:50:26 2000 @@ -0,0 +1,91 @@ +/* + * osconf.h - ACPI OS-dependent headers for Kernel Boot/Configuration time + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + */ + + +struct acpi_osd { + void * (*allocate)(u32 size); + void * (*callocate)(u32 size); + void (*free)(void *ptr); + ACPI_STATUS (*queue_for_exec)(u32 pri, OSD_EXECUTION_CALLBACK cb, void *context); + ACPI_STATUS (*read_pci_cfg_byte)(u32 bus, u32 func, u32 addr, u8 *val); + ACPI_STATUS (*read_pci_cfg_word)(u32 bus, u32 func, u32 addr, u16 *val); + ACPI_STATUS (*read_pci_cfg_dword)(u32 bus, u32 func, u32 addr, u32 *val); + ACPI_STATUS (*write_pci_cfg_byte)(u32 bus, u32 func, u32 addr, u8 val); + ACPI_STATUS (*write_pci_cfg_word)(u32 bus, u32 func, u32 addr, u16 val); + ACPI_STATUS (*write_pci_cfg_dword)(u32 bus, u32 func, u32 addr, u32 val); +}; + + +#define PCI_CONFIG_ADDRESS(bus, devfn, where) \ + (((u64) bus << 16) | ((u64) (devfn & 0xff) << 8) | (where & 0xff)) + +#define ACPI_CF_PHASE_BOOTTIME 0x00 +#define ACPI_CF_PHASE_RUNTIME 0x01 + + +/* acpi_osd functions */ +void * acpi_os_allocate(u32 size); +void * acpi_os_callocate(u32 size); +void acpi_os_free(void *ptr); + + +ACPI_STATUS +acpi_os_queue_for_execution( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context + ); + +ACPI_STATUS +acpi_os_read_pci_cfg_byte( u32 segbus, u32 func, u32 addr, u8 * val); + +ACPI_STATUS +acpi_os_read_pci_cfg_word( u32 segbus, u32 func, u32 addr, u16 * val); + +ACPI_STATUS +acpi_os_read_pci_cfg_dword( u32 segbus, u32 func, u32 addr, u32 * val); + +ACPI_STATUS +acpi_os_write_pci_cfg_byte( u32 segbus, u32 func, u32 addr, u8 val); + +ACPI_STATUS +acpi_os_write_pci_cfg_word( u32 segbus, u32 func, u32 addr, u16 val); + +ACPI_STATUS +acpi_os_write_pci_cfg_dword( u32 segbus, u32 func, u32 addr, u32 val); + + +/* acpi_osd_rt functions */ +extern void * acpi_os_allocate_rt(u32 size); +extern void * acpi_os_callocate_rt(u32 size); +extern void acpi_os_free_rt(void *ptr); + +extern ACPI_STATUS +acpi_os_queue_for_execution_rt( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context + ); + +extern ACPI_STATUS +acpi_os_read_pci_cfg_byte_rt( u32 segbus, u32 func, u32 addr, u8 * val); + +extern ACPI_STATUS +acpi_os_read_pci_cfg_word_rt( u32 segbus, u32 func, u32 addr, u16 * val); + +extern ACPI_STATUS +acpi_os_read_pci_cfg_dword_rt( u32 segbus, u32 func, u32 addr, u32 * val); + +extern ACPI_STATUS +acpi_os_write_pci_cfg_byte_rt( u32 segbus, u32 func, u32 addr, u8 val); + +extern ACPI_STATUS +acpi_os_write_pci_cfg_word_rt( u32 segbus, u32 func, u32 addr, u16 val); + +extern ACPI_STATUS +acpi_os_write_pci_cfg_dword_rt( u32 segbus, u32 func, u32 addr, u32 val); + diff -urN linux-2.4.0-test12/drivers/acpi/parser/Makefile linux-2.4.0-test12-lia/drivers/acpi/parser/Makefile --- linux-2.4.0-test12/drivers/acpi/parser/Makefile Fri Sep 15 18:21:44 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/parser/psargs.c linux-2.4.0-test12-lia/drivers/acpi/parser/psargs.c --- linux-2.4.0-test12/drivers/acpi/parser/psargs.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psargs.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 35 $ + * $Revision: 40 $ * *****************************************************************************/ @@ -33,20 +33,6 @@ MODULE_NAME ("psargs") -u32 -acpi_ps_pkg_length_encoding_size ( - u32 first_byte) -{ - - /* - * Bits 6-7 contain the number of bytes - * in the encoded package length (-1) - */ - - return ((first_byte >> 6) + 1); -} - - /******************************************************************************* * * FUNCTION: Acpi_ps_get_next_package_length @@ -61,55 +47,6 @@ ******************************************************************************/ u32 -xxx_acpi_ps_get_next_package_length ( - ACPI_PARSE_STATE *parser_state) -{ - u32 encoding_length; - u32 package_length = 0; - u8 *aml_ptr = parser_state->aml; - - - encoding_length = acpi_ps_pkg_length_encoding_size ((u32) GET8 (aml_ptr)); - - - switch (encoding_length) - { - case 1: /* 1-byte encoding (bits 0-5) */ - - package_length = ((u32) GET8 (aml_ptr) & 0x3f); - break; - - - case 2: /* 2-byte encoding (next byte + bits 0-3) */ - - package_length = ((((u32) GET8 (aml_ptr + 1)) << 4) | - (((u32) GET8 (aml_ptr)) & 0x0f)); - break; - - - case 3: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - - package_length = ((((u32) GET8 (aml_ptr + 2)) << 12) | - (((u32) GET8 (aml_ptr + 1)) << 4) | - (((u32) GET8 (aml_ptr)) & 0x0f)); - break; - - - case 4: /* 4-byte encoding (next 3 bytes + bits 0-3) */ - - package_length = ((((u32) GET8 (aml_ptr + 3)) << 20) | - (((u32) GET8 (aml_ptr + 2)) << 12) | - (((u32) GET8 (aml_ptr + 1)) << 4) | - (((u32) GET8 (aml_ptr)) & 0x0f)); - break; - } - - parser_state->aml += encoding_length; - - return (package_length); -} - -u32 acpi_ps_get_next_package_length ( ACPI_PARSE_STATE *parser_state) { @@ -125,32 +62,33 @@ { case 0: /* 1-byte encoding (bits 0-5) */ - length = (encoded_length & 0x3f); + length = (encoded_length & 0x3F); break; case 1: /* 2-byte encoding (next byte + bits 0-3) */ - length = (GET8 (parser_state->aml) << 4) | (encoded_length & 0xf); + length = ((GET8 (parser_state->aml) << 04) | + (encoded_length & 0x0F)); parser_state->aml++; break; case 2: /* 3-byte encoding (next 2 bytes + bits 0-3) */ - length = ( (GET8 (parser_state->aml + 1) << 12) - | (GET8 (parser_state->aml) << 4) - | (encoded_length & 0xf)); + length = ((GET8 (parser_state->aml + 1) << 12) | + (GET8 (parser_state->aml) << 04) | + (encoded_length & 0x0F)); parser_state->aml += 2; break; case 3: /* 4-byte encoding (next 3 bytes + bits 0-3) */ - length = ( (GET8 (parser_state->aml + 2) << 20) - | (GET8 (parser_state->aml + 1) << 12) - | (GET8 (parser_state->aml) << 4) - | (encoded_length & 0xf)); + length = ((GET8 (parser_state->aml + 2) << 20) | + (GET8 (parser_state->aml + 1) << 12) | + (GET8 (parser_state->aml) << 04) | + (encoded_length & 0x0F)); parser_state->aml += 3; break; } @@ -441,6 +379,10 @@ name_op->node = method_node; acpi_ps_append_arg (arg, name_op); + + if (!(ACPI_OPERAND_OBJECT *) method_node->object) { + return; + } *arg_count = ((ACPI_OPERAND_OBJECT *) method_node->object)->method.param_count; } diff -urN linux-2.4.0-test12/drivers/acpi/parser/psfind.c linux-2.4.0-test12-lia/drivers/acpi/parser/psfind.c --- linux-2.4.0-test12/drivers/acpi/parser/psfind.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psfind.c Wed Dec 31 16:00:00 1969 @@ -1,319 +0,0 @@ - -/****************************************************************************** - * - * Module Name: psfind - Parse tree search routine - * $Revision: 16 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "acparser.h" -#include "amlcode.h" - -#define _COMPONENT PARSER - MODULE_NAME ("psfind") - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_get_parent - * - * PARAMETERS: Op - Get the parent of this Op - * - * RETURN: The Parent op. - * - * DESCRIPTION: Get op's parent - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT* -acpi_ps_get_parent ( - ACPI_PARSE_OBJECT *op) -{ - ACPI_PARSE_OBJECT *parent = op; - - - /* Traverse the tree upward (to root if necessary) */ - - while (parent) { - switch (parent->opcode) - { - case AML_SCOPE_OP: - case AML_PACKAGE_OP: - case AML_METHOD_OP: - case AML_DEVICE_OP: - case AML_POWER_RES_OP: - case AML_THERMAL_ZONE_OP: - - return (parent->parent); - } - - parent = parent->parent; - } - - return (parent); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_find_name - * - * PARAMETERS: Scope - Scope to search - * Name - ACPI name to search for - * Opcode - Opcode to search for - * - * RETURN: Op containing the name - * - * DESCRIPTION: Find name segment from a list of acpi_ops. Searches a single - * scope, no more. - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT * -acpi_ps_find_name ( - ACPI_PARSE_OBJECT *scope, - u32 name, - u32 opcode) -{ - ACPI_PARSE_OBJECT *op; - ACPI_PARSE_OBJECT *field; - - - /* search scope level for matching name segment */ - - op = acpi_ps_get_child (scope); - - while (op) { - - if (acpi_ps_is_field_op (op->opcode)) { - /* Field, search named fields */ - - field = acpi_ps_get_child (op); - while (field) { - if (acpi_ps_is_named_op (field->opcode) && - acpi_ps_get_name (field) == name && - (!opcode || field->opcode == opcode)) - { - return (field); - } - - field = field->next; - } - } - - else if (acpi_ps_is_create_field_op (op->opcode)) { - if (op->opcode == AML_CREATE_FIELD_OP) { - field = acpi_ps_get_arg (op, 3); - } - - else { - /* Create_xXXField, check name */ - - field = acpi_ps_get_arg (op, 2); - } - - if ((field) && - (field->value.string) && - (!STRNCMP (field->value.string, (char *) &name, ACPI_NAME_SIZE))) - { - return (op); - } - } - - else if ((acpi_ps_is_named_op (op->opcode)) && - (acpi_ps_get_name (op) == name) && - (!opcode || op->opcode == opcode)) - { - break; - } - - op = op->next; - } - - return (op); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_find - * - * PARAMETERS: Scope - Where to begin the search - * Path - ACPI Path to the named object - * Opcode - Opcode associated with the object - * Create - if TRUE, create the object if not found. - * - * RETURN: Op if found, NULL otherwise. - * - * DESCRIPTION: Find object within scope - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT* -acpi_ps_find ( - ACPI_PARSE_OBJECT *scope, - NATIVE_CHAR *path, - u16 opcode, - u32 create) -{ - u32 seg_count; - u32 name; - u32 name_op; - ACPI_PARSE_OBJECT *op = NULL; - u8 unprefixed = TRUE; - - - if (!scope || !path) { - return (NULL); - } - - - acpi_gbl_ps_find_count++; - - - /* Handle all prefixes in the name path */ - - while (acpi_ps_is_prefix_char (GET8 (path))) { - switch (GET8 (path)) - { - - case '\\': - - /* Could just use a global for "root scope" here */ - - while (scope->parent) { - scope = scope->parent; - } - - /* get first object within the scope */ - /* TBD: [Investigate] OR - set next in root scope to point to the same value as arg */ - - /* Scope = Scope->Value.Arg; */ - - break; - - - case '^': - - /* Go up to the next valid scoping Op (method, scope, etc.) */ - - if (acpi_ps_get_parent (scope)) { - scope = acpi_ps_get_parent (scope); - } - - break; - } - - unprefixed = FALSE; - path++; - } - - /* get name segment count */ - - switch (GET8 (path)) - { - case '\0': - seg_count = 0; - - /* Null name case */ - - if (unprefixed) { - op = NULL; - } - else { - op = scope; - } - - - return (op); - break; - - case AML_DUAL_NAME_PREFIX: - seg_count = 2; - path++; - break; - - case AML_MULTI_NAME_PREFIX_OP: - seg_count = GET8 (path + 1); - path += 2; - break; - - default: - seg_count = 1; - break; - } - - /* match each name segment */ - - while (scope && seg_count) { - MOVE_UNALIGNED32_TO_32 (&name, path); - path += 4; - seg_count --; - - if (seg_count) { - name_op = 0; - } - else { - name_op = opcode; - } - - op = acpi_ps_find_name (scope, name, name_op); - - if (!op) { - if (create) { - /* Create a new Scope level */ - - if (seg_count) { - op = acpi_ps_alloc_op (AML_SCOPE_OP); - } - else { - op = acpi_ps_alloc_op (opcode); - } - - if (op) { - acpi_ps_set_name (op, name); - acpi_ps_append_arg (scope, op); - - } - } - - else if (unprefixed) { - /* Search higher scopes for unprefixed name */ - - while (!op && scope->parent) { - scope = scope->parent; - op = acpi_ps_find_name (scope, name, opcode); - - } - } - - } - - unprefixed = FALSE; - scope = op; - } - - return (op); -} - - diff -urN linux-2.4.0-test12/drivers/acpi/parser/psopcode.c linux-2.4.0-test12-lia/drivers/acpi/parser/psopcode.c --- linux-2.4.0-test12/drivers/acpi/parser/psopcode.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psopcode.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psopcode - Parser opcode information table - * $Revision: 20 $ + * $Revision: 24 $ * *****************************************************************************/ @@ -33,9 +33,6 @@ MODULE_NAME ("psopcode") -u8 acpi_gbl_aml_short_op_info_index[]; -u8 acpi_gbl_aml_long_op_info_index[]; - #define _UNK 0x6B /* * Reserved ASCII characters. Do not use any of these for @@ -55,112 +52,6 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_get_opcode_info - * - * PARAMETERS: Opcode - The AML opcode - * - * RETURN: A pointer to the info about the opcode. NULL if the opcode was - * not found in the table. - * - * DESCRIPTION: Find AML opcode description based on the opcode. - * NOTE: This procedure must ALWAYS return a valid pointer! - * - ******************************************************************************/ - -ACPI_OPCODE_INFO * -acpi_ps_get_opcode_info ( - u16 opcode) -{ - ACPI_OPCODE_INFO *op_info; - u8 upper_opcode; - u8 lower_opcode; - - - /* Split the 16-bit opcode into separate bytes */ - - upper_opcode = (u8) (opcode >> 8); - lower_opcode = (u8) opcode; - - /* Default is "unknown opcode" */ - - op_info = &acpi_gbl_aml_op_info [_UNK]; - - - /* - * Detect normal 8-bit opcode or extended 16-bit opcode - */ - - switch (upper_opcode) - { - case 0: - - /* Simple (8-bit) opcode: 0-255, can't index beyond table */ - - op_info = &acpi_gbl_aml_op_info [acpi_gbl_aml_short_op_info_index [lower_opcode]]; - break; - - - case AML_EXTOP: - - /* Extended (16-bit, prefix+opcode) opcode */ - - if (lower_opcode <= MAX_EXTENDED_OPCODE) { - op_info = &acpi_gbl_aml_op_info [acpi_gbl_aml_long_op_info_index [lower_opcode]]; - } - break; - - - case AML_LNOT_OP: - - /* This case is for the bogus opcodes LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL */ - /* TBD: [Investigate] remove this case? */ - - break; - - - default: - - break; - } - - - /* Get the Op info pointer for this opcode */ - - return (op_info); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_get_opcode_name - * - * PARAMETERS: Opcode - The AML opcode - * - * RETURN: A pointer to the name of the opcode (ASCII String) - * Note: Never returns NULL. - * - * DESCRIPTION: Translate an opcode into a human-readable string - * - ******************************************************************************/ - -NATIVE_CHAR * -acpi_ps_get_opcode_name ( - u16 opcode) -{ - ACPI_OPCODE_INFO *op; - - - op = acpi_ps_get_opcode_info (opcode); - - /* Always guaranteed to return a valid pointer */ - - DEBUG_ONLY_MEMBERS (return op->name); - return ("AE_NOT_CONFIGURED"); -} - - -/******************************************************************************* - * * NAME: Acpi_gbl_Aml_op_info * * DESCRIPTION: Opcode table. Each entry contains @@ -387,7 +278,7 @@ #define ARGI_REVISION_OP ARG_NONE #define ARGI_DEBUG_OP ARG_NONE #define ARGI_FATAL_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_REGION_OP ARGI_INVALID_OPCODE +#define ARGI_REGION_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) #define ARGI_DEF_FIELD_OP ARGI_INVALID_OPCODE #define ARGI_DEVICE_OP ARGI_INVALID_OPCODE #define ARGI_PROCESSOR_OP ARGI_INVALID_OPCODE @@ -412,7 +303,7 @@ */ -ACPI_OPCODE_INFO acpi_gbl_aml_op_info[] = +static ACPI_OPCODE_INFO aml_op_info[] = { /* Index Opcode Type Class Has Arguments? Name Parser Args Interpreter Args */ @@ -539,7 +430,7 @@ * index into the table above */ -u8 acpi_gbl_aml_short_op_info_index[256] = +static u8 aml_short_op_info_index[256] = { /* 0 1 2 3 4 5 6 7 */ /* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK, @@ -577,7 +468,7 @@ }; -u8 acpi_gbl_aml_long_op_info_index[NUM_EXTENDED_OPCODE] = +static u8 aml_long_op_info_index[NUM_EXTENDED_OPCODE] = { /* 0 1 2 3 4 5 6 7 */ /* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK, @@ -602,5 +493,110 @@ /* 0 1 2 3 4 5 6 7 */ /* 0x00 */ + + +/******************************************************************************* + * + * FUNCTION: Acpi_ps_get_opcode_info + * + * PARAMETERS: Opcode - The AML opcode + * + * RETURN: A pointer to the info about the opcode. NULL if the opcode was + * not found in the table. + * + * DESCRIPTION: Find AML opcode description based on the opcode. + * NOTE: This procedure must ALWAYS return a valid pointer! + * + ******************************************************************************/ + +ACPI_OPCODE_INFO * +acpi_ps_get_opcode_info ( + u16 opcode) +{ + ACPI_OPCODE_INFO *op_info; + u8 upper_opcode; + u8 lower_opcode; + + + /* Split the 16-bit opcode into separate bytes */ + + upper_opcode = (u8) (opcode >> 8); + lower_opcode = (u8) opcode; + + /* Default is "unknown opcode" */ + + op_info = &aml_op_info [_UNK]; + + + /* + * Detect normal 8-bit opcode or extended 16-bit opcode + */ + + switch (upper_opcode) + { + case 0: + + /* Simple (8-bit) opcode: 0-255, can't index beyond table */ + + op_info = &aml_op_info [aml_short_op_info_index [lower_opcode]]; + break; + + + case AML_EXTOP: + + /* Extended (16-bit, prefix+opcode) opcode */ + + if (lower_opcode <= MAX_EXTENDED_OPCODE) { + op_info = &aml_op_info [aml_long_op_info_index [lower_opcode]]; + } + break; + + + case AML_LNOT_OP: + + /* This case is for the bogus opcodes LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL */ + /* TBD: [Investigate] remove this case? */ + + break; + + + default: + + break; + } + + + /* Get the Op info pointer for this opcode */ + + return (op_info); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_ps_get_opcode_name + * + * PARAMETERS: Opcode - The AML opcode + * + * RETURN: A pointer to the name of the opcode (ASCII String) + * Note: Never returns NULL. + * + * DESCRIPTION: Translate an opcode into a human-readable string + * + ******************************************************************************/ + +NATIVE_CHAR * +acpi_ps_get_opcode_name ( + u16 opcode) +{ + ACPI_OPCODE_INFO *op; + + + op = acpi_ps_get_opcode_info (opcode); + + /* Always guaranteed to return a valid pointer */ + + return ("AE_NOT_CONFIGURED"); +} diff -urN linux-2.4.0-test12/drivers/acpi/parser/psparse.c linux-2.4.0-test12-lia/drivers/acpi/parser/psparse.c --- linux-2.4.0-test12/drivers/acpi/parser/psparse.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psparse.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 51 $ + * $Revision: 65 $ * *****************************************************************************/ @@ -30,7 +30,7 @@ * generated parser to tightly constrain stack and dynamic memory * usage. At the same time, parsing is kept flexible and the code * fairly compact by parsing based on a list of AML opcode - * templates in Acpi_gbl_Aml_op_info[] + * templates in Aml_op_info[] */ #include "acpi.h" @@ -50,95 +50,6 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_delete_completed_op - * - * PARAMETERS: State - Walk state - * Op - Completed op - * - * RETURN: AE_OK - * - * DESCRIPTION: Callback function for Acpi_ps_get_next_walk_op(). Used during - * Acpi_ps_delete_parse tree to delete Op objects when all sub-objects - * have been visited (and deleted.) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_ps_delete_completed_op ( - ACPI_WALK_STATE *state, - ACPI_PARSE_OBJECT *op) -{ - - acpi_ps_free_op (op); - return (AE_OK); -} - - -#ifndef PARSER_ONLY -/******************************************************************************* - * - * FUNCTION: Acpi_ps_delete_parse_tree - * - * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete - * - * RETURN: None - * - * DESCRIPTION: Delete a portion of or an entire parse tree. - * - ******************************************************************************/ - -void -acpi_ps_delete_parse_tree ( - ACPI_PARSE_OBJECT *subtree_root) -{ - ACPI_WALK_STATE *walk_state; - ACPI_WALK_LIST walk_list; - - - if (!subtree_root) { - return; - } - - /* Create and initialize a new walk list */ - - walk_list.walk_state = NULL; - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list); - if (!walk_state) { - return; - } - - walk_state->parser_state = NULL; - walk_state->parse_flags = 0; - walk_state->descending_callback = NULL; - walk_state->ascending_callback = NULL; - - - walk_state->origin = subtree_root; - walk_state->next_op = subtree_root; - - - /* Head downward in the tree */ - - walk_state->next_op_info = NEXT_OP_DOWNWARD; - - /* Visit all nodes in the subtree */ - - while (walk_state->next_op) { - acpi_ps_get_next_walk_op (walk_state, walk_state->next_op, - acpi_ps_delete_completed_op); - } - - /* We are done with this walk */ - - acpi_ds_delete_walk_state (walk_state); - - return; -} -#endif - - -/******************************************************************************* - * * FUNCTION: Acpi_ps_peek_opcode * * PARAMETERS: None @@ -149,7 +60,7 @@ * ******************************************************************************/ -u32 +static u32 acpi_ps_get_opcode_size ( u32 opcode) { @@ -323,7 +234,7 @@ * ******************************************************************************/ -u8 +static u8 acpi_ps_complete_this_op ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op) @@ -443,8 +354,7 @@ * ******************************************************************************/ - -ACPI_STATUS +static ACPI_STATUS acpi_ps_next_parse_state ( ACPI_WALK_STATE *walk_state, ACPI_PARSE_OBJECT *op, @@ -452,6 +362,8 @@ { ACPI_PARSE_STATE *parser_state = walk_state->parser_state; ACPI_STATUS status = AE_CTRL_PENDING; + u8 *start; + u32 package_length; switch (callback_status) @@ -490,10 +402,12 @@ * Predicate of an IF was true, and we are at the matching ELSE. * Just close out this package * - * Parser_state->Aml is modified by the package length procedure + * Note: Parser_state->Aml is modified by the package length procedure + * TBD: [Investigate] perhaps it shouldn't, too much trouble */ - parser_state->aml = (parser_state->aml + - acpi_ps_get_next_package_length (parser_state)) -1; + start = parser_state->aml; + package_length = acpi_ps_get_next_package_length (parser_state); + parser_state->aml = start + package_length; break; @@ -528,7 +442,7 @@ /* Will return value (if any) be used by the caller? */ - walk_state->return_used = acpi_ds_is_result_used (op); + walk_state->return_used = acpi_ds_is_result_used (op, walk_state); break; @@ -577,15 +491,48 @@ parser_state = walk_state->parser_state; - if (walk_state->prev_op) { - op = walk_state->prev_op; - arg_types = walk_state->prev_arg_types; +#ifndef PARSER_ONLY + if (walk_state->walk_type & WALK_METHOD_RESTART) { + /* We are restarting a preempted control method */ + + if (acpi_ps_has_completed_scope (parser_state)) { + /* + * We must check if a predicate to an IF or WHILE statement + * was just completed + */ + if ((parser_state->scope->parse_scope.op) && + ((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) || + (parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) && + (walk_state->control_state) && + (walk_state->control_state->common.state == + CONTROL_PREDICATE_EXECUTING)) + { + + /* + * A predicate was just completed, get the value of the + * predicate and branch based on that value + */ + + status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE); + status = acpi_ps_next_parse_state (walk_state, op, status); + } + + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); + } + + else if (walk_state->prev_op) { + /* We were in the middle of an op */ + + op = walk_state->prev_op; + arg_types = walk_state->prev_arg_types; + } } +#endif /* * Iterative parsing loop, while there is more aml to process: */ - while (parser_state->aml < parser_state->aml_end) { + while ((parser_state->aml < parser_state->aml_end) || (op)) { if (!op) { /* Get the next opcode from the AML stream */ @@ -625,7 +572,9 @@ /* The opcode is unrecognized. Just skip unknown opcodes */ - parser_state->aml += acpi_ps_get_opcode_size (opcode); + /* Assume one-byte bad opcode */ + + parser_state->aml++; continue; } @@ -693,9 +642,8 @@ } } - else { - + else { /* Not a named opcode, just allocate Op and append to parent */ op = acpi_ps_alloc_op (opcode); @@ -703,6 +651,25 @@ return (AE_NO_MEMORY); } + + if ((op->opcode == AML_CREATE_FIELD_OP) || + (op->opcode == AML_BIT_FIELD_OP) || + (op->opcode == AML_BYTE_FIELD_OP) || + (op->opcode == AML_WORD_FIELD_OP) || + (op->opcode == AML_DWORD_FIELD_OP)) + { + /* + * Backup to beginning of Create_xXXfield declaration (1 for + * Opcode) + * + * Body_length is unknown until we parse the body + */ + deferred_op = (ACPI_PARSE2_OBJECT *) op; + + deferred_op->data = parser_state->aml -1; + deferred_op->length = 0; + } + acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op); if ((walk_state->descending_callback != NULL)) { @@ -728,7 +695,11 @@ } + /* Start Arg_count at zero because we don't know if there are any args yet */ + arg_count = 0; + + if (arg_types) /* Are there any arguments that must be processed? */ { /* get arguments */ @@ -761,12 +732,11 @@ arg = acpi_ps_get_next_arg (parser_state, GET_CURRENT_ARG_TYPE (arg_types), &arg_count); - if (arg) { arg->aml_offset = aml_offset; + acpi_ps_append_arg (op, arg); } - acpi_ps_append_arg (op, arg); INCREMENT_ARG_LIST (arg_types); } @@ -800,6 +770,10 @@ } } + + /* + * Zero Arg_count means that all arguments for this op have been processed + */ if (!arg_count) { /* completed Op, prepare for next */ @@ -821,11 +795,29 @@ */ deferred_op->length = parser_state->aml - - deferred_op->data; + deferred_op->data; } } } + if ((op->opcode == AML_CREATE_FIELD_OP) || + (op->opcode == AML_BIT_FIELD_OP) || + (op->opcode == AML_BYTE_FIELD_OP) || + (op->opcode == AML_WORD_FIELD_OP) || + (op->opcode == AML_DWORD_FIELD_OP)) + { + /* + * Backup to beginning of Create_xXXfield declaration (1 for + * Opcode) + * + * Body_length is unknown until we parse the body + * -4 for the name (last) -- TBD: namestring: may be longer + * than 4? + */ + deferred_op = (ACPI_PARSE2_OBJECT *) op; + + deferred_op->length = parser_state->aml - deferred_op->data; + } /* This op complete, notify the dispatcher */ @@ -841,6 +833,9 @@ close_this_op: + /* + * Finished one argument of the containing scope + */ parser_state->scope->parse_scope.arg_count--; /* Close this Op (may result in parse subtree deletion) */ @@ -850,8 +845,18 @@ } - if (status == AE_CTRL_END) { - acpi_ps_pop_scope (parser_state, &op, &arg_types); + if (status == AE_CTRL_TRANSFER) { + /* + * We are about to transfer to a called method. + */ + walk_state->prev_op = op; + walk_state->prev_arg_types = arg_types; + return (status); + } + + else if (status == AE_CTRL_END) { + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); + status = walk_state->ascending_callback (walk_state, op); status = acpi_ps_next_parse_state (walk_state, op, status); acpi_ps_complete_this_op (walk_state, op); @@ -859,9 +864,25 @@ status = AE_OK; } + else if (status == AE_CTRL_TERMINATE) { + status = AE_OK; + + /* Clean up */ + do + { + if (op) { + acpi_ps_complete_this_op (walk_state, op); + } + + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); + } while (op); + + return (status); + } + else if (ACPI_FAILURE (status)) { if (op == NULL) { - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } walk_state->prev_op = op; walk_state->prev_arg_types = arg_types; @@ -870,19 +891,6 @@ * TEMP: */ - if (status == AE_CTRL_TERMINATE) { - status = AE_OK; - - /* Clean up */ - do - { - if (op) { - acpi_ps_complete_this_op (walk_state, op); - } - - acpi_ps_pop_scope (parser_state, &op, &arg_types); - } while (op); - } return (status); } @@ -890,7 +898,7 @@ /* This scope complete? */ if (acpi_ps_has_completed_scope (parser_state)) { - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } else { @@ -899,6 +907,9 @@ } + + /* Arg_count is non-zero */ + else { /* complex argument, push Op and prepare for argument */ @@ -937,7 +948,7 @@ acpi_ps_complete_this_op (walk_state, op); } - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } while (op); @@ -953,7 +964,7 @@ acpi_ps_complete_this_op (walk_state, op); } - acpi_ps_pop_scope (parser_state, &op, &arg_types); + acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count); } while (op); @@ -1145,6 +1156,7 @@ */ acpi_ds_restart_control_method (walk_state, return_desc); + walk_state->walk_type |= WALK_METHOD_RESTART; } /* diff -urN linux-2.4.0-test12/drivers/acpi/parser/psscope.c linux-2.4.0-test12-lia/drivers/acpi/parser/psscope.c --- linux-2.4.0-test12/drivers/acpi/parser/psscope.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psscope.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psscope - Parser scope stack management routines - * $Revision: 18 $ + * $Revision: 21 $ * *****************************************************************************/ @@ -118,7 +118,7 @@ * * PARAMETERS: Parser_state - Current parser state object * Op - Current op to be pushed - * Next_arg - Next op argument (to be pushed) + * Remaining_args - List of args remaining * Arg_count - Fixed or variable number of args * * RETURN: Status @@ -175,8 +175,9 @@ * * PARAMETERS: Parser_state - Current parser state object * Op - Where the popped op is returned - * Next_arg - Where the popped "next argument" is + * Arg_list - Where the popped "next argument" is * returned + * Arg_count - Count of objects in Arg_list * * RETURN: Status * @@ -188,7 +189,8 @@ acpi_ps_pop_scope ( ACPI_PARSE_STATE *parser_state, ACPI_PARSE_OBJECT **op, - u32 *arg_list) + u32 *arg_list, + u32 *arg_count) { ACPI_GENERIC_STATE *scope = parser_state->scope; @@ -204,6 +206,7 @@ *op = scope->parse_scope.op; *arg_list = scope->parse_scope.arg_list; + *arg_count = scope->parse_scope.arg_count; parser_state->pkg_end = scope->parse_scope.pkg_end; /* All done with this scope state structure */ @@ -216,6 +219,7 @@ *op = NULL; *arg_list = 0; + *arg_count = 0; } diff -urN linux-2.4.0-test12/drivers/acpi/parser/pstree.c linux-2.4.0-test12-lia/drivers/acpi/parser/pstree.c --- linux-2.4.0-test12/drivers/acpi/parser/pstree.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/pstree.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: pstree - Parser op tree manipulation/traversal/search - * $Revision: 23 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -284,117 +284,6 @@ } return (next); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_fetch_prefix - * - * PARAMETERS: Scope - Op to fetch prefix for - * Path - A namestring containing the prefix - * io - Direction flag - * - * RETURN: Op referenced by the prefix - * - * DESCRIPTION: Fetch and handle path prefix ('\\' or '^') - * - ******************************************************************************/ - -ACPI_PARSE_OBJECT * -acpi_ps_fetch_prefix ( - ACPI_PARSE_OBJECT *scope, - NATIVE_CHAR **path, - u32 io) -{ - u32 prefix = io ? GET8 (*path):**path; - - - switch (prefix) - { - case '\\': - case '/': - - /* go to the root */ - - *path += 1; - while (scope->parent) { - scope = scope->parent; - } - break; - - - case '^': - - /* go up one level */ - - *path += 1; - scope = scope->parent; - break; - } - - if (scope && !scope->parent) { - /* searching from the root, start with its children */ - - scope = acpi_ps_get_child (scope); - } - - return (scope); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_ps_fetch_name - * - * PARAMETERS: Path - A string containing the name segment - * io - Direction flag - * - * RETURN: The 4-s8 ASCII ACPI Name as a u32 - * - * DESCRIPTION: Fetch ACPI name segment (dot-delimited) - * - ******************************************************************************/ - -u32 -acpi_ps_fetch_name ( - NATIVE_CHAR **path, - u32 io) -{ - u32 name = 0; - NATIVE_CHAR *nm; - u32 i; - NATIVE_CHAR ch; - - - if (io) { - /* Get the name from the path pointer */ - - MOVE_UNALIGNED32_TO_32 (&name, *path); - *path += 4; - } - - else { - if (**path == '.') { - *path += 1; - } - - nm = (NATIVE_CHAR *) &name; - for (i = 0; i < 4; i++) { - ch = **path; - if (ch && ch != '.') { - *nm = ch; - *path += 1; - } - - else { - *nm = '_'; - } - nm++; - } - } - - return (name); } diff -urN linux-2.4.0-test12/drivers/acpi/parser/psutils.c linux-2.4.0-test12-lia/drivers/acpi/parser/psutils.c --- linux-2.4.0-test12/drivers/acpi/parser/psutils.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psutils.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 29 $ + * $Revision: 30 $ * *****************************************************************************/ @@ -460,7 +460,12 @@ u16 opcode) { return ((u8) - (opcode == AML_METHOD_OP || + (opcode == AML_METHOD_OP || + opcode == AML_CREATE_FIELD_OP || + opcode == AML_BIT_FIELD_OP || + opcode == AML_BYTE_FIELD_OP || + opcode == AML_WORD_FIELD_OP || + opcode == AML_DWORD_FIELD_OP || opcode == AML_REGION_OP)); } diff -urN linux-2.4.0-test12/drivers/acpi/parser/pswalk.c linux-2.4.0-test12-lia/drivers/acpi/parser/pswalk.c --- linux-2.4.0-test12/drivers/acpi/parser/pswalk.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/pswalk.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: pswalk - Parser routines to walk parsed op tree(s) - * $Revision: 45 $ + * $Revision: 50 $ * *****************************************************************************/ @@ -42,8 +42,6 @@ * PARAMETERS: Walk_state - Current state of the walk * Op - Current Op to be walked * Ascending_callback - Procedure called when Op is complete - * Prev_op - Where the previous Op is stored - * Next_op - Where the next Op in the walk is stored * * RETURN: Status * @@ -90,112 +88,40 @@ status = ascending_callback (walk_state, op); - switch (status) - { - case AE_CTRL_TERMINATE: - - /* - * A control method was terminated via a RETURN statement. - * The walk of this method is complete. - */ - walk_state->prev_op = walk_state->origin; - walk_state->next_op = NULL; - - return (AE_OK); - break; - - - case AE_CTRL_FALSE: - - /* - * Either an IF/WHILE Predicate was false or we encountered a BREAK - * opcode. In both cases, we do not execute the rest of the - * package; We simply close out the parent (finishing the walk of - * this branch of the tree) and continue execution at the parent - * level. - */ - - next = parent->next; - status = AE_OK; - - /* - * If there is a sibling to the parent, we must close out the - * parent now, because we are going to continue to go downward (to - * the sibling) in the parse tree. - */ - if (next) { - status = ascending_callback (walk_state, parent); - - /* The parent sibling will be next */ - - walk_state->prev_op = op; - walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; - - /* Continue downward */ - - return (AE_OK); - } - - /* - * Drop into the loop below because we are moving upwards in - * the tree - */ - - break; - - - default: - /* - * If we are back to the starting point, the walk is complete. - */ - if (op == walk_state->origin) { - /* Reached the point of origin, the walk is complete */ - - walk_state->prev_op = op; - walk_state->next_op = NULL; - - return (status); - } - - /* - * Check for a sibling to the current op. A sibling means - * we are still going "downward" in the tree. - */ + /* + * If we are back to the starting point, the walk is complete. + */ + if (op == walk_state->origin) { + /* Reached the point of origin, the walk is complete */ - if (next) { - /* There is a sibling, it will be next */ + walk_state->prev_op = op; + walk_state->next_op = NULL; - walk_state->prev_op = op; - walk_state->next_op = next; - walk_state->next_op_info = NEXT_OP_DOWNWARD; + return (status); + } - /* Continue downward */ + /* + * Check for a sibling to the current op. A sibling means + * we are still going "downward" in the tree. + */ - return (status); - } + if (next) { + /* There is a sibling, it will be next */ - /* - * No sibling, but check status. - * Abort on error from callback routine - */ - if (ACPI_FAILURE (status)) { - /* Next op will be the parent */ + walk_state->prev_op = op; + walk_state->next_op = next; + walk_state->next_op_info = NEXT_OP_DOWNWARD; - walk_state->prev_op = op; - walk_state->next_op = parent; - walk_state->next_op_info = NEXT_OP_UPWARD; + /* Continue downward */ - return (status); - } + return (status); + } - /* - * Drop into the loop below because we are moving upwards in - * the tree - */ - break; - } + /* + * Drop into the loop below because we are moving upwards in + * the tree + */ } else { @@ -221,69 +147,6 @@ status = ascending_callback (walk_state, parent); - - switch (status) - { - case AE_CTRL_FALSE: - - /* - * Either an IF/WHILE Predicate was false or we encountered a - * BREAK opcode. In both cases, we do not execute the rest of the - * package; We simply close out the parent (finishing the walk of - * this branch of the tree) and continue execution at the parent - * level. - */ - - parent = grand_parent; - next = grand_parent->next; - grand_parent = grand_parent->parent; - - status = ascending_callback (walk_state, parent); - - /* Now continue to the next node in the tree */ - - break; - - - case AE_CTRL_TRUE: - - /* - * Predicate of a WHILE was true and the loop just completed an - * execution. Go back to the start of the loop and reevaluate the - * predicate. - */ - - op = walk_state->control_state->control.predicate_op; - - walk_state->control_state->common.state = CONTROL_PREDICATE_EXECUTING; - - /* - * Acpi_evaluate the predicate again (next) - * Because we will traverse WHILE tree again - */ - - walk_state->prev_op = op->parent; - walk_state->next_op = op; - walk_state->next_op_info = NEXT_OP_DOWNWARD; - - return (AE_OK); - break; - - - case AE_CTRL_TERMINATE: - - /* - * A control method was terminated via a RETURN statement. - * The walk of this method is complete. - */ - walk_state->prev_op = walk_state->origin; - walk_state->next_op = NULL; - - return (AE_OK); - break; - } - - /* * If we are back to the starting point, the walk is complete. */ @@ -296,7 +159,6 @@ return (status); } - /* * If there is a sibling to this parent (it is not the starting point * Op), then we will visit it. @@ -311,18 +173,6 @@ return (status); } - /* - * No sibling, check for an error from closing the parent - * (Also, AE_PENDING if a method call was encountered) - */ - if (ACPI_FAILURE (status)) { - walk_state->prev_op = parent; - walk_state->next_op = grand_parent; - walk_state->next_op_info = NEXT_OP_UPWARD; - - return (status); - } - /* No siblings, no errors, just move up one more level in the tree */ op = parent; @@ -342,251 +192,88 @@ /******************************************************************************* * - * FUNCTION: Acpi_ps_walk_loop + * FUNCTION: Acpi_ps_delete_completed_op * - * PARAMETERS: Walk_list - State of the walk - * Start_op - Starting Op of the subtree to be walked - * Descending_callback - Procedure called when a new Op is - * encountered - * Ascending_callback - Procedure called when Op is complete + * PARAMETERS: State - Walk state + * Op - Completed op * - * RETURN: Status + * RETURN: AE_OK * - * DESCRIPTION: Perform a walk of the parsed AML tree. Begins and terminates at - * the Start_op. + * DESCRIPTION: Callback function for Acpi_ps_get_next_walk_op(). Used during + * Acpi_ps_delete_parse tree to delete Op objects when all sub-objects + * have been visited (and deleted.) * ******************************************************************************/ -ACPI_STATUS -acpi_ps_walk_loop ( - ACPI_WALK_LIST *walk_list, - ACPI_PARSE_OBJECT *start_op, - ACPI_PARSE_DOWNWARDS descending_callback, - ACPI_PARSE_UPWARDS ascending_callback) +static ACPI_STATUS +acpi_ps_delete_completed_op ( + ACPI_WALK_STATE *state, + ACPI_PARSE_OBJECT *op) { - ACPI_STATUS status = AE_OK; - ACPI_WALK_STATE *walk_state; - ACPI_PARSE_OBJECT *op = start_op; - - - walk_state = acpi_ds_get_current_walk_state (walk_list); - - - /* Walk entire subtree, visiting all nodes depth-first */ - - while (op) { - if (walk_state->next_op_info != NEXT_OP_UPWARD) { - status = descending_callback (op->opcode, op, walk_state, NULL); - } - - /* - * A TRUE exception means that an ELSE was detected, but the IF - * predicate evaluated TRUE. - */ - if (status == AE_CTRL_TRUE) { - /* - * Ignore the entire ELSE block by moving on to the the next opcode. - * And we do that by simply going up in the tree (either to the next - * sibling or to the parent) from here. - */ - - walk_state->next_op_info = NEXT_OP_UPWARD; - } - - /* Get the next node (op) in the depth-first walk */ - - status = acpi_ps_get_next_walk_op (walk_state, op, ascending_callback); - - /* - * A PENDING exception means that a control method invocation has been - * detected - */ - - if (status == AE_CTRL_PENDING) { - /* Transfer control to the called control method */ - - status = acpi_ds_call_control_method (walk_list, walk_state, op); - - /* - * If the transfer to the new method method call worked, a new walk - * state was created -- get it - */ - - walk_state = acpi_ds_get_current_walk_state (walk_list); - } - - /* Abort the walk on any exception */ - - if (ACPI_FAILURE (status)) { - return (status); - } - - op = walk_state->next_op; - } + acpi_ps_free_op (op); return (AE_OK); } /******************************************************************************* * - * FUNCTION: Acpi_ps_walk_parsed_aml + * FUNCTION: Acpi_ps_delete_parse_tree * - * PARAMETERS: Start_op - Starting Op of the subtree to be walked - * End_op - Where to terminate the walk - * Descending_callback - Procedure called when a new Op is - * encountered - * Ascending_callback - Procedure called when Op is complete + * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete * - * RETURN: Status - * - * DESCRIPTION: Top level interface to walk the parsed AML tree. Handles - * preemption of executing control methods. + * RETURN: None * - * NOTE: The End_op is usually only different from the Start_op if - * we don't want to visit the Start_op during the tree descent. + * DESCRIPTION: Delete a portion of or an entire parse tree. * ******************************************************************************/ -ACPI_STATUS -acpi_ps_walk_parsed_aml ( - ACPI_PARSE_OBJECT *start_op, - ACPI_PARSE_OBJECT *end_op, - ACPI_OPERAND_OBJECT *mth_desc, - ACPI_NAMESPACE_NODE *start_node, - ACPI_OPERAND_OBJECT **params, - ACPI_OPERAND_OBJECT **caller_return_desc, - ACPI_OWNER_ID owner_id, - ACPI_PARSE_DOWNWARDS descending_callback, - ACPI_PARSE_UPWARDS ascending_callback) +void +acpi_ps_delete_parse_tree ( + ACPI_PARSE_OBJECT *subtree_root) { - ACPI_PARSE_OBJECT *op; ACPI_WALK_STATE *walk_state; - ACPI_OPERAND_OBJECT *return_desc; - ACPI_STATUS status; ACPI_WALK_LIST walk_list; - ACPI_WALK_LIST *prev_walk_list; - /* Parameter Validation */ - - if (!start_op || !end_op) { - return (AE_BAD_PARAMETER); + if (!subtree_root) { + return; } - /* Initialize a new walk list */ + /* Create and initialize a new walk list */ walk_list.walk_state = NULL; - - walk_state = acpi_ds_create_walk_state (owner_id, end_op, mth_desc, &walk_list); + walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list); if (!walk_state) { - return (AE_NO_MEMORY); + return; } - /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter - */ - prev_walk_list = acpi_gbl_current_walk_list; - acpi_gbl_current_walk_list = &walk_list; + walk_state->parser_state = NULL; + walk_state->parse_flags = 0; + walk_state->descending_callback = NULL; + walk_state->ascending_callback = NULL; - if (start_node) { - /* Push start scope on scope stack and make it current */ - status = acpi_ds_scope_stack_push (start_node, ACPI_TYPE_METHOD, walk_state); - if (ACPI_FAILURE (status)) { - return (status); - } - - } - - if (mth_desc) { - /* Init arguments if this is a control method */ - /* TBD: [Restructure] add walkstate as a param */ - - acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state); - } + walk_state->origin = subtree_root; + walk_state->next_op = subtree_root; - op = start_op; - status = AE_OK; + /* Head downward in the tree */ - /* - * Execute the walk loop as long as there is a valid Walk State. This - * handles nested control method invocations without recursion. - */ - - while (walk_state) { - if (ACPI_SUCCESS (status)) { - status = acpi_ps_walk_loop (&walk_list, op, descending_callback, - ascending_callback); - } + walk_state->next_op_info = NEXT_OP_DOWNWARD; - /* We are done with this walk, move on to the parent if any */ - - BREAKPOINT3; - - walk_state = acpi_ds_pop_walk_state (&walk_list); - - /* Extract return value before we delete Walk_state */ - - return_desc = walk_state->return_desc; - - /* Reset the current scope to the beginning of scope stack */ - - acpi_ds_scope_stack_clear (walk_state); - - /* - * If we just returned from the execution of a control method, - * there's lots of cleanup to do - */ + /* Visit all nodes in the subtree */ - if (walk_state->method_desc) { - acpi_ds_terminate_control_method (walk_state); - } - - /* Delete this walk state and all linked control states */ - - acpi_ds_delete_walk_state (walk_state); - - /* Check if we have restarted a preempted walk */ - - walk_state = acpi_ds_get_current_walk_state (&walk_list); - if (walk_state && - ACPI_SUCCESS (status)) - { - /* There is another walk state, restart it */ - - /* - * If the method returned value is not used by the parent, - * The object is deleted - */ - - acpi_ds_restart_control_method (walk_state, return_desc); - - /* Get the next Op to process */ - - op = walk_state->next_op; - } - - /* - * Just completed a 1st-level method, save the final internal return - * value (if any) - */ - - else if (caller_return_desc) { - *caller_return_desc = return_desc; /* NULL if no return value */ - } - - else if (return_desc) { - /* Caller doesn't want it, must delete it */ - - acpi_cm_remove_reference (return_desc); - } + while (walk_state->next_op) { + acpi_ps_get_next_walk_op (walk_state, walk_state->next_op, + acpi_ps_delete_completed_op); } + /* We are done with this walk */ - acpi_gbl_current_walk_list = prev_walk_list; + acpi_ds_delete_walk_state (walk_state); - return (status); + return; } diff -urN linux-2.4.0-test12/drivers/acpi/parser/psxface.c linux-2.4.0-test12-lia/drivers/acpi/parser/psxface.c --- linux-2.4.0-test12/drivers/acpi/parser/psxface.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/parser/psxface.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psxface - Parser external interfaces - * $Revision: 36 $ + * $Revision: 37 $ * *****************************************************************************/ @@ -40,11 +40,13 @@ * * FUNCTION: Acpi_psx_execute * - * PARAMETERS: Obj_desc - A method object containing both the AML + * PARAMETERS: Method_node - A method object containing both the AML * address and length. * **Params - List of parameters to pass to method, * terminated by NULL. Params itself may be * NULL if no parameters are being passed. + * **Return_obj_desc - Return object from execution of the + * method. * * RETURN: Status * diff -urN linux-2.4.0-test12/drivers/acpi/resources/Makefile linux-2.4.0-test12-lia/drivers/acpi/resources/Makefile --- linux-2.4.0-test12/drivers/acpi/resources/Makefile Fri Sep 15 18:21:44 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsaddr.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsaddr.c --- linux-2.4.0-test12/drivers/acpi/resources/rsaddr.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsaddr.c Wed Nov 15 16:25:04 2000 @@ -1,12 +1,12 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsaddr - Acpi_rs_address16_resource * Acpi_rs_address16_stream * Acpi_rs_address32_resource * Acpi_rs_address32_stream - * $Revision: 9 $ + * $Revision: 12 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -28,16 +28,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsaddr") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_address16_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -53,7 +54,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address16_resource ( @@ -253,11 +254,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_address16_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -268,7 +269,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address16_stream ( @@ -350,7 +351,6 @@ */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.min_address_range); - buffer += 2; /* @@ -358,7 +358,6 @@ */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.max_address_range); - buffer += 2; /* @@ -366,7 +365,6 @@ */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.address_translation_offset); - buffer += 2; /* @@ -374,7 +372,6 @@ */ MOVE_UNALIGNED16_TO_16 (buffer, &linked_list->data.address16.address_length); - buffer += 2; /* @@ -418,11 +415,12 @@ return (AE_OK); } -/*************************************************************************** + +/******************************************************************************* + * * FUNCTION: Acpi_rs_address32_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -438,7 +436,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address32_resource ( @@ -641,11 +639,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_address32_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -656,7 +654,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_address32_stream ( @@ -676,7 +674,6 @@ * The descriptor field is static */ *buffer = 0x87; - buffer += 1; /* @@ -684,7 +681,6 @@ */ length_field = (u16 *)buffer; - buffer += 2; /* @@ -693,22 +689,17 @@ temp8 = (u8) (linked_list->data.address32.resource_type & 0x03); *buffer = temp8; - buffer += 1; /* * Set the general flags */ temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01); - temp8 |= (linked_list->data.address32.decode & 0x01) << 1; - temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2; - temp8 |= (linked_list->data.address32.max_address_fixed & 0x01) << 3; *buffer = temp8; - buffer += 1; /* @@ -747,7 +738,6 @@ */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.min_address_range); - buffer += 4; /* @@ -755,7 +745,6 @@ */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.max_address_range); - buffer += 4; /* @@ -763,7 +752,6 @@ */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset); - buffer += 4; /* @@ -771,7 +759,6 @@ */ MOVE_UNALIGNED32_TO_32 (buffer, &linked_list->data.address32.address_length); - buffer += 4; /* @@ -781,7 +768,6 @@ temp8 = (u8) linked_list->data.address32.resource_source_index; *buffer = temp8; - buffer += 1; temp_pointer = (NATIVE_CHAR *) buffer; diff -urN linux-2.4.0-test12/drivers/acpi/resources/rscalc.c linux-2.4.0-test12-lia/drivers/acpi/resources/rscalc.c --- linux-2.4.0-test12/drivers/acpi/resources/rscalc.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rscalc.c Wed Nov 15 16:25:04 2000 @@ -1,10 +1,10 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length * Acpi_rs_calculate_list_length - * $Revision: 9 $ + * $Revision: 16 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -26,16 +26,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rscalc") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_calculate_byte_stream_length * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Size_needed - u32 pointer of the size buffer needed * to properly return the parsed data * @@ -45,7 +46,7 @@ * the size buffer needed to hold the linked list that conveys * the resource data. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_calculate_byte_stream_length ( @@ -279,15 +280,14 @@ *size_needed = byte_stream_size_needed; return (AE_OK); - -} /* Acpi_rs_calculate_byte_stream_length */ +} -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_calculate_list_length * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource byte stream + * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream * Byte_stream_buffer_length - Size of Byte_stream_buffer * Size_needed - u32 pointer of the size buffer * needed to properly return the @@ -299,7 +299,7 @@ * the size buffer needed to hold the linked list that conveys * the resource data. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_calculate_list_length ( @@ -344,7 +344,6 @@ structure_size = sizeof (MEMORY24_RESOURCE) + RESOURCE_LENGTH_NO_DATA; - break; case LARGE_VENDOR_DEFINED: @@ -481,7 +480,6 @@ * Interrupt table length to the Temp8 variable. */ buffer += 3; - temp8 = *buffer; /* @@ -521,7 +519,7 @@ break; -/* 64-bit not currently supported */ +/* TBD: [Future] 64-bit not currently supported */ /* case 0x8A: break; @@ -555,7 +553,6 @@ * trailing bytes */ buffer = byte_stream_buffer; - temp8 = *buffer; if(temp8 & 0x01) { @@ -587,7 +584,6 @@ structure_size = sizeof (IO_RESOURCE) + RESOURCE_LENGTH_NO_DATA + (number_of_interrupts * sizeof (u32)); - break; @@ -621,7 +617,6 @@ structure_size = sizeof (DMA_RESOURCE) + RESOURCE_LENGTH_NO_DATA + (number_of_channels * sizeof (u32)); - break; @@ -634,7 +629,6 @@ * Determine if it there are two or three trailing bytes */ buffer = byte_stream_buffer; - temp8 = *buffer; if(temp8 & 0x01) { @@ -657,7 +651,6 @@ * End Dependent Functions Resource */ bytes_consumed = 1; - structure_size = RESOURCE_LENGTH; break; @@ -667,7 +660,6 @@ * IO Port Resource */ bytes_consumed = 8; - structure_size = sizeof (IO_RESOURCE) + RESOURCE_LENGTH_NO_DATA; break; @@ -679,7 +671,6 @@ * Fixed IO Port Resource */ bytes_consumed = 4; - structure_size = sizeof (FIXED_IO_RESOURCE) + RESOURCE_LENGTH_NO_DATA; break; @@ -700,7 +691,6 @@ * Ensure a 32-bit boundry for the structure */ temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); - structure_size = sizeof (VENDOR_RESOURCE) + RESOURCE_LENGTH_NO_DATA + (temp8 * sizeof (u8)); @@ -713,7 +703,6 @@ * End Tag */ bytes_consumed = 2; - structure_size = RESOURCE_LENGTH; break; @@ -749,14 +738,14 @@ *size_needed = buffer_size; return (AE_OK); +} -} /* Acpi_rs_calculate_list_length */ -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_calculate_pci_routing_table_length * - * PARAMETERS: - * Package_object - Pointer to the package object + * PARAMETERS: Package_object - Pointer to the package object * Buffer_size_needed - u32 pointer of the size buffer * needed to properly return the * parsed data @@ -767,17 +756,22 @@ * calculates the size of the corresponding linked list of * descriptions. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_calculate_pci_routing_table_length ( ACPI_OPERAND_OBJECT *package_object, u32 *buffer_size_needed) { - u32 number_of_elements; - u32 temp_size_needed; - ACPI_OPERAND_OBJECT **top_object_list; - u32 index; + u32 number_of_elements; + u32 temp_size_needed = 0; + ACPI_OPERAND_OBJECT **top_object_list; + u32 index; + ACPI_OPERAND_OBJECT *package_element; + ACPI_OPERAND_OBJECT **sub_object_list; + u8 name_found; + u32 table_index; + number_of_elements = package_object->package.count; @@ -791,8 +785,6 @@ * NOTE: The Number_of_elements is incremented by one to add an end * table structure that is essentially a structure of zeros. */ - temp_size_needed = (number_of_elements + 1) * - (sizeof (PCI_ROUTING_TABLE) - 1); /* * But each PRT_ENTRY structure has a pointer to a string and @@ -801,11 +793,6 @@ top_object_list = package_object->package.elements; for (index = 0; index < number_of_elements; index++) { - ACPI_OPERAND_OBJECT *package_element; - ACPI_OPERAND_OBJECT **sub_object_list; - u8 name_found; - u32 table_index; - /* * Dereference the sub-package */ @@ -835,6 +822,8 @@ } } + temp_size_needed += (sizeof (PCI_ROUTING_TABLE) - 1); + /* * Was a String type found? */ @@ -844,7 +833,6 @@ * terminating NULL */ temp_size_needed += (*sub_object_list)->string.length; - temp_size_needed = ROUND_UP_TO_32_bITS (temp_size_needed); } else { @@ -855,13 +843,19 @@ temp_size_needed += sizeof(u32); } + + /* Round up the size since each element must be aligned */ + + temp_size_needed = ROUND_UP_TO_64_bITS (temp_size_needed); + /* * Point to the next ACPI_OPERAND_OBJECT */ top_object_list++; } - *buffer_size_needed = temp_size_needed; + + *buffer_size_needed = temp_size_needed + sizeof (PCI_ROUTING_TABLE); return (AE_OK); -} \ No newline at end of file +} diff -urN linux-2.4.0-test12/drivers/acpi/resources/rscreate.c linux-2.4.0-test12-lia/drivers/acpi/resources/rscreate.c --- linux-2.4.0-test12/drivers/acpi/resources/rscreate.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rscreate.c Wed Nov 15 16:25:04 2000 @@ -1,11 +1,11 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rscreate - Acpi_rs_create_resource_list * Acpi_rs_create_pci_routing_table * Acpi_rs_create_byte_stream - * $Revision: 16 $ + * $Revision: 21 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -182,11 +182,12 @@ * contain a u32 Address, a u8 Pin, a Name and a u8 * Source_index. */ - top_object_list = package_object->package.elements; + top_object_list = package_object->package.elements; + number_of_elements = package_object->package.count; + user_prt = (PCI_ROUTING_TABLE *) buffer; - number_of_elements = package_object->package.count; - user_prt = (PCI_ROUTING_TABLE *) buffer; + buffer = ROUND_PTR_UP_TO_8 (buffer, u8); for (index = 0; index < number_of_elements; index++) { /* @@ -198,6 +199,7 @@ buffer += user_prt->length; user_prt = (PCI_ROUTING_TABLE *) buffer; + /* * Fill in the Length field with the information we * have at this point. @@ -237,7 +239,7 @@ if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { user_prt->data.pin = - (*sub_object_list)->number.value; + (u32) (*sub_object_list)->number.value; } else { @@ -257,8 +259,6 @@ * Add to the Length field the length of the string */ user_prt->length += (*sub_object_list)->string.length; - user_prt->length = - ROUND_UP_TO_32_bITS (user_prt->length); } else { @@ -280,6 +280,10 @@ } } + /* Now align the current length */ + + user_prt->length = ROUND_UP_TO_64_bITS (user_prt->length); + /* * Dereference the Source Index */ @@ -287,7 +291,7 @@ if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { user_prt->data.source_index = - (*sub_object_list)->number.value; + (u32) (*sub_object_list)->number.value; } else { @@ -314,7 +318,6 @@ *output_buffer_length = buffer_size_needed; return (AE_OK); - } @@ -393,6 +396,5 @@ } return (AE_OK); - } diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsdump.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsdump.c --- linux-2.4.0-test12/drivers/acpi/resources/rsdump.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsdump.c Wed Nov 15 16:25:04 2000 @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsdump - Functions do dump out the resource structures. - * $Revision: 10 $ + * $Revision: 12 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -25,12 +25,13 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsdump") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_irq * @@ -76,7 +77,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_dma * @@ -156,7 +157,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_start_dependent_functions * @@ -221,7 +222,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_io * @@ -261,7 +262,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_fixed_io * @@ -291,7 +292,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_vendor_specific * @@ -324,7 +325,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_memory24 * @@ -366,7 +367,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_memory32 * @@ -408,7 +409,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_fixed_memory32 * @@ -444,7 +445,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_address16 * @@ -587,7 +588,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_address32 * @@ -729,7 +730,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_extended_irq * @@ -787,7 +788,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_resource_list * @@ -886,7 +887,7 @@ return; } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_dump_irq_list * diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsio.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsio.c --- linux-2.4.0-test12/drivers/acpi/resources/rsio.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsio.c Wed Nov 15 16:25:04 2000 @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsio - Acpi_rs_io_resource * Acpi_rs_fixed_io_resource @@ -6,9 +6,9 @@ * Acpi_rs_fixed_io_stream * Acpi_rs_dma_resource * Acpi_rs_dma_stream - * $Revision: 7 $ + * $Revision: 10 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -30,16 +30,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsio") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_io_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -55,7 +56,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_io_resource ( @@ -133,11 +134,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_io_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -153,7 +154,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_io_resource ( @@ -207,11 +208,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_io_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -222,7 +223,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_io_stream ( @@ -239,7 +240,6 @@ * The descriptor field is static */ *buffer = 0x47; - buffer += 1; /* @@ -248,7 +248,6 @@ temp8 = (u8) (linked_list->data.io.io_decode & 0x01); *buffer = temp8; - buffer += 1; /* @@ -256,8 +255,7 @@ */ temp16 = (u16) linked_list->data.io.min_base_address; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -265,8 +263,7 @@ */ temp16 = (u16) linked_list->data.io.max_base_address; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -275,7 +272,6 @@ temp8 = (u8) linked_list->data.io.alignment; *buffer = temp8; - buffer += 1; /* @@ -284,7 +280,6 @@ temp8 = (u8) linked_list->data.io.range_length; *buffer = temp8; - buffer += 1; /* @@ -297,11 +292,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_io_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -312,7 +307,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_io_stream ( @@ -337,8 +332,7 @@ */ temp16 = (u16) linked_list->data.fixed_io.base_address; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -347,7 +341,6 @@ temp8 = (u8) linked_list->data.fixed_io.range_length; *buffer = temp8; - buffer += 1; /* @@ -360,11 +353,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_dma_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -380,7 +373,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_dma_resource ( @@ -402,14 +395,12 @@ * The number of bytes consumed are Constant */ *bytes_consumed = 3; - output_struct->id = dma; /* * Point to the 8-bits of Byte 1 */ buffer += 1; - temp8 = *buffer; /* Decode the IRQ bits */ @@ -431,9 +422,8 @@ /* * Point to Byte 2 */ - buffer += 1; - - temp8 = *buffer; + buffer += 1; + temp8 = *buffer; /* * Check for transfer preference (Bits[1:0]) @@ -468,11 +458,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_dma_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -483,7 +473,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_dma_stream ( @@ -501,9 +491,7 @@ * The descriptor field is static */ *buffer = 0x2A; - buffer += 1; - temp8 = 0; /* @@ -518,20 +506,16 @@ } *buffer = temp8; - buffer += 1; /* * Set the DMA Info */ temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5); - temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2); - temp8 |= (linked_list->data.dma.transfer & 0x03); *buffer = temp8; - buffer += 1; /* diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsirq.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsirq.c --- linux-2.4.0-test12/drivers/acpi/resources/rsirq.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsirq.c Wed Nov 15 16:25:04 2000 @@ -1,12 +1,12 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsirq - Acpi_rs_irq_resource, * Acpi_rs_irq_stream * Acpi_rs_extended_irq_resource * Acpi_rs_extended_irq_stream - * $Revision: 8 $ + * $Revision: 11 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -28,16 +28,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsirq") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_irq_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -53,7 +54,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_irq_resource ( @@ -77,9 +78,7 @@ * (Bits:0-1) */ temp8 = *buffer; - *bytes_consumed = (temp8 & 0x03) + 1; - output_struct->id = irq; /* @@ -91,6 +90,7 @@ output_struct->data.irq.number_of_interrupts = 0; /* Decode the IRQ bits */ + for (i = 0, index = 0; index < 16; index++) { if((temp16 >> index) & 0x01) { output_struct->data.irq.interrupts[i] = index; @@ -109,7 +109,6 @@ */ if (4 == *bytes_consumed) { buffer += 2; - temp8 = *buffer; /* @@ -166,11 +165,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_irq_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -181,7 +180,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_irq_stream ( @@ -213,7 +212,6 @@ } buffer += 1; - temp16 = 0; /* @@ -227,8 +225,7 @@ temp16 |= 0x1 << temp8; } - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; /* @@ -236,7 +233,6 @@ */ if (IRQinfo_byte_needed) { temp8 = 0; - temp8 = (u8) ((linked_list->data.irq.shared_exclusive & 0x01) << 4); @@ -251,7 +247,6 @@ } *buffer = temp8; - buffer += 1; } @@ -265,11 +260,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_extended_irq_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -285,7 +280,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_extended_irq_resource ( @@ -450,11 +445,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_extended_irq_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -463,9 +458,9 @@ * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code * * DESCRIPTION: Take the linked list resource structure and fills in the - * the appropriate bytes in a byte stream + * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_extended_irq_stream ( @@ -518,7 +513,6 @@ temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts; *buffer = temp8; - buffer += 1; for (index = 0; diff -urN linux-2.4.0-test12/drivers/acpi/resources/rslist.c linux-2.4.0-test12-lia/drivers/acpi/resources/rslist.c --- linux-2.4.0-test12/drivers/acpi/resources/rslist.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rslist.c Wed Nov 15 16:25:04 2000 @@ -1,10 +1,10 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rslist - Acpi_rs_byte_stream_to_list * Acpi_list_to_byte_stream - * $Revision: 6 $ + * $Revision: 8 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -32,11 +32,11 @@ MODULE_NAME ("rslist") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_byte_stream_to_list * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource byte stream + * PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream * Byte_stream_buffer_length - Length of Byte_stream_buffer * Output_buffer - Pointer to the buffer that will * contain the output structures @@ -46,7 +46,7 @@ * DESCRIPTION: Takes the resource byte stream and parses it, creating a * linked list of resources in the caller's output buffer * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_byte_stream_to_list ( @@ -157,7 +157,7 @@ break; -/* 64-bit not currently supported */ +/* TBD: [Future] 64-bit not currently supported */ /* case 0x8A: break; @@ -309,15 +309,14 @@ } return (AE_OK); - -} /* Acpi_rs_byte_stream_to_list */ +} -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_list_to_byte_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Byte_steam_size_needed - Calculated size of the byte stream * needed from calling * Acpi_rs_calculate_byte_stream_length() @@ -332,7 +331,7 @@ * DESCRIPTION: Takes the resource linked list and parses it, creating a * byte stream of resources in the caller's output buffer * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_list_to_byte_stream ( @@ -503,6 +502,5 @@ } return (AE_OK); - -} /* Acpi_rs_list_to_byte_stream */ +} diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsmemory.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsmemory.c --- linux-2.4.0-test12/drivers/acpi/resources/rsmemory.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsmemory.c Wed Nov 15 16:25:04 2000 @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsmem24 - Acpi_rs_memory24_resource * Acpi_rs_memory24_stream @@ -6,9 +6,9 @@ * Acpi_rs_fixed_memory32_resource * Acpi_rs_memory32_range_stream * Acpi_rs_fixed_memory32_stream - * $Revision: 7 $ + * $Revision: 10 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -30,16 +30,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsmemory") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory24_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -55,7 +56,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory24_resource ( @@ -78,54 +79,42 @@ buffer += 1; MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - *bytes_consumed = temp16 + 3; - output_struct->id = memory24; /* * Check Byte 3 the Read/Write bit */ temp8 = *buffer; - buffer += 1; - output_struct->data.memory24.read_write_attribute = temp8 & 0x01; /* * Get Min_base_address (Bytes 4-5) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - output_struct->data.memory24.min_base_address = temp16; /* * Get Max_base_address (Bytes 6-7) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - output_struct->data.memory24.max_base_address = temp16; /* * Get Alignment (Bytes 8-9) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - buffer += 2; - output_struct->data.memory24.alignment = temp16; /* * Get Range_length (Bytes 10-11) */ MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - output_struct->data.memory24.range_length = temp16; /* @@ -142,11 +131,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory24_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -157,7 +146,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory24_stream ( @@ -174,16 +163,13 @@ * The descriptor field is static */ *buffer = 0x81; - buffer += 1; /* * The length field is static */ temp16 = 0x09; - MOVE_UNALIGNED16_TO_16 (buffer, &temp16); - buffer += 2; /* @@ -227,11 +213,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory32_range_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -247,7 +233,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory32_range_resource ( @@ -332,11 +318,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_memory32_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -352,7 +338,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_memory32_resource ( @@ -414,11 +400,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_memory32_range_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -429,7 +415,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_memory32_range_stream ( @@ -497,11 +483,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_fixed_memory32_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -512,7 +498,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_fixed_memory32_stream ( diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsmisc.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsmisc.c --- linux-2.4.0-test12/drivers/acpi/resources/rsmisc.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsmisc.c Wed Nov 15 16:25:04 2000 @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsmisc - Acpi_rs_end_tag_resource * Acpi_rs_end_tag_stream @@ -8,9 +8,9 @@ * Acpi_rs_end_dependent_functions_resource * Acpi_rs_start_dependent_functions_stream * Acpi_rs_end_dependent_functions_stream - * $Revision: 7 $ + * $Revision: 10 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -32,16 +32,17 @@ #include "acpi.h" +#include "acresrc.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rsmisc") -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_tag_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -57,7 +58,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_tag_resource ( @@ -94,11 +95,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_tag_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -109,7 +110,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_tag_stream ( @@ -125,7 +126,6 @@ * The descriptor field is static */ *buffer = 0x79; - buffer += 1; /* @@ -135,7 +135,6 @@ temp8 = 0; *buffer = temp8; - buffer += 1; /* @@ -147,11 +146,12 @@ return (AE_OK); } -/*************************************************************************** + +/******************************************************************************* + * * FUNCTION: Acpi_rs_vendor_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -167,7 +167,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_vendor_resource ( @@ -230,7 +230,6 @@ } output_struct->id = vendor_specific; - output_struct->data.vendor_specific.length = temp16; for (index = 0; index < temp16; index++) { @@ -259,11 +258,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_vendor_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -274,7 +273,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_vendor_stream ( @@ -300,13 +299,11 @@ * Set the descriptor field and length bytes */ *buffer = 0x84; - buffer += 1; temp16 = (u16) linked_list->data.vendor_specific.length; - MOVE_UNALIGNED16_TO_16 (&temp16, buffer); - + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; } @@ -319,11 +316,9 @@ * Set the descriptor field */ temp8 = 0x70; - temp8 |= linked_list->data.vendor_specific.length; *buffer = temp8; - buffer += 1; } @@ -332,6 +327,7 @@ */ for (index = 0; index < linked_list->data.vendor_specific.length; index++) { temp8 = linked_list->data.vendor_specific.reserved[index]; + *buffer = temp8; buffer += 1; } @@ -345,11 +341,12 @@ return (AE_OK); } -/*************************************************************************** + +/******************************************************************************* + * * FUNCTION: Acpi_rs_start_dependent_functions_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -365,7 +362,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_start_dependent_functions_resource ( @@ -441,11 +438,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_dependent_functions_resource * - * PARAMETERS: - * Byte_stream_buffer - Pointer to the resource input byte + * PARAMETERS: Byte_stream_buffer - Pointer to the resource input byte * stream * Bytes_consumed - u32 pointer that is filled with * the number of bytes consumed from @@ -461,7 +458,7 @@ * structure pointed to by the Output_buffer. Return the * number of bytes consumed from the byte stream. * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_dependent_functions_resource ( @@ -498,11 +495,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_start_dependent_functions_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -513,7 +510,8 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ + ACPI_STATUS acpi_rs_start_dependent_functions_stream ( RESOURCE *linked_list, @@ -537,18 +535,15 @@ } else { *buffer = 0x31; - buffer += 1; /* * Set the Priority Byte Definition */ temp8 = 0; - temp8 = (u8) ((linked_list->data.start_dependent_functions.performance_robustness & 0x03) << 2); - temp8 |= (linked_list->data.start_dependent_functions.compatibility_priority & 0x03); @@ -568,11 +563,11 @@ } -/*************************************************************************** +/******************************************************************************* + * * FUNCTION: Acpi_rs_end_dependent_functions_stream * - * PARAMETERS: - * Linked_list - Pointer to the resource linked list + * PARAMETERS: Linked_list - Pointer to the resource linked list * Output_buffer - Pointer to the user's return buffer * Bytes_consumed - u32 pointer that is filled with * the number of bytes of the @@ -583,7 +578,7 @@ * DESCRIPTION: Take the linked list resource structure and fills in the * the appropriate bytes in a byte stream * - ***************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_rs_end_dependent_functions_stream ( @@ -599,7 +594,6 @@ * The descriptor field is static */ *buffer = 0x38; - buffer += 1; /* diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsutils.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsutils.c --- linux-2.4.0-test12/drivers/acpi/resources/rsutils.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsutils.c Wed Nov 15 16:25:04 2000 @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsutils - Utilities for the resource manager - * $Revision: 10 $ + * $Revision: 12 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -33,7 +33,7 @@ MODULE_NAME ("rsutils") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_get_prt_method_data * @@ -117,7 +117,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_get_crs_method_data * @@ -200,7 +200,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_get_prs_method_data * @@ -281,7 +281,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_rs_set_srs_method_data * @@ -310,6 +310,7 @@ u8 *byte_stream = NULL; u32 buffer_size_needed = 0; + /* already validated params, so we won't repeat here */ /* @@ -325,7 +326,6 @@ status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, &buffer_size_needed); - /* * We expect a return of AE_BUFFER_OVERFLOW * if not, exit with the error @@ -338,7 +338,6 @@ * Allocate the buffer needed */ byte_stream = acpi_cm_callocate(buffer_size_needed); - if (NULL == byte_stream) { return (AE_NO_MEMORY); } @@ -349,7 +348,6 @@ status = acpi_rs_create_byte_stream (in_buffer->pointer, byte_stream, &buffer_size_needed); - if (ACPI_FAILURE (status)) { goto cleanup; } diff -urN linux-2.4.0-test12/drivers/acpi/resources/rsxface.c linux-2.4.0-test12-lia/drivers/acpi/resources/rsxface.c --- linux-2.4.0-test12/drivers/acpi/resources/rsxface.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/resources/rsxface.c Wed Nov 15 16:25:04 2000 @@ -1,9 +1,9 @@ -/****************************************************************************** +/******************************************************************************* * * Module Name: rsxface - Public interfaces to the ACPI subsystem - * $Revision: 7 $ + * $Revision: 8 $ * - *****************************************************************************/ + ******************************************************************************/ /* * Copyright (C) 2000 R. Byron Moore @@ -33,7 +33,7 @@ MODULE_NAME ("rsxface") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_get_irq_routing_table * @@ -83,7 +83,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_get_current_resources * @@ -134,7 +134,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_get_possible_resources * @@ -142,7 +142,7 @@ * device we are querying * Ret_buffer - a pointer to a buffer to receive the * resources for the device - * + * * RETURN: Status - the status of the call * * DESCRIPTION: This function is called to get a list of the possible resources @@ -182,7 +182,7 @@ } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_set_current_resources * diff -urN linux-2.4.0-test12/drivers/acpi/sys.c linux-2.4.0-test12-lia/drivers/acpi/sys.c --- linux-2.4.0-test12/drivers/acpi/sys.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/sys.c Wed Nov 15 16:25:04 2000 @@ -27,16 +27,14 @@ #define _COMPONENT OS_DEPENDENT MODULE_NAME ("sys") -#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb)) -#define ACPI_SLP_TYPA(value) \ - ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) -#define ACPI_SLP_TYPB(value) \ - ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) +#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb)) +#define ACPI_SLP_TYPA(value) ((value) >> 8) +#define ACPI_SLP_TYPB(value) ((value) & 0xff) struct acpi_enter_sx_ctx { wait_queue_head_t wait; - int state; + unsigned int state; }; volatile acpi_sstate_t acpi_sleep_state = ACPI_S0; @@ -49,10 +47,8 @@ acpi_enter_sx_async(void *context) { struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context; - struct acpi_facp *facp = &acpi_facp; ACPI_OBJECT_LIST arg_list; ACPI_OBJECT arg; - u16 value; /* * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. @@ -69,34 +65,26 @@ acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL); - // clear wake status - acpi_write_pm1_status(facp, ACPI_WAK); - + // clear wake status by writing a 1 + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1); + acpi_sleep_state = ctx->state; // set ACPI_SLP_TYPA/b and ACPI_SLP_EN - __cli(); - if (facp->pm1a_cnt) { - value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK; - value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state]) - | ACPI_SLP_EN); - outw(value, facp->pm1a_cnt); - } - if (facp->pm1b_cnt) { - value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK; - value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state]) - | ACPI_SLP_EN); - outw(value, facp->pm1b_cnt); - } - __sti(); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_TYPE_A, + ACPI_SLP_TYPA(acpi_slptyp[ctx->state])); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_TYPE_B, + ACPI_SLP_TYPB(acpi_slptyp[ctx->state])); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, SLP_EN, 1); if (ctx->state != ACPI_S1) { + /* we should have just shut off - what are we doing here? */ printk(KERN_ERR "ACPI: S%d failed\n", ctx->state); goto out; } // wait until S1 is entered - while (!(acpi_read_pm1_status(facp) & ACPI_WAK)) + while (!(acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, WAK_STS))) safe_halt(); // run the _WAK method @@ -125,7 +113,7 @@ { struct acpi_enter_sx_ctx ctx; - if (acpi_facp.hdr.signature != ACPI_FACP_SIG + if ((STRNCMP(acpi_fadt.header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) || acpi_slptyp[ACPI_S5] == ACPI_INVALID) return; @@ -142,7 +130,7 @@ { struct acpi_enter_sx_ctx ctx; - if (acpi_facp.hdr.signature != ACPI_FACP_SIG + if ((STRNCMP(acpi_fadt.header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) || acpi_slptyp[state] == ACPI_INVALID) return -EINVAL; @@ -162,23 +150,28 @@ int acpi_sys_init(void) { - u8 sx, typa, typb; + u8 sx; + u8 type_a; + u8 type_b; + + printk(KERN_INFO "ACPI: System firmware supports:"); for (sx = ACPI_S0; sx <= ACPI_S5; sx++) { int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1); if (ACPI_SUCCESS( acpi_hw_obtain_sleep_type_register_data(ca_sx, - &typa, - &typb))) - acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb); - else + &type_a, + &type_b))) { + + acpi_slptyp[sx] = ACPI_SLP_TYP(type_a, type_b); + printk(" S%d", sx); + } + else { acpi_slptyp[sx] = ACPI_INVALID; + } } - if (acpi_slptyp[ACPI_S1] != ACPI_INVALID) - printk(KERN_INFO "ACPI: S1 supported\n"); - if (acpi_slptyp[ACPI_S5] != ACPI_INVALID) - printk(KERN_INFO "ACPI: S5 supported\n"); - + printk("\n"); + pm_power_off = acpi_power_off; return 0; diff -urN linux-2.4.0-test12/drivers/acpi/table.c linux-2.4.0-test12-lia/drivers/acpi/table.c --- linux-2.4.0-test12/drivers/acpi/table.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/table.c Wed Nov 15 16:25:04 2000 @@ -1,5 +1,5 @@ /* - * tables.c - ACPI tables, chipset, and errata handling + * table.c - ACPI tables, chipset, and errata handling * * Copyright (C) 2000 Andrew Henroid * @@ -27,250 +27,39 @@ #include "driver.h" #define _COMPONENT OS_DEPENDENT - MODULE_NAME ("tables") + MODULE_NAME ("table") -struct acpi_facp acpi_facp; - -#define ACPI_DUMMY_CHECKSUM 9 -#define ACPI_DUMMY_PBLK 51 - -static u8 acpi_dummy_dsdt[] = -{ - 0x44, 0x53, 0x44, 0x54, // "DSDT" - 0x38, 0x00, 0x00, 0x00, // length - 0x01, // revision - 0x00, // checksum - 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX" - 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY" - 0x01, 0x00, 0x00, 0x00, // OEM rev - 0x4c, 0x4e, 0x55, 0x58, // "LNUX" - 0x01, 0x00, 0x00, 0x00, // creator rev - 0x10, // Scope - 0x13, // PkgLength - 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_ - 0x5b, 0x83, // Processor - 0x0b, // PkgLength - 0x43, 0x50, 0x55, 0x30, // CPU0 - 0x00, // ID - 0x00, 0x00, 0x00, 0x00, // PBLK - 0x06 // PBLK size -}; - -/* - * Calculate and set ACPI table checksum - */ -static void -acpi_set_checksum(u8 *table, int size) -{ - int i, sum = 0; - for (i = 0; i < size; i++) - sum += (int) table[i]; - sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff)); - table[ACPI_DUMMY_CHECKSUM] = sum; -} - -/* - * Init PIIX4 device, create a fake FACP - */ -static int -acpi_init_piix4(struct pci_dev *dev) -{ - u32 base, pblk; - u16 cmd; - u8 pmregmisc; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (!(cmd & PCI_COMMAND_IO)) - return -ENODEV; - - pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc); - if (!(pmregmisc & ACPI_PIIX4_PMIOSE)) - return -ENODEV; - - base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES); - if (!base) - return -ENODEV; - - printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); - - memset(&acpi_facp, 0, sizeof(acpi_facp)); - acpi_facp.hdr.signature = ACPI_FACP_SIG; - acpi_facp.hdr.length = sizeof(acpi_facp); - acpi_facp.int_model = ACPI_PIIX4_INT_MODEL; - acpi_facp.sci_int = ACPI_PIIX4_SCI_INT; - acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD; - acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE; - acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE; - acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ; - acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT; - acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT; - acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT; - acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR; - acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0; - acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN; - acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN; - acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN; - acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN; - acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN; - acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; - acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; - - acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); - acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); - - pblk = base + ACPI_PIIX4_P_BLK; - memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); - acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); - acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); - - return 0; -} +FADT_DESCRIPTOR acpi_fadt; /* - * Init VIA ACPI device and create a fake FACP + * Fetch the fadt information */ static int -acpi_init_via(struct pci_dev *dev) -{ - u32 base, pblk; - u8 tmp, irq; - - pci_read_config_byte(dev, 0x41, &tmp); - if (!(tmp & 0x80)) - return -ENODEV; - - base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES); - if (!base) { - base = pci_resource_start(dev, PCI_BASE_ADDRESS_4); - if (!base) - return -ENODEV; - } - - pci_read_config_byte(dev, 0x42, &irq); - - printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); - - memset(&acpi_facp, 0, sizeof(acpi_facp)); - acpi_facp.hdr.signature = ACPI_FACP_SIG; - acpi_facp.hdr.length = sizeof(acpi_facp); - acpi_facp.int_model = ACPI_VIA_INT_MODEL; - acpi_facp.sci_int = irq; - acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD; - acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE; - acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE; - acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT; - acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT; - acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR; - acpi_facp.gpe0 = base + ACPI_VIA_GPE0; - - acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN; - acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN; - acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN; - acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN; - acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; - acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; - - acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET; - acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH; - - acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM; - acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM; - acpi_facp.century = ACPI_VIA_CENTURY; - - acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); - acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); - - pblk = base + ACPI_VIA_P_BLK; - memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); - acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); - acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); - - return 0; -} - -typedef enum -{ - CH_UNKNOWN = 0, - CH_INTEL_PIIX4, - CH_VIA_586, - CH_VIA_686A, -} acpi_chip_t; - -/* indexed by value of each enum in acpi_chip_t */ -const static struct -{ - int (*chip_init)(struct pci_dev *dev); -} acpi_chip_info[] = -{ - {NULL,}, - {acpi_init_piix4}, - {acpi_init_via}, - {acpi_init_via}, -}; - -static struct pci_device_id acpi_pci_tbl[] = -{ - {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, - {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586}, - {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A}, - {0,} /* terminate list */ -}; - -static int -acpi_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - return acpi_chip_info[id->driver_data].chip_init(dev); -} - -static struct pci_driver acpi_driver = -{ - name: "acpi", - id_table: acpi_pci_tbl, - probe: acpi_probe, -}; -static int acpi_driver_registered = 0; - -/* - * Locate a known ACPI chipset - */ -static int -acpi_find_chipset(void) -{ - if (pci_register_driver(&acpi_driver) < 1) - return -ENODEV; - acpi_driver_registered = 1; - return 0; -} - -/* - * Fetch the FACP information - */ -static int -acpi_fetch_facp(void) +acpi_fetch_fadt(void) { ACPI_BUFFER buffer; - memset(&acpi_facp, 0, sizeof(acpi_facp)); - buffer.pointer = &acpi_facp; - buffer.length = sizeof(acpi_facp); - if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) { - printk(KERN_ERR "ACPI: missing FACP\n"); + memset(&acpi_fadt, 0, sizeof(acpi_fadt)); + buffer.pointer = &acpi_fadt; + buffer.length = sizeof(acpi_fadt); + if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) { + printk(KERN_ERR "ACPI: missing fadt\n"); return -ENODEV; } - if (acpi_facp.p_lvl2_lat - && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) { + if (acpi_fadt.plvl2_lat + && acpi_fadt.plvl2_lat <= ACPI_MAX_P_LVL2_LAT) { acpi_c2_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat); acpi_c2_enter_latency - = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); + = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); } - if (acpi_facp.p_lvl3_lat - && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) { + if (acpi_fadt.plvl3_lat + && acpi_fadt.plvl3_lat <= ACPI_MAX_P_LVL3_LAT) { acpi_c3_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat); acpi_c3_enter_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5); } return 0; @@ -280,24 +69,19 @@ * Find and load ACPI tables */ int -acpi_load_tables(void) +acpi_find_and_load_tables(u64 rsdp) { - if (ACPI_SUCCESS(acpi_load_firmware_tables())) + if (ACPI_SUCCESS(acpi_load_tables(rsdp))) { - printk(KERN_INFO "ACPI: support found\n"); + printk(KERN_INFO "ACPI: System description tables loaded\n"); } - else if (acpi_find_chipset()) { - acpi_terminate(); - return -1; - } - - if (acpi_fetch_facp()) { + else { + printk(KERN_INFO "ACPI: System description table load failed\n"); acpi_terminate(); return -1; } - if (!ACPI_SUCCESS(acpi_load_namespace())) { - printk(KERN_ERR "ACPI: namespace load failed\n"); + if (acpi_fetch_fadt()) { acpi_terminate(); return -1; } diff -urN linux-2.4.0-test12/drivers/acpi/tables/Makefile linux-2.4.0-test12-lia/drivers/acpi/tables/Makefile --- linux-2.4.0-test12/drivers/acpi/tables/Makefile Fri Sep 15 18:21:44 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/Makefile Wed Nov 15 16:25:04 2000 @@ -17,8 +17,7 @@ EXTRA_CFLAGS += $(ACPI_CFLAGS) -# if the interpreter is used, it overrides arch/i386/kernel/acpi.c -ifeq ($(CONFIG_ACPI_INTERPRETER),y) +ifeq ($(CONFIG_ACPI),y) O_OBJS := $(ACPI_OBJS) endif diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbconvrt.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbconvrt.c --- linux-2.4.0-test12/drivers/acpi/tables/tbconvrt.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbconvrt.c Wed Nov 15 16:25:04 2000 @@ -0,0 +1,553 @@ +/****************************************************************************** + * + * Module Name: tbconvrt - ACPI Table conversion utilities + * $Revision: 14 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "achware.h" +#include "actables.h" +#include "actbl.h" + + +#define _COMPONENT TABLE_MANAGER + MODULE_NAME ("tbconvrt") + + +/* + * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions) + * + * 1) Address space + * 2) Length in bytes -- convert to length in bits + * 3) Bit offset is zero + * 4) Reserved field is zero + * 5) Expand address to 64 bits + */ +#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d) {a.address_space_id = (u8) d;\ + a.register_bit_width = (u8) MUL_8 (b);\ + a.register_bit_offset = 0;\ + a.reserved = 0;\ + a.address = (UINT64) c;} + + +/* ACPI V1.0 entries -- address space is always I/O */ + +#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c) ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ADDRESS_SPACE_SYSTEM_IO) + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_convert_to_xsdt + * + * PARAMETERS: + * + * RETURN: + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_convert_to_xsdt ( + ACPI_TABLE_DESC *table_info, + u32 *number_of_tables) +{ + u32 table_size; + u32 pointer_size; + u32 i; + XSDT_DESCRIPTOR *new_table; + + +#ifndef _IA64 + + if (acpi_gbl_RSDP->revision < 2) { + pointer_size = sizeof (u32); + } + + else +#endif + { + pointer_size = sizeof (UINT64); + } + + /* + * Determine the number of tables pointed to by the RSDT/XSDT. + * This is defined by the ACPI Specification to be the number of + * pointers contained within the RSDT/XSDT. The size of the pointers + * is architecture-dependent. + */ + + table_size = table_info->pointer->length; + *number_of_tables = (table_size - + sizeof (ACPI_TABLE_HEADER)) / pointer_size; + + /* Compute size of the converted XSDT */ + + table_size = (*number_of_tables * sizeof (UINT64)) + sizeof (ACPI_TABLE_HEADER); + + + /* Allocate an XSDT */ + + new_table = acpi_cm_callocate (table_size); + if (!new_table) { + return (AE_NO_MEMORY); + } + + /* Copy the header and set the length */ + + MEMCPY (new_table, table_info->pointer, sizeof (ACPI_TABLE_HEADER)); + new_table->header.length = table_size; + + /* Copy the table pointers */ + + for (i = 0; i < *number_of_tables; i++) { + if (acpi_gbl_RSDP->revision < 2) { +#ifdef _IA64 + new_table->table_offset_entry[i] = + ((RSDT_DESCRIPTOR_REV071 *) table_info->pointer)->table_offset_entry[i]; +#else + new_table->table_offset_entry[i] = + ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]; +#endif + } + else { + new_table->table_offset_entry[i] = + ((XSDT_DESCRIPTOR *) table_info->pointer)->table_offset_entry[i]; + } + } + + + /* Delete the original table (either mapped or in a buffer) */ + + acpi_tb_delete_single_table (table_info); + + + /* Point the table descriptor to the new table */ + + table_info->pointer = (ACPI_TABLE_HEADER *) new_table; + table_info->base_pointer = (ACPI_TABLE_HEADER *) new_table; + table_info->length = table_size; + table_info->allocation = ACPI_MEM_ALLOCATED; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_convert_table_fadt + * + * PARAMETERS: + * + * RETURN: + * + * DESCRIPTION: + * Converts BIOS supplied 1.0 and 0.71 ACPI FADT to an intermediate + * ACPI 2.0 FADT. If the BIOS supplied a 2.0 FADT then it is simply + * copied to the intermediate FADT. The ACPI CA software uses this + * intermediate FADT. Thus a significant amount of special #ifdef + * type codeing is saved. This intermediate FADT will need to be + * freed at some point. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_convert_table_fadt (void) +{ + +#ifdef _IA64 + FADT_DESCRIPTOR_REV071 *FADT71; + u8 pm1_address_space; + u8 pm2_address_space; + u8 pm_timer_address_space; + u8 gpe0address_space; + u8 gpe1_address_space; +#else + FADT_DESCRIPTOR_REV1 *FADT1; +#endif + + FADT_DESCRIPTOR_REV2 *FADT2; + ACPI_TABLE_DESC *table_desc; + + + /* Acpi_gbl_FADT is valid */ + /* Allocate and zero the 2.0 buffer */ + + FADT2 = acpi_cm_callocate (sizeof (FADT_DESCRIPTOR_REV2)); + if (FADT2 == NULL) { + return (AE_NO_MEMORY); + } + + + /* The ACPI FADT revision number is FADT2_REVISION_ID=3 */ + /* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */ + + if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) { + /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ + + *FADT2 = *((FADT_DESCRIPTOR_REV2*) acpi_gbl_FADT); + + } + + else { + +#ifdef _IA64 + /* + * For the 64-bit case only, a revision ID less than V2.0 means the + * tables are the 0.71 extensions + */ + + /* The BIOS stored FADT should agree with Revision 0.71 */ + + FADT71 = (FADT_DESCRIPTOR_REV071 *) acpi_gbl_FADT; + + /* Copy the table header*/ + + FADT2->header = FADT71->header; + + /* Copy the common fields */ + + FADT2->sci_int = FADT71->sci_int; + FADT2->acpi_enable = FADT71->acpi_enable; + FADT2->acpi_disable = FADT71->acpi_disable; + FADT2->S4_bios_req = FADT71->S4_bios_req; + FADT2->plvl2_lat = FADT71->plvl2_lat; + FADT2->plvl3_lat = FADT71->plvl3_lat; + FADT2->day_alrm = FADT71->day_alrm; + FADT2->mon_alrm = FADT71->mon_alrm; + FADT2->century = FADT71->century; + FADT2->gpe1_base = FADT71->gpe1_base; + + /* + * We still use the block length registers even though + * the GAS structure should obsolete them. This is because + * these registers are byte lengths versus the GAS which + * contains a bit width + */ + FADT2->pm1_evt_len = FADT71->pm1_evt_len; + FADT2->pm1_cnt_len = FADT71->pm1_cnt_len; + FADT2->pm2_cnt_len = FADT71->pm2_cnt_len; + FADT2->pm_tm_len = FADT71->pm_tm_len; + FADT2->gpe0blk_len = FADT71->gpe0blk_len; + FADT2->gpe1_blk_len = FADT71->gpe1_blk_len; + FADT2->gpe1_base = FADT71->gpe1_base; + + /* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/ + + FADT2->wb_invd = FADT71->flush_cash; + FADT2->proc_c1 = FADT71->proc_c1; + FADT2->plvl2_up = FADT71->plvl2_up; + FADT2->pwr_button = FADT71->pwr_button; + FADT2->sleep_button = FADT71->sleep_button; + FADT2->fixed_rTC = FADT71->fixed_rTC; + FADT2->rtcs4 = FADT71->rtcs4; + FADT2->tmr_val_ext = FADT71->tmr_val_ext; + FADT2->dock_cap = FADT71->dock_cap; + + + /* We should not use these next two addresses */ + /* Since our buffer is pre-zeroed nothing to do for */ + /* the next three data items in the structure */ + /* FADT2->Firmware_ctrl = 0; */ + /* FADT2->Dsdt = 0; */ + + /* System Interrupt Model isn't used in ACPI 2.0*/ + /* FADT2->Reserved1 = 0; */ + + /* This field is set by the OEM to convey the preferred */ + /* power management profile to OSPM. It doesn't have any*/ + /* 0.71 equivalence. Since we don't know what kind of */ + /* 64-bit system this is, we will pick unspecified. */ + + FADT2->prefer_PM_profile = PM_UNSPECIFIED; + + + /* Port address of SMI command port */ + /* We shouldn't use this port because IA64 doesn't */ + /* have or use SMI. It has PMI. */ + + FADT2->smi_cmd = (u32)(FADT71->smi_cmd & 0xFFFFFFFF); + + + /* processor performance state control*/ + /* The value OSPM writes to the SMI_CMD register to assume */ + /* processor performance state control responsibility. */ + /* There isn't any equivalence in 0.71 */ + /* Again this should be meaningless for IA64 */ + /* FADT2->Pstate_cnt = 0; */ + + /* The 32-bit Power management and GPE registers are */ + /* not valid in IA-64 and we are not going to use them */ + /* so leaving them pre-zeroed. */ + + /* Support for the _CST object and C States change notification.*/ + /* This data item hasn't any 0.71 equivalence so leaving it zero.*/ + /* FADT2->Cst_cnt = 0; */ + + /* number of flush strides that need to be read */ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Flush_size = 0; */ + + /* Processor's memory cache line width, in bytes */ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Flush_stride = 0; */ + + /* Processor’s duty cycle index in processor's P_CNT reg*/ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Duty_offset = 0; */ + + /* Processor’s duty cycle value bit width in P_CNT register.*/ + /* No 0.71 equivalence. Leave pre-zeroed. */ + /* FADT2->Duty_width = 0; */ + + + /* Since there isn't any equivalence in 0.71 */ + /* and since Big_sur had to support legacy */ + + FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + + /* Copy to ACPI 2.0 64-BIT Extended Addresses */ + + FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl; + FADT2->Xdsdt = FADT71->dsdt; + + + /* Extract the address space IDs */ + + pm1_address_space = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE) >> 1); + pm2_address_space = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2); + pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3); + gpe0address_space = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE) >> 4); + gpe1_address_space = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE) >> 5); + + /* + * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures, + * in this order: + * + * PM 1_a Events + * PM 1_b Events + * PM 1_a Control + * PM 1_b Control + * PM 2 Control + * PM Timer Control + * GPE Block 0 + * GPE Block 1 + */ + + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len, FADT71->pm_tmr_blk, pm_timer_address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk, FADT71->gpe0blk_len, FADT71->gpe0blk, gpe0address_space); + ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk, FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space); + +#else + + /* ACPI 1.0 FACS */ + + + /* The BIOS stored FADT should agree with Revision 1.0 */ + + FADT1 = (FADT_DESCRIPTOR_REV1*) acpi_gbl_FADT; + + /* + * Copy the table header and the common part of the tables + * The 2.0 table is an extension of the 1.0 table, so the + * entire 1.0 table can be copied first, then expand some + * fields to 64 bits. + */ + + MEMCPY (FADT2, FADT1, sizeof (FADT_DESCRIPTOR_REV1)); + + + /* Convert table pointers to 64-bit fields */ + + FADT2->Xfirmware_ctrl = (UINT64) FADT1->firmware_ctrl; + FADT2->Xdsdt = (UINT64) FADT1->dsdt; + + /* System Interrupt Model isn't used in ACPI 2.0*/ + /* FADT2->Reserved1 = 0; */ + + /* This field is set by the OEM to convey the preferred */ + /* power management profile to OSPM. It doesn't have any*/ + /* 1.0 equivalence. Since we don't know what kind of */ + /* 32-bit system this is, we will pick unspecified. */ + + FADT2->prefer_PM_profile = PM_UNSPECIFIED; + + + /* Processor Performance State Control. This is the value */ + /* OSPM writes to the SMI_CMD register to assume processor */ + /* performance state control responsibility. There isn't */ + /* any equivalence in 1.0. So leave it zeroed. */ + + FADT2->pstate_cnt = 0; + + + /* Support for the _CST object and C States change notification.*/ + /* This data item hasn't any 1.0 equivalence so leaving it zero.*/ + + FADT2->cst_cnt = 0; + + + /* Since there isn't any equivalence in 1.0 and since it */ + /* is highly likely that a 1.0 system has legacy support. */ + + FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; + + + /* + * Convert the V1.0 Block addresses to V2.0 GAS structures + * in this order: + * + * PM 1_a Events + * PM 1_b Events + * PM 1_a Control + * PM 1_b Control + * PM 2 Control + * PM Timer Control + * GPE Block 0 + * GPE Block 1 + */ + + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len, FADT1->pm_tmr_blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk, FADT1->gpe0blk_len, FADT1->gpe0blk); + ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk, FADT1->gpe1_blk_len, FADT1->gpe1_blk); +#endif + } + + + /* + * Global FADT pointer will point to the common V2.0 FADT + */ + acpi_gbl_FADT = FADT2; + + + /* Free the original table */ + + table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT]; + acpi_tb_delete_single_table (table_desc); + + + /* Install the new table */ + + table_desc->pointer = (ACPI_TABLE_HEADER *) acpi_gbl_FADT; + table_desc->base_pointer = acpi_gbl_FADT; + table_desc->allocation = ACPI_MEM_ALLOCATED; + table_desc->length = sizeof (FADT_DESCRIPTOR_REV2); + + + /* Dump the FADT Header */ + + /* Dump the entire FADT */ + + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_convert_table_facs + * + * PARAMETERS: + * + * RETURN: + * + * DESCRIPTION: + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_build_common_facs ( + ACPI_TABLE_DESC *table_info) +{ + ACPI_COMMON_FACS *common_facs; + +#ifdef _IA64 + FACS_DESCRIPTOR_REV071 *FACS71; +#else + FACS_DESCRIPTOR_REV1 *FACS1; +#endif + + FACS_DESCRIPTOR_REV2 *FACS2; + + + /* Allocate a common FACS */ + + common_facs = acpi_cm_callocate (sizeof (ACPI_COMMON_FACS)); + if (!common_facs) { + return (AE_NO_MEMORY); + } + + + /* Copy fields to the new FACS */ + + if (acpi_gbl_RSDP->revision < 2) { +#ifdef _IA64 + /* 0.71 FACS */ + + FACS71 = (FACS_DESCRIPTOR_REV071 *) acpi_gbl_FACS; + + common_facs->global_lock = (u32 *) &(FACS71->global_lock); + common_facs->firmware_waking_vector = &FACS71->firmware_waking_vector; + common_facs->vector_width = 64; +#else + /* ACPI 1.0 FACS */ + + FACS1 = (FACS_DESCRIPTOR_REV1 *) acpi_gbl_FACS; + + common_facs->global_lock = &(FACS1->global_lock); + common_facs->firmware_waking_vector = (UINT64 *) &FACS1->firmware_waking_vector; + common_facs->vector_width = 32; + +#endif + } + + else { + /* ACPI 2.0 FACS */ + + FACS2 = (FACS_DESCRIPTOR_REV2 *) acpi_gbl_FACS; + + common_facs->global_lock = &(FACS2->global_lock); + common_facs->firmware_waking_vector = &FACS2->Xfirmware_waking_vector; + common_facs->vector_width = 64; + } + + + /* Set the global FACS pointer to point to the common FACS */ + + + acpi_gbl_FACS = common_facs; + + return (AE_OK); +} + + diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbget.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbget.c --- linux-2.4.0-test12/drivers/acpi/tables/tbget.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbget.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbget - ACPI Table get* routines - * $Revision: 22 $ + * $Revision: 39 $ * *****************************************************************************/ @@ -32,6 +32,7 @@ #define _COMPONENT TABLE_MANAGER MODULE_NAME ("tbget") +#define RSDP_CHECKSUM_LENGTH 20 /******************************************************************************* * @@ -127,7 +128,7 @@ ACPI_STATUS acpi_tb_get_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, ACPI_TABLE_HEADER *buffer_ptr, ACPI_TABLE_DESC *table_info) { @@ -239,9 +240,10 @@ MEMSET (&table_info, 0, sizeof (ACPI_TABLE_DESC)); - /* Get the table via the RSDT */ + /* Get the table via the XSDT */ - status = acpi_tb_get_table ((void *) acpi_gbl_RSDT->table_offset_entry[index], + status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) + acpi_gbl_XSDT->table_offset_entry[index], table_ptr, &table_info); /* Ignore a table that failed verification */ @@ -266,15 +268,25 @@ * determine if there are enough tables to continue. */ - acpi_tb_delete_single_table (&table_info); + acpi_tb_uninstall_table (&table_info); } } /* + * Convert the FADT to a common format. This allows earlier revisions of the + * table to coexist with newer versions, using common access code. + */ + status = acpi_tb_convert_table_fadt (); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* * Get the minimum set of ACPI tables, namely: * - * 1) FACP (via RSDT in loop above) + * 1) FADT (via RSDT in loop above) * 2) FACS * 3) DSDT * @@ -282,8 +294,8 @@ /* - * Get the FACS (must have the FACP first, from loop above) - * Acpi_tb_get_table_facs will fail if FACP pointer is not valid + * Get the FACS (must have the FADT first, from loop above) + * Acpi_tb_get_table_facs will fail if FADT pointer is not valid */ status = acpi_tb_get_table_facs (table_ptr, &table_info); @@ -291,6 +303,7 @@ return (status); } + /* Install the FACS */ status = acpi_tb_install_table (table_ptr, &table_info); @@ -298,10 +311,22 @@ return (status); } + /* + * Create the common FACS pointer table + * (Contains pointers to the original table) + */ + + status = acpi_tb_build_common_facs (&table_info); + if (ACPI_FAILURE (status)) { + return (status); + } + - /* Get the DSDT (We know that the FACP if valid now) */ + /* + * Get the DSDT (We know that the FADT is valid now) + */ - status = acpi_tb_get_table ((void *) acpi_gbl_FACP->dsdt, table_ptr, &table_info); + status = acpi_tb_get_table (acpi_gbl_FADT->Xdsdt, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return (status); } @@ -321,8 +346,264 @@ * Initialize the capabilities flags. * Assumes that platform supports ACPI_MODE since we have tables! */ - acpi_gbl_system_flags |= acpi_hw_get_mode_capabilities (); + + + /* Always delete the RSDP mapping, we are done with it */ + + acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP); + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_verify_rsdp + * + * PARAMETERS: Number_of_tables - Where the table count is placed + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_verify_rsdp ( + ACPI_PHYSICAL_ADDRESS rsdp_physical_address) +{ + ACPI_TABLE_DESC table_info; + ACPI_STATUS status; + u8 *table_ptr; + + + /* + * Obtain access to the RSDP structure + */ + status = acpi_os_map_memory (rsdp_physical_address, + sizeof (RSDP_DESCRIPTOR), + (void **) &table_ptr); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* + * The signature and checksum must both be correct + */ + if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { + /* Nope, BAD Signature */ + + status = AE_BAD_SIGNATURE; + goto cleanup; + } + + if (acpi_tb_checksum (table_ptr, RSDP_CHECKSUM_LENGTH) != 0) { + /* Nope, BAD Checksum */ + + status = AE_BAD_CHECKSUM; + goto cleanup; + } + + /* TBD: Check extended checksum if table version >= 2 */ + + /* The RSDP supplied is OK */ + + table_info.pointer = (ACPI_TABLE_HEADER *) table_ptr; + table_info.length = sizeof (RSDP_DESCRIPTOR); + table_info.allocation = ACPI_MEM_MAPPED; + table_info.base_pointer = table_ptr; + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + + /* Save the RSDP in a global for easy access */ + + acpi_gbl_RSDP = (RSDP_DESCRIPTOR *) table_info.pointer; + return (status); + + + /* Error exit */ +cleanup: + + acpi_os_unmap_memory (table_ptr, sizeof (RSDP_DESCRIPTOR)); + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_get_table_rsdt + * + * PARAMETERS: Number_of_tables - Where the table count is placed + * + * RETURN: Status + * + * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_get_table_rsdt ( + u32 *number_of_tables) +{ + ACPI_TABLE_DESC table_info; + ACPI_STATUS status = AE_OK; + ACPI_PHYSICAL_ADDRESS physical_address; + u32 signature_length; + char *table_signature; + + + /* + * Get the RSDT from the RSDP + */ + + /* + * For RSDP revision 0 or 1, we use the RSDT. + * For RSDP revision 2 (and above), we use the XSDT + */ + if (acpi_gbl_RSDP->revision < 2) { +#ifdef _IA64 + /* 0.71 RSDP has 64bit Rsdt address field */ + physical_address = ((RSDP_DESCRIPTOR_REV071 *)acpi_gbl_RSDP)->rsdt_physical_address; +#else + physical_address = acpi_gbl_RSDP->rsdt_physical_address; +#endif + table_signature = RSDT_SIG; + signature_length = sizeof (RSDT_SIG) -1; + } + else { + physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->xsdt_physical_address; + table_signature = XSDT_SIG; + signature_length = sizeof (XSDT_SIG) -1; + } + + + /* Get the RSDT/XSDT */ + + status = acpi_tb_get_table (physical_address, NULL, &table_info); + if (ACPI_FAILURE (status)) { + return (status); + } + + + /* Check the RSDT or XSDT signature */ + + if (STRNCMP ((char *) table_info.pointer, table_signature, + signature_length)) + { + /* Invalid RSDT or XSDT signature */ + + REPORT_ERROR (("Invalid signature where RSDP indicates %s should be located\n", + table_signature)); + + return (status); + } + + + /* Valid RSDT signature, verify the checksum */ + + status = acpi_tb_verify_table_checksum (table_info.pointer); + + + /* Convert and/or copy to an XSDT structure */ + + status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables); + if (ACPI_FAILURE (status)) { + return (status); + } + + /* Save the table pointers and allocation info */ + + status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info); + if (ACPI_FAILURE (status)) { + return (status); + } + + acpi_gbl_XSDT = (XSDT_DESCRIPTOR *) table_info.pointer; + + return (status); +} + + +/****************************************************************************** + * + * FUNCTION: Acpi_tb_get_table_facs + * + * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from + * buffer rather than searching memory + * *Table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Returns a pointer to the FACS as defined in FADT. This + * function assumes the global variable FADT has been + * correctly initialized. The value of FADT->Firmware_ctrl + * into a far pointer which is returned. + * + *****************************************************************************/ + +ACPI_STATUS +acpi_tb_get_table_facs ( + ACPI_TABLE_HEADER *buffer_ptr, + ACPI_TABLE_DESC *table_info) +{ + void *table_ptr = NULL; + u32 size; + u8 allocation; + ACPI_STATUS status = AE_OK; + + + /* Must have a valid FADT pointer */ + + if (!acpi_gbl_FADT) { + return (AE_NO_ACPI_TABLES); + } + + size = sizeof (FACS_DESCRIPTOR); + if (buffer_ptr) { + /* + * Getting table from a file -- allocate a buffer and + * read the table. + */ + table_ptr = acpi_cm_allocate (size); + if(!table_ptr) { + return (AE_NO_MEMORY); + } + + MEMCPY (table_ptr, buffer_ptr, size); + + /* Save allocation type */ + + allocation = ACPI_MEM_ALLOCATED; + } + + else { + /* Just map the physical memory to our address space */ + + status = acpi_tb_map_acpi_table (acpi_gbl_FADT->Xfirmware_ctrl, + &size, &table_ptr); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Save allocation type */ + + allocation = ACPI_MEM_MAPPED; + } + + + /* Return values */ + + table_info->pointer = table_ptr; + table_info->length = size; + table_info->allocation = allocation; + table_info->base_pointer = table_ptr; return (status); } diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbinstal.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbinstal.c --- linux-2.4.0-test12/drivers/acpi/tables/tbinstal.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbinstal.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbinstal - ACPI table installation and removal - * $Revision: 29 $ + * $Revision: 33 $ * *****************************************************************************/ @@ -307,7 +307,7 @@ * Memory can either be mapped or allocated */ - for (type = 0; type < ACPI_TABLE_MAX; type++) { + for (type = 0; type < NUM_ACPI_TABLES; type++) { acpi_tb_delete_acpi_table (type); } @@ -352,35 +352,24 @@ acpi_gbl_RSDP = NULL; break; - case ACPI_TABLE_APIC: - acpi_gbl_APIC = NULL; - break; - case ACPI_TABLE_DSDT: acpi_gbl_DSDT = NULL; break; - case ACPI_TABLE_FACP: - acpi_gbl_FACP = NULL; + case ACPI_TABLE_FADT: + acpi_gbl_FADT = NULL; break; case ACPI_TABLE_FACS: acpi_gbl_FACS = NULL; break; - case ACPI_TABLE_PSDT: - break; - - case ACPI_TABLE_RSDT: - acpi_gbl_RSDT = NULL; + case ACPI_TABLE_XSDT: + acpi_gbl_XSDT = NULL; break; case ACPI_TABLE_SSDT: - break; - - case ACPI_TABLE_SBST: - acpi_gbl_SBST = NULL; - + case ACPI_TABLE_PSDT: default: break; } @@ -424,7 +413,7 @@ */ for (i = 0; i < count; i++) { - table_desc = acpi_tb_delete_single_table (table_desc); + table_desc = acpi_tb_uninstall_table (table_desc); } return; @@ -439,37 +428,20 @@ * * RETURN: None. * - * DESCRIPTION: Free the memory associated with an internal ACPI table that - * is either installed or has never been installed. - * Table mutex should be locked. + * DESCRIPTION: Low-level free for a single ACPI table. Handles cases where + * the table was allocated a buffer or was mapped. * ******************************************************************************/ -ACPI_TABLE_DESC * +void acpi_tb_delete_single_table ( ACPI_TABLE_DESC *table_desc) { - ACPI_TABLE_DESC *next_desc; - if (!table_desc) { - return (NULL); - } - - - /* Unlink the descriptor */ - - if (table_desc->prev) { - table_desc->prev->next = table_desc->next; - } - - if (table_desc->next) { - table_desc->next->prev = table_desc->prev; + return; } - - /* Free the memory allocated for the table itself */ - if (table_desc->pointer) { /* Valid table, determine type of memory allocation */ @@ -477,7 +449,6 @@ { case ACPI_MEM_NOT_ALLOCATED: - break; @@ -493,10 +464,52 @@ break; } } +} - /* Free the table descriptor (Don't delete the list head, tho) */ +/******************************************************************************* + * + * FUNCTION: Acpi_tb_uninstall_table + * + * PARAMETERS: Table_info - A table info struct + * + * RETURN: None. + * + * DESCRIPTION: Free the memory associated with an internal ACPI table that + * is either installed or has never been installed. + * Table mutex should be locked. + * + ******************************************************************************/ +ACPI_TABLE_DESC * +acpi_tb_uninstall_table ( + ACPI_TABLE_DESC *table_desc) +{ + ACPI_TABLE_DESC *next_desc; + + + if (!table_desc) { + return (NULL); + } + + + /* Unlink the descriptor */ + + if (table_desc->prev) { + table_desc->prev->next = table_desc->next; + } + + if (table_desc->next) { + table_desc->next->prev = table_desc->prev; + } + + + /* Free the memory allocated for the table itself */ + + acpi_tb_delete_single_table (table_desc); + + + /* Free the table descriptor (Don't delete the list head, tho) */ if ((table_desc->prev) == (table_desc->next)) { diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbtable.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbtable.c --- linux-2.4.0-test12/drivers/acpi/tables/tbtable.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbtable.c Wed Dec 31 16:00:00 1969 @@ -1,392 +0,0 @@ -/****************************************************************************** - * - * Module Name: tbtable - ACPI tables: FACP, FACS, and RSDP utilities - * $Revision: 24 $ - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 R. Byron Moore - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "acpi.h" -#include "achware.h" -#include "actables.h" - - -#define _COMPONENT TABLE_MANAGER - MODULE_NAME ("tbtable") - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_get_table_rsdt - * - * PARAMETERS: Number_of_tables - Where the table count is placed - * - * RETURN: Status - * - * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table) - * - ******************************************************************************/ - -ACPI_STATUS -acpi_tb_get_table_rsdt ( - u32 *number_of_tables) -{ - ACPI_STATUS status = AE_OK; - ACPI_TABLE_DESC table_info; - - - /* Get the RSDP */ - - status = acpi_tb_find_rsdp (&table_info); - if (ACPI_FAILURE (status)) { - REPORT_WARNING ("RSDP structure not found"); - return (AE_NO_ACPI_TABLES); - } - - /* Save the table pointers and allocation info */ - - status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info); - if (ACPI_FAILURE (status)) { - return (status); - } - - acpi_gbl_RSDP = (ROOT_SYSTEM_DESCRIPTOR_POINTER *) table_info.pointer; - - - /* - * RSDP structure was found; Now get the RSDT - */ - - status = acpi_tb_get_table ((void *) acpi_gbl_RSDP->rsdt_physical_address, NULL, - &table_info); - if (ACPI_FAILURE (status)) { - if (status == AE_BAD_SIGNATURE) { - /* Invalid RSDT signature */ - - REPORT_ERROR ("Invalid signature where RSDP indicates RSDT should be located"); - - } - REPORT_ERROR ("Unable to locate RSDT"); - - return (status); - } - - - /* Always delete the RSDP mapping */ - - acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP); - - /* Save the table pointers and allocation info */ - - status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDT, &table_info); - if (ACPI_FAILURE (status)) { - return (status); - } - - acpi_gbl_RSDT = (ROOT_SYSTEM_DESCRIPTION_TABLE *) table_info.pointer; - - - /* Valid RSDT signature, verify the checksum */ - - status = acpi_tb_verify_table_checksum ((ACPI_TABLE_HEADER *) acpi_gbl_RSDT); - - /* - * Determine the number of tables pointed to by the RSDT. - * This is defined by the ACPI Specification to be the number of - * pointers contained within the RSDT. The size of the pointers - * is architecture-dependent. - */ - - *number_of_tables = ((acpi_gbl_RSDT->header.length - - sizeof (ACPI_TABLE_HEADER)) / sizeof (void *)); - - - return (status); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_scan_memory_for_rsdp - * - * PARAMETERS: Start_address - Starting pointer for search - * Length - Maximum length to search - * - * RETURN: Pointer to the RSDP if found, otherwise NULL. - * - * DESCRIPTION: Search a block of memory for the RSDP signature - * - ******************************************************************************/ - -u8 * -acpi_tb_scan_memory_for_rsdp ( - u8 *start_address, - u32 length) -{ - u32 offset; - u8 *mem_rover; - - - /* Search from given start addr for the requested length */ - - for (offset = 0, mem_rover = start_address; - offset < length; - offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) - { - - /* The signature and checksum must both be correct */ - - if (STRNCMP ((NATIVE_CHAR *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && - acpi_tb_checksum (mem_rover, - sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)) == 0) - { - /* If so, we have found the RSDP */ - - return (mem_rover); - } - } - - /* Searched entire block, no RSDP was found */ - - return (NULL); -} - - -/******************************************************************************* - * - * FUNCTION: Acpi_tb_find_rsdp - * - * PARAMETERS: *Buffer_ptr - If == NULL, read data from buffer - * rather than searching memory - * *Table_info - Where the table info is returned - * - * RETURN: Status - * - * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. - * - * NOTE: The RSDP must be either in the first 1_k of the Extended - * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section - * 5.2.2; assertion #421). - * - ******************************************************************************/ - -ACPI_STATUS -acpi_tb_find_rsdp ( - ACPI_TABLE_DESC *table_info) -{ - u8 *table_ptr; - u8 *mem_rover; - ACPI_STATUS status = AE_OK; - - if (acpi_gbl_acpi_init_data.RSDP_physical_address) { - /* - * RSDP address was supplied as part of the initialization data - */ - - status = acpi_os_map_memory(acpi_gbl_acpi_init_data.RSDP_physical_address, - sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER), - (void **)&table_ptr); - - if (ACPI_FAILURE (status)) { - return (status); - } - - if (!table_ptr) { - return (AE_NO_MEMORY); - } - - /* - * The signature and checksum must both be correct - */ - - if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { - /* Nope, BAD Signature */ - acpi_os_unmap_memory (table_ptr, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)); - return (AE_BAD_SIGNATURE); - } - - /* The signature and checksum must both be correct */ - - if (acpi_tb_checksum (table_ptr, - sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)) != 0) - { - /* Nope, BAD Checksum */ - acpi_os_unmap_memory (table_ptr, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)); - return (AE_BAD_CHECKSUM); - } - - /* RSDP supplied is OK */ - /* If so, we have found the RSDP */ - - table_info->pointer = (ACPI_TABLE_HEADER *) table_ptr; - table_info->length = sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER); - table_info->allocation = ACPI_MEM_MAPPED; - table_info->base_pointer = table_ptr; - - return (AE_OK); - } - - /* - * Search memory for RSDP. First map low physical memory. - */ - - status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE, - (void **)&table_ptr); - - if (ACPI_FAILURE (status)) { - return (status); - } - - /* - * 1) Search EBDA (low memory) paragraphs - */ - - if (NULL != (mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, - LO_RSDP_WINDOW_SIZE))) - { - /* Found it, return pointer and don't delete the mapping */ - - table_info->pointer = (ACPI_TABLE_HEADER *) mem_rover; - table_info->length = LO_RSDP_WINDOW_SIZE; - table_info->allocation = ACPI_MEM_MAPPED; - table_info->base_pointer = table_ptr; - - return (AE_OK); - } - - /* This mapping is no longer needed */ - - acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE); - - - /* - * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h - */ - - status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE, - (void **)&table_ptr); - - if (ACPI_FAILURE (status)) { - return (status); - } - - if (NULL != (mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, - HI_RSDP_WINDOW_SIZE))) - { - /* Found it, return pointer and don't delete the mapping */ - - table_info->pointer = (ACPI_TABLE_HEADER *) mem_rover; - table_info->length = HI_RSDP_WINDOW_SIZE; - table_info->allocation = ACPI_MEM_MAPPED; - table_info->base_pointer = table_ptr; - - return (AE_OK); - } - - /* This mapping is no longer needed */ - - acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE); - - - /* RSDP signature was not found */ - - return (AE_NOT_FOUND); -} - - -/****************************************************************************** - * - * FUNCTION: Acpi_tb_get_table_facs - * - * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from - * buffer rather than searching memory - * *Table_info - Where the table info is returned - * - * RETURN: Status - * - * DESCRIPTION: Returns a pointer to the FACS as defined in FACP. This - * function assumes the global variable FACP has been - * correctly initialized. The value of FACP->Firmware_ctrl - * into a far pointer which is returned. - * - *****************************************************************************/ - -ACPI_STATUS -acpi_tb_get_table_facs ( - ACPI_TABLE_HEADER *buffer_ptr, - ACPI_TABLE_DESC *table_info) -{ - void *table_ptr = NULL; - u32 size; - u8 allocation; - ACPI_STATUS status = AE_OK; - - - /* Must have a valid FACP pointer */ - - if (!acpi_gbl_FACP) { - return (AE_NO_ACPI_TABLES); - } - - size = sizeof (FIRMWARE_ACPI_CONTROL_STRUCTURE); - if (buffer_ptr) { - /* - * Getting table from a file -- allocate a buffer and - * read the table. - */ - table_ptr = acpi_cm_allocate (size); - if(!table_ptr) { - return (AE_NO_MEMORY); - } - - MEMCPY (table_ptr, buffer_ptr, size); - - /* Save allocation type */ - - allocation = ACPI_MEM_ALLOCATED; - } - - else { - /* Just map the physical memory to our address space */ - - status = acpi_tb_map_acpi_table ((void *) acpi_gbl_FACP->firmware_ctrl, - &size, &table_ptr); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Save allocation type */ - - allocation = ACPI_MEM_MAPPED; - } - - - /* Return values */ - - table_info->pointer = table_ptr; - table_info->length = size; - table_info->allocation = allocation; - table_info->base_pointer = table_ptr; - - return (status); -} - diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbutils.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbutils.c --- linux-2.4.0-test12/drivers/acpi/tables/tbutils.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbutils.c Wed Nov 15 16:25:04 2000 @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbutils - Table manipulation utilities - * $Revision: 26 $ + * $Revision: 30 $ * *****************************************************************************/ @@ -107,7 +107,9 @@ /* Check for a pointer within the DSDT */ - if (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT)) { + if ((acpi_gbl_DSDT) && + (IS_IN_ACPI_TABLE (where, acpi_gbl_DSDT))) + { return (TRUE); } @@ -186,7 +188,7 @@ MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature); if (!acpi_cm_valid_acpi_name (signature)) { - REPORT_WARNING ("Invalid table signature found"); + REPORT_WARNING (("Invalid table signature found\n")); return (AE_BAD_SIGNATURE); } @@ -194,7 +196,7 @@ /* Validate the table length */ if (table_header->length < sizeof (ACPI_TABLE_HEADER)) { - REPORT_WARNING ("Invalid table header length found"); + REPORT_WARNING (("Invalid table header length found\n")); return (AE_BAD_HEADER); } @@ -220,7 +222,7 @@ ACPI_STATUS acpi_tb_map_acpi_table ( - void *physical_address, + ACPI_PHYSICAL_ADDRESS physical_address, u32 *size, void **logical_address) { @@ -294,18 +296,20 @@ acpi_tb_verify_table_checksum ( ACPI_TABLE_HEADER *table_header) { - u8 check_sum; + u8 checksum; ACPI_STATUS status = AE_OK; /* Compute the checksum on the table */ - check_sum = acpi_tb_checksum (table_header, table_header->length); + checksum = acpi_tb_checksum (table_header, table_header->length); /* Return the appropriate exception */ - if (check_sum) { - REPORT_ERROR ("Invalid ACPI table checksum"); + if (checksum) { + REPORT_WARNING (("Invalid checksum (%X) in table %4.4s\n", + checksum, &table_header->signature)); + status = AE_BAD_CHECKSUM; } diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbxface.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbxface.c --- linux-2.4.0-test12/drivers/acpi/tables/tbxface.c Fri Sep 15 14:30:30 2000 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbxface.c Wed Nov 15 16:25:04 2000 @@ -2,7 +2,7 @@ * * Module Name: tbxface - Public interfaces to the ACPI subsystem * ACPI table oriented interfaces - * $Revision: 24 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -37,43 +37,69 @@ /******************************************************************************* * - * FUNCTION: Acpi_load_firmware_tables + * FUNCTION: Acpi_load_tables * * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: This function is called to load the ACPI tables from BIOS + * DESCRIPTION: This function is called to load the ACPI tables from the + * provided RSDT * ******************************************************************************/ ACPI_STATUS -acpi_load_firmware_tables (void) +acpi_load_tables ( + ACPI_PHYSICAL_ADDRESS rsdp_physical_address) { ACPI_STATUS status = AE_OK; u32 number_of_tables = 0; - /* Get the RSDT first */ + /* Map and validate the RSDP */ - status = acpi_tb_get_table_rsdt (&number_of_tables); + status = acpi_tb_verify_rsdp (rsdp_physical_address); if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: RSDP Failed validation: %s\n", + acpi_cm_format_exception (status))); goto error_exit; } + /* Get the RSDT via the RSDP */ + + status = acpi_tb_get_table_rsdt (&number_of_tables); + if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %s\n", + acpi_cm_format_exception (status))); + goto error_exit; + } /* Now get the rest of the tables */ status = acpi_tb_get_all_tables (number_of_tables, NULL); if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n", + acpi_cm_format_exception (status))); goto error_exit; } + /* Load the namespace from the tables */ + + status = acpi_ns_load_namespace (); + if (ACPI_FAILURE (status)) { + REPORT_ERROR (("Acpi_load_tables: Could not load namespace: %s\n", + acpi_cm_format_exception (status))); + goto error_exit; + } + return (AE_OK); error_exit: + REPORT_ERROR (("Acpi_load_tables: Could not load tables: %s\n", + acpi_cm_format_exception (status))); + return (status); } @@ -110,7 +136,7 @@ /* Copy the table to a local buffer */ - status = acpi_tb_get_table (NULL, table_ptr, &table_info); + status = acpi_tb_get_table (0, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return (status); } @@ -119,9 +145,22 @@ status = acpi_tb_install_table (NULL, &table_info); if (ACPI_FAILURE (status)) { - /* TBD: [Errors] must free table allocated by Acpi_tb_get_table */ + /* Free table allocated by Acpi_tb_get_table */ + + acpi_tb_delete_single_table (&table_info); + return (status); + } + + + status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); + if (ACPI_FAILURE (status)) { + /* Uninstall table and free the buffer */ + + acpi_tb_uninstall_table (table_info.installed_desc); + return (status); } + return (status); } @@ -289,12 +328,11 @@ /* - * Must have a buffer + * If we have a buffer, we must have a length too */ if ((instance == 0) || (!ret_buffer) || - (!ret_buffer->pointer) || - (!ret_buffer->length)) + ((!ret_buffer->pointer) && (ret_buffer->length))) { return (AE_BAD_PARAMETER); } @@ -331,7 +369,7 @@ /* * RSD PTR is the only "table" without a header */ - ret_buf_len = sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER); + ret_buf_len = sizeof (RSDP_DESCRIPTOR); } else { ret_buf_len = tbl_ptr->length; diff -urN linux-2.4.0-test12/drivers/acpi/tables/tbxfroot.c linux-2.4.0-test12-lia/drivers/acpi/tables/tbxfroot.c --- linux-2.4.0-test12/drivers/acpi/tables/tbxfroot.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/acpi/tables/tbxfroot.c Wed Nov 15 16:25:04 2000 @@ -0,0 +1,214 @@ +/****************************************************************************** + * + * Module Name: tbxfroot - Find the root ACPI table (RSDT) + * $Revision: 33 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 R. Byron Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "acpi.h" +#include "achware.h" +#include "actables.h" + + +#define _COMPONENT TABLE_MANAGER + MODULE_NAME ("tbxfroot") + +#define RSDP_CHECKSUM_LENGTH 20 + + +/******************************************************************************* + * + * FUNCTION: Acpi_find_root_pointer + * + * PARAMETERS: **Rsdp_physical_address - Where to place the RSDP address + * + * RETURN: Status, Physical address of the RSDP + * + * DESCRIPTION: Find the RSDP + * + ******************************************************************************/ + +ACPI_STATUS +acpi_find_root_pointer ( + ACPI_PHYSICAL_ADDRESS *rsdp_physical_address) +{ + ACPI_TABLE_DESC table_info; + ACPI_STATUS status; + + + /* Get the RSDP */ + + status = acpi_tb_find_rsdp (&table_info); + if (ACPI_FAILURE (status)) { + return (AE_NO_ACPI_TABLES); + } + + *rsdp_physical_address = table_info.physical_address; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_scan_memory_for_rsdp + * + * PARAMETERS: Start_address - Starting pointer for search + * Length - Maximum length to search + * + * RETURN: Pointer to the RSDP if found, otherwise NULL. + * + * DESCRIPTION: Search a block of memory for the RSDP signature + * + ******************************************************************************/ + +u8 * +acpi_tb_scan_memory_for_rsdp ( + u8 *start_address, + u32 length) +{ + u32 offset; + u8 *mem_rover; + + + /* Search from given start addr for the requested length */ + + for (offset = 0, mem_rover = start_address; + offset < length; + offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) + { + + /* The signature and checksum must both be correct */ + + if (STRNCMP ((NATIVE_CHAR *) mem_rover, + RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && + acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0) + { + /* If so, we have found the RSDP */ + + return (mem_rover); + } + } + + /* Searched entire block, no RSDP was found */ + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_tb_find_rsdp + * + * PARAMETERS: *Buffer_ptr - If == NULL, read data from buffer + * rather than searching memory + * *Table_info - Where the table info is returned + * + * RETURN: Status + * + * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor + * pointer structure. If it is found, set *RSDP to point to it. + * + * NOTE: The RSDP must be either in the first 1_k of the Extended + * BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section + * 5.2.2; assertion #421). + * + ******************************************************************************/ + +ACPI_STATUS +acpi_tb_find_rsdp ( + ACPI_TABLE_DESC *table_info) +{ + u8 *table_ptr; + u8 *mem_rover; + UINT64 phys_addr; + ACPI_STATUS status = AE_OK; + + + /* + * Search memory for RSDP. First map low physical memory. + */ + + status = acpi_os_map_memory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE, + (void **)&table_ptr); + + if (ACPI_FAILURE (status)) { + return (status); + } + + /* + * 1) Search EBDA (low memory) paragraphs + */ + + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, LO_RSDP_WINDOW_SIZE); + + /* This mapping is no longer needed */ + + acpi_os_unmap_memory (table_ptr, LO_RSDP_WINDOW_SIZE); + + if (mem_rover) { + /* Found it, return the physical address */ + + phys_addr = LO_RSDP_WINDOW_BASE; + phys_addr += (mem_rover - table_ptr); + + table_info->physical_address = phys_addr; + + return (AE_OK); + } + + + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h + */ + + status = acpi_os_map_memory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE, + (void **)&table_ptr); + + if (ACPI_FAILURE (status)) { + return (status); + } + + mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, HI_RSDP_WINDOW_SIZE); + + /* This mapping is no longer needed */ + + acpi_os_unmap_memory (table_ptr, HI_RSDP_WINDOW_SIZE); + + if (mem_rover) { + /* Found it, return the physical address */ + + phys_addr = HI_RSDP_WINDOW_BASE; + phys_addr += (mem_rover - table_ptr); + + table_info->physical_address = phys_addr; + + return (AE_OK); + } + + + /* RSDP signature was not found */ + + return (AE_NOT_FOUND); +} + + diff -urN linux-2.4.0-test12/drivers/char/Makefile linux-2.4.0-test12-lia/drivers/char/Makefile --- linux-2.4.0-test12/drivers/char/Makefile Wed Dec 13 17:29:35 2000 +++ linux-2.4.0-test12-lia/drivers/char/Makefile Wed Dec 13 17:31:39 2000 @@ -112,6 +112,7 @@ obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o +obj-$(CONFIG_SIM_SERIAL) += simserial.o obj-$(CONFIG_ROCKETPORT) += rocket.o obj-$(CONFIG_MOXA_SMARTIO) += mxser.o obj-$(CONFIG_MOXA_INTELLIO) += moxa.o diff -urN linux-2.4.0-test12/drivers/char/drm/vm.c linux-2.4.0-test12-lia/drivers/char/drm/vm.c --- linux-2.4.0-test12/drivers/char/drm/vm.c Sun Oct 1 20:00:00 2000 +++ linux-2.4.0-test12-lia/drivers/char/drm/vm.c Mon Oct 30 22:48:30 2000 @@ -272,6 +272,7 @@ drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; drm_map_t *map = NULL; + unsigned long off; int i; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", @@ -288,7 +289,16 @@ bit longer. */ for (i = 0; i < dev->map_count; i++) { map = dev->maplist[i]; - if (map->offset == VM_OFFSET(vma)) break; + off = map->offset ^ VM_OFFSET(vma); +#ifdef __ia64__ + /* + * Ignore region bits, makes IA32 processes happier + * XXX This is a hack... + */ + off &= ~0xe000000000000000; +#endif // __ia64__ + if (off == 0) + break; } if (i >= dev->map_count) return -EINVAL; diff -urN linux-2.4.0-test12/drivers/char/mem.c linux-2.4.0-test12-lia/drivers/char/mem.c --- linux-2.4.0-test12/drivers/char/mem.c Wed Dec 6 18:32:38 2000 +++ linux-2.4.0-test12-lia/drivers/char/mem.c Wed Dec 6 18:36:46 2000 @@ -198,8 +198,12 @@ * through a file pointer that was marked O_SYNC will be * done non-cached. */ - if (noncached_address(offset) || (file->f_flags & O_SYNC)) + if (noncached_address(offset) || (file->f_flags & O_SYNC) + || vma->vm_flags & VM_NONCACHED) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (vma->vm_flags & VM_WRITECOMBINED) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); /* * Don't dump addresses that are not real memory to a core file. diff -urN linux-2.4.0-test12/drivers/char/simserial.c linux-2.4.0-test12-lia/drivers/char/simserial.c --- linux-2.4.0-test12/drivers/char/simserial.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/char/simserial.c Wed Nov 1 23:18:55 2000 @@ -0,0 +1,1095 @@ +/* + * Simulated Serial Driver (fake serial) + * + * This driver is mostly used for bringup purposes and will go away. + * It has a strong dependency on the system console. All outputs + * are rerouted to the same facility as the one used by printk which, in our + * case means sys_sim.c console (goes via the simulator). The code hereafter + * is completely leveraged from the serial.c driver. + * + * Copyright (C) 1999-2000 Hewlett-Packard Co + * Copyright (C) 1999 Stephane Eranian + * Copyright (C) 2000 David Mosberger-Tang + * + * 02/04/00 D. Mosberger Merged in serial.c bug fixes in rs_close(). + * 02/25/00 D. Mosberger Synced up with 2.3.99pre-5 version of serial.c. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef SIMSERIAL_DEBUG /* define this to get some debug information */ + +#define KEYBOARD_INTR 3 /* must match with simulator! */ + +#define NR_PORTS 1 /* only one port for now */ +#define SERIAL_INLINE 1 + +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) + +#define SSC_GETCHAR 21 + +extern long ia64_ssc (long, long, long, long, int); +extern void ia64_ssc_connect_irq (long intr, long irq); + +static char *serial_name = "SimSerial driver"; +static char *serial_version = "0.6"; + +/* + * This has been extracted from asm/serial.h. We need one eventually but + * I don't know exactly what we're going to put in it so just fake one + * for now. + */ +#define BASE_BAUD ( 1843200 / 16 ) + +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + +/* + * Most of the values here are meaningless to this particular driver. + * However some values must be preserved for the code (leveraged from serial.c + * to work correctly). + * port must not be 0 + * type must not be UNKNOWN + * So I picked arbitrary (guess from where?) values instead + */ +static struct serial_state rs_table[NR_PORTS]={ + /* UART CLK PORT IRQ FLAGS */ + { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 } /* ttyS0 */ +}; + +/* + * Just for the fun of it ! + */ +static struct serial_uart_config uart_config[] = { + { "unknown", 1, 0 }, + { "8250", 1, 0 }, + { "16450", 1, 0 }, + { "16550", 1, 0 }, + { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, + { "cirrus", 1, 0 }, + { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH }, + { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | + UART_STARTECH }, + { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO}, + { 0, 0} +}; + +static struct tty_driver serial_driver, callout_driver; +static int serial_refcount; + +static struct async_struct *IRQ_ports[NR_IRQS]; +static struct tty_struct *serial_table[NR_PORTS]; +static struct termios *serial_termios[NR_PORTS]; +static struct termios *serial_termios_locked[NR_PORTS]; + +static struct console *console; + +static unsigned char *tmp_buf; +static DECLARE_MUTEX(tmp_buf_sem); + +extern struct console *console_drivers; /* from kernel/printk.c */ + +/* + * ------------------------------------------------------------ + * rs_stop() and rs_start() + * + * This routines are called before setting or resetting tty->stopped. + * They enable or disable transmitter interrupts, as necessary. + * ------------------------------------------------------------ + */ +static void rs_stop(struct tty_struct *tty) +{ +#ifdef SIMSERIAL_DEBUG + printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", + tty->stopped, tty->hw_stopped, tty->flow_stopped); +#endif + +} + +static void rs_start(struct tty_struct *tty) +{ +#if SIMSERIAL_DEBUG + printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n", + tty->stopped, tty->hw_stopped, tty->flow_stopped); +#endif +} + +static void receive_chars(struct tty_struct *tty) +{ + unsigned char ch; + static unsigned char seen_esc = 0; + + while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) { + if ( ch == 27 && seen_esc == 0 ) { + seen_esc = 1; + continue; + } else { + if ( seen_esc==1 && ch == 'O' ) { + seen_esc = 2; + continue; + } else if ( seen_esc == 2 ) { + if ( ch == 'P' ) show_state(); /* F1 key */ + if ( ch == 'Q' ) show_buffers(); /* F2 key */ + seen_esc = 0; + continue; + } + } + seen_esc = 0; + if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; + + *tty->flip.char_buf_ptr = ch; + + *tty->flip.flag_buf_ptr = 0; + + tty->flip.flag_buf_ptr++; + tty->flip.char_buf_ptr++; + tty->flip.count++; + } + tty_flip_buffer_push(tty); +} + +/* + * This is the serial driver's interrupt routine for a single port + */ +static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) +{ + struct async_struct * info; + + /* + * I don't know exactly why they don't use the dev_id opaque data + * pointer instead of this extra lookup table + */ + info = IRQ_ports[irq]; + if (!info || !info->tty) { + printk("simrs_interrupt_single: info|tty=0 info=%p problem\n", info); + return; + } + /* + * pretty simple in our case, because we only get interrupts + * on inbound traffic + */ + receive_chars(info->tty); +} + +/* + * ------------------------------------------------------------------- + * Here ends the serial interrupt routines. + * ------------------------------------------------------------------- + */ + +#if 0 +/* + * not really used in our situation so keep them commented out for now + */ +static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */ +static void do_serial_bh(void) +{ + run_task_queue(&tq_serial); + printk("do_serial_bh: called\n"); +} +#endif + +static void do_softint(void *private_) +{ + printk("simserial: do_softint called\n"); +} + +static void rs_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (!tty || !info->xmit.buf) return; + + save_flags(flags); cli(); + if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) { + restore_flags(flags); + return; + } + info->xmit.buf[info->xmit.head] = ch; + info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); + restore_flags(flags); +} + +static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) +{ + int count; + unsigned long flags; + + save_flags(flags); cli(); + + if (info->x_char) { + char c = info->x_char; + + console->write(console, &c, 1); + + info->state->icount.tx++; + info->x_char = 0; + + goto out; + } + + if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) { +#ifdef SIMSERIAL_DEBUG + printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", + info->xmit.head, info->xmit.tail, info->tty->stopped); +#endif + goto out; + } + /* + * We removed the loop and try to do it in to chunks. We need + * 2 operations maximum because it's a ring buffer. + * + * First from current to tail if possible. + * Then from the beginning of the buffer until necessary + */ + + count = MIN(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE), + SERIAL_XMIT_SIZE - info->xmit.tail); + console->write(console, info->xmit.buf+info->xmit.tail, count); + + info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1); + + /* + * We have more at the beginning of the buffer + */ + count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (count) { + console->write(console, info->xmit.buf, count); + info->xmit.tail += count; + } +out: + restore_flags(flags); +} + +static void rs_flush_chars(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped || + !info->xmit.buf) + return; + + transmit_chars(info, NULL); +} + + +static int rs_write(struct tty_struct * tty, int from_user, + const unsigned char *buf, int count) +{ + int c, ret = 0; + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + if (!tty || !info->xmit.buf || !tmp_buf) return 0; + + save_flags(flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + int c1; + c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (c1 < c) + c = c1; + memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + up(&tmp_buf_sem); + } else { + cli(); + while (1) { + c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) { + break; + } + memcpy(info->xmit.buf + info->xmit.head, buf, c); + info->xmit.head = ((info->xmit.head + c) & + (SERIAL_XMIT_SIZE-1)); + buf += c; + count -= c; + ret += c; + } + restore_flags(flags); + } + /* + * Hey, we transmit directly from here in our case + */ + if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) + && !tty->stopped && !tty->hw_stopped) { + transmit_chars(info, NULL); + } + return ret; +} + +static int rs_write_room(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static int rs_chars_in_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); +} + +static void rs_flush_buffer(struct tty_struct *tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + unsigned long flags; + + save_flags(flags); cli(); + info->xmit.head = info->xmit.tail = 0; + restore_flags(flags); + + wake_up_interruptible(&tty->write_wait); + + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void rs_send_xchar(struct tty_struct *tty, char ch) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + info->x_char = ch; + if (ch) { + /* + * I guess we could call console->write() directly but + * let's do that for now. + */ + transmit_chars(info, NULL); + } +} + +/* + * ------------------------------------------------------------ + * rs_throttle() + * + * This routine is called by the upper-layer tty layer to signal that + * incoming characters should be throttled. + * ------------------------------------------------------------ + */ +static void rs_throttle(struct tty_struct * tty) +{ + if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); + + printk("simrs_throttle called\n"); +} + +static void rs_unthrottle(struct tty_struct * tty) +{ + struct async_struct *info = (struct async_struct *)tty->driver_data; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + rs_send_xchar(tty, START_CHAR(tty)); + } + printk("simrs_unthrottle called\n"); +} + +/* + * rs_break() --- routine which turns the break handling on or off + */ +static void rs_break(struct tty_struct *tty, int break_state) +{ +} + +static int rs_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + printk("rs_ioctl: TIOCMGET called\n"); + return -EINVAL; + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + printk("rs_ioctl: TIOCMBIS/BIC/SET called\n"); + return -EINVAL; + case TIOCGSERIAL: + printk("simrs_ioctl TIOCGSERIAL called\n"); + return 0; + case TIOCSSERIAL: + printk("simrs_ioctl TIOCSSERIAL called\n"); + return 0; + case TIOCSERCONFIG: + printk("rs_ioctl: TIOCSERCONFIG called\n"); + return -EINVAL; + + case TIOCSERGETLSR: /* Get line status register */ + printk("rs_ioctl: TIOCSERGETLSR called\n"); + return -EINVAL; + + case TIOCSERGSTRUCT: + printk("rs_ioctl: TIOCSERGSTRUCT called\n"); +#if 0 + if (copy_to_user((struct async_struct *) arg, + info, sizeof(struct async_struct))) + return -EFAULT; +#endif + return 0; + + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + printk("rs_ioctl: TIOCMIWAIT: called\n"); + return 0; + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + case TIOCGICOUNT: + printk("rs_ioctl: TIOCGICOUNT called\n"); + return 0; + + case TIOCSERGWILD: + case TIOCSERSWILD: + /* "setserial -W" is called in Debian boot */ + printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + return 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + +static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + unsigned int cflag = tty->termios->c_cflag; + + if ( (cflag == old_termios->c_cflag) + && ( RELEVANT_IFLAG(tty->termios->c_iflag) + == RELEVANT_IFLAG(old_termios->c_iflag))) + return; + + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; + rs_start(tty); + } +} +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void shutdown(struct async_struct * info) +{ + unsigned long flags; + struct serial_state *state; + int retval; + + if (!(info->flags & ASYNC_INITIALIZED)) return; + + state = info->state; + +#ifdef SIMSERIAL_DEBUG + printk("Shutting down serial port %d (irq %d)....", info->line, + state->irq); +#endif + + save_flags(flags); cli(); /* Disable interrupts */ + + /* + * First unlink the serial port from the IRQ chain... + */ + if (info->next_port) + info->next_port->prev_port = info->prev_port; + if (info->prev_port) + info->prev_port->next_port = info->next_port; + else + IRQ_ports[state->irq] = info->next_port; + + /* + * Free the IRQ, if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + free_irq(state->irq, NULL); + retval = request_irq(state->irq, rs_interrupt_single, + IRQ_T(info), "serial", NULL); + + if (retval) + printk("serial shutdown: request_irq: error %d" + " Couldn't reacquire IRQ.\n", retval); + } else + free_irq(state->irq, NULL); + } + + if (info->xmit.buf) { + free_page((unsigned long) info->xmit.buf); + info->xmit.buf = 0; + } + + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; + restore_flags(flags); +} + +/* + * ------------------------------------------------------------ + * rs_close() + * + * This routine is called when the serial port gets closed. First, we + * wait for the last remaining data to be sent. Then, we unlink its + * async structure from the interrupt chain if necessary, and we free + * that IRQ if nothing is left in the chain. + * ------------------------------------------------------------ + */ +static void rs_close(struct tty_struct *tty, struct file * filp) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state; + unsigned long flags; + + if (!info ) return; + + state = info->state; + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { +#ifdef SIMSERIAL_DEBUG + printk("rs_close: hung_up\n"); +#endif + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } +#ifdef SIMSERIAL_DEBUG + printk("rs_close ttys%d, count = %d\n", info->line, state->count); +#endif + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("rs_close: bad serial port count; tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + printk("rs_close: bad serial port count for ttys%d: %d\n", + info->line, state->count); + state->count = 0; + } + if (state->count) { + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + info->flags |= ASYNC_CLOSING; + restore_flags(flags); + + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + shutdown(info); + if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); + info->event = 0; + info->tty = 0; + if (info->blocked_open) { + if (info->close_delay) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(info->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; +} + +/* + * rs_wait_until_sent() --- wait until the transmitter is empty + */ +static void rs_wait_until_sent(struct tty_struct *tty, int timeout) +{ +} + + +/* + * rs_hangup() --- called by tty_hangup() when a hangup is signaled. + */ +static void rs_hangup(struct tty_struct *tty) +{ + struct async_struct * info = (struct async_struct *)tty->driver_data; + struct serial_state *state = info->state; + +#ifdef SIMSERIAL_DEBUG + printk("rs_hangup: called\n"); +#endif + + state = info->state; + + rs_flush_buffer(tty); + if (info->flags & ASYNC_CLOSING) + return; + shutdown(info); + + info->event = 0; + state->count = 0; + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + info->tty = 0; + wake_up_interruptible(&info->open_wait); +} + + +static int get_async_struct(int line, struct async_struct **ret_info) +{ + struct async_struct *info; + struct serial_state *sstate; + + sstate = rs_table + line; + sstate->count++; + if (sstate->info) { + *ret_info = sstate->info; + return 0; + } + info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); + if (!info) { + sstate->count--; + return -ENOMEM; + } + memset(info, 0, sizeof(struct async_struct)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->magic = SERIAL_MAGIC; + info->port = sstate->port; + info->flags = sstate->flags; + info->xmit_fifo_size = sstate->xmit_fifo_size; + info->line = line; + info->tqueue.routine = do_softint; + info->tqueue.data = info; + info->state = sstate; + if (sstate->info) { + kfree(info); + *ret_info = sstate->info; + return 0; + } + *ret_info = sstate->info = info; + return 0; +} + +static int +startup(struct async_struct *info) +{ + unsigned long flags; + int retval=0; + void (*handler)(int, void *, struct pt_regs *); + struct serial_state *state= info->state; + unsigned long page; + + page = get_free_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + save_flags(flags); cli(); + + if (info->flags & ASYNC_INITIALIZED) { + free_page(page); + goto errout; + } + + if (!state->port || !state->type) { + if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); + free_page(page); + goto errout; + } + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + +#ifdef SIMSERIAL_DEBUG + printk("startup: ttys%d (irq %d)...", info->line, state->irq); +#endif + + /* + * Allocate the IRQ if necessary + */ + if (state->irq && (!IRQ_ports[state->irq] || + !IRQ_ports[state->irq]->next_port)) { + if (IRQ_ports[state->irq]) { + retval = -EBUSY; + goto errout; + } else + handler = rs_interrupt_single; + + retval = request_irq(state->irq, handler, IRQ_T(info), + "simserial", NULL); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, + &info->tty->flags); + retval = 0; + } + goto errout; + } + } + + /* + * Insert serial port into IRQ chain. + */ + info->prev_port = 0; + info->next_port = IRQ_ports[state->irq]; + if (info->next_port) + info->next_port->prev_port = info; + IRQ_ports[state->irq] = info; + + if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); + + info->xmit.head = info->xmit.tail = 0; + +#if 0 + /* + * Set up serial timers... + */ + timer_table[RS_TIMER].expires = jiffies + 2*HZ/100; + timer_active |= 1 << RS_TIMER; +#endif + + /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + info->flags |= ASYNC_INITIALIZED; + restore_flags(flags); + return 0; + +errout: + restore_flags(flags); + return retval; +} + + +/* + * This routine is called whenever a serial port is opened. It + * enables interrupts for a serial port, linking in its async structure into + * the IRQ chain. It also performs the serial-specific + * initialization for the tty structure. + */ +static int rs_open(struct tty_struct *tty, struct file * filp) +{ + struct async_struct *info; + int retval, line; + unsigned long page; + + MOD_INC_USE_COUNT; + line = MINOR(tty->device) - tty->driver.minor_start; + if ((line < 0) || (line >= NR_PORTS)) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + retval = get_async_struct(line, &info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + tty->driver_data = info; + info->tty = tty; + +#ifdef SIMSERIAL_DEBUG + printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line, + info->state->count); +#endif + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + if (!tmp_buf) { + page = get_free_page(GFP_KERNEL); + if (!page) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ + return -ENOMEM; + } + if (tmp_buf) + free_page(page); + else + tmp_buf = (unsigned char *) page; + } + + /* + * If the port is the middle of closing, bail out now + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ +#ifdef SERIAL_DO_RESTART + return ((info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS); +#else + return -EAGAIN; +#endif + } + + /* + * Start up serial port + */ + retval = startup(info); + if (retval) { + /* MOD_DEC_USE_COUNT; "info->tty" will cause this? */ + return retval; + } + + if ((info->state->count == 1) && + (info->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) + *tty->termios = info->state->normal_termios; + else + *tty->termios = info->state->callout_termios; + } + + /* + * figure out which console to use (should be one already) + */ + console = console_drivers; + while (console) { + if ((console->flags & CON_ENABLED) && console->write) break; + console = console->next; + } + + info->session = current->session; + info->pgrp = current->pgrp; + +#ifdef SIMSERIAL_DEBUG + printk("rs_open ttys%d successful\n", info->line); +#endif + return 0; +} + +/* + * /proc fs routines.... + */ + +static inline int line_info(char *buf, struct serial_state *state) +{ + return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n", + state->line, uart_config[state->type].name, + state->port, state->irq); +} + +int rs_read_proc(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int i, len = 0, l; + off_t begin = 0; + + len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version); + for (i = 0; i < NR_PORTS && len < 4000; i++) { + l = line_info(page + len, &rs_table[i]); + len += l; + if (len+begin > off+count) + goto done; + if (len+begin < off) { + begin += len; + len = 0; + } + } + *eof = 1; +done: + if (off >= len+begin) + return 0; + *start = page + (begin-off); + return ((count < begin+len-off) ? count : begin+len-off); +} + +/* + * --------------------------------------------------------------------- + * rs_init() and friends + * + * rs_init() is called at boot-time to initialize the serial driver. + * --------------------------------------------------------------------- + */ + +/* + * This routine prints out the appropriate serial driver version + * number, and identifies which options were configured into this + * driver. + */ +static inline void show_serial_version(void) +{ + printk(KERN_INFO "%s version %s with", serial_name, serial_version); + printk(" no serial options enabled\n"); +} + +/* + * The serial driver boot-time initialization code! + */ +static int __init +simrs_init (void) +{ + int i; + struct serial_state *state; + + show_serial_version(); + + /* Initialize the tty_driver structure */ + + memset(&serial_driver, 0, sizeof(struct tty_driver)); + serial_driver.magic = TTY_DRIVER_MAGIC; + serial_driver.driver_name = "simserial"; + serial_driver.name = "ttyS"; + serial_driver.major = TTY_MAJOR; + serial_driver.minor_start = 64; + serial_driver.num = 1; + serial_driver.type = TTY_DRIVER_TYPE_SERIAL; + serial_driver.subtype = SERIAL_TYPE_NORMAL; + serial_driver.init_termios = tty_std_termios; + serial_driver.init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + serial_driver.flags = TTY_DRIVER_REAL_RAW; + serial_driver.refcount = &serial_refcount; + serial_driver.table = serial_table; + serial_driver.termios = serial_termios; + serial_driver.termios_locked = serial_termios_locked; + + serial_driver.open = rs_open; + serial_driver.close = rs_close; + serial_driver.write = rs_write; + serial_driver.put_char = rs_put_char; + serial_driver.flush_chars = rs_flush_chars; + serial_driver.write_room = rs_write_room; + serial_driver.chars_in_buffer = rs_chars_in_buffer; + serial_driver.flush_buffer = rs_flush_buffer; + serial_driver.ioctl = rs_ioctl; + serial_driver.throttle = rs_throttle; + serial_driver.unthrottle = rs_unthrottle; + serial_driver.send_xchar = rs_send_xchar; + serial_driver.set_termios = rs_set_termios; + serial_driver.stop = rs_stop; + serial_driver.start = rs_start; + serial_driver.hangup = rs_hangup; + serial_driver.break_ctl = rs_break; + serial_driver.wait_until_sent = rs_wait_until_sent; + serial_driver.read_proc = rs_read_proc; + + /* + * Let's have a little bit of fun ! + */ + for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { + + if (state->type == PORT_UNKNOWN) continue; + + if (!state->irq) { + state->irq = ia64_alloc_irq(); + ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); + } + + printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a %s\n", + state->line, + state->port, state->irq, + uart_config[state->type].name); + } + /* + * The callout device is just like normal device except for + * major number and the subtype code. + */ + callout_driver = serial_driver; + callout_driver.name = "cua"; + callout_driver.major = TTYAUX_MAJOR; + callout_driver.subtype = SERIAL_TYPE_CALLOUT; + callout_driver.read_proc = 0; + callout_driver.proc_entry = 0; + + if (tty_register_driver(&serial_driver)) + panic("Couldn't register simserial driver\n"); + + if (tty_register_driver(&callout_driver)) + panic("Couldn't register callout driver\n"); + + return 0; +} + +#ifndef MODULE +__initcall(simrs_init); +#endif diff -urN linux-2.4.0-test12/drivers/media/radio/Makefile linux-2.4.0-test12-lia/drivers/media/radio/Makefile --- linux-2.4.0-test12/drivers/media/radio/Makefile Tue Sep 19 08:01:34 2000 +++ linux-2.4.0-test12-lia/drivers/media/radio/Makefile Mon Oct 30 22:17:11 2000 @@ -9,7 +9,7 @@ # parent makes.. # -O_OBJS := +O_OBJS := dummy.o OX_OBJS := M_OBJS := MX_OBJS := diff -urN linux-2.4.0-test12/drivers/media/radio/dummy.c linux-2.4.0-test12-lia/drivers/media/radio/dummy.c --- linux-2.4.0-test12/drivers/media/radio/dummy.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/media/radio/dummy.c Mon Oct 30 22:17:11 2000 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -urN linux-2.4.0-test12/drivers/media/video/Makefile linux-2.4.0-test12-lia/drivers/media/video/Makefile --- linux-2.4.0-test12/drivers/media/video/Makefile Wed Dec 6 18:32:48 2000 +++ linux-2.4.0-test12-lia/drivers/media/video/Makefile Wed Dec 6 18:36:54 2000 @@ -16,7 +16,7 @@ # Object file lists. -obj-y := +obj-y := dummy.o obj-m := obj-n := obj- := diff -urN linux-2.4.0-test12/drivers/media/video/dummy.c linux-2.4.0-test12-lia/drivers/media/video/dummy.c --- linux-2.4.0-test12/drivers/media/video/dummy.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/media/video/dummy.c Mon Oct 30 22:17:11 2000 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -urN linux-2.4.0-test12/drivers/net/Makefile linux-2.4.0-test12-lia/drivers/net/Makefile --- linux-2.4.0-test12/drivers/net/Makefile Thu Sep 21 13:27:10 2000 +++ linux-2.4.0-test12-lia/drivers/net/Makefile Mon Oct 30 22:17:11 2000 @@ -199,6 +199,7 @@ obj-$(CONFIG_ES3210) += es3210.o 8390.o obj-$(CONFIG_LNE390) += lne390.o 8390.o obj-$(CONFIG_NE3210) += ne3210.o 8390.o +obj-$(CONFIG_SIMETH) += simeth.o obj-$(CONFIG_PPP) += ppp_generic.o slhc.o obj-$(CONFIG_PPP_ASYNC) += ppp_async.o diff -urN linux-2.4.0-test12/drivers/net/eepro100.c linux-2.4.0-test12-lia/drivers/net/eepro100.c --- linux-2.4.0-test12/drivers/net/eepro100.c Wed Dec 13 17:29:57 2000 +++ linux-2.4.0-test12-lia/drivers/net/eepro100.c Thu Dec 14 14:42:16 2000 @@ -25,6 +25,8 @@ Disabled FC and ER, to avoid lockups when when we get FCP interrupts. 2000 Jul 17 Goutham Rao PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary + 2000 Aug 31 David Mosberger + RX_ALIGN support: enables rx DMA without causing unaligned accesses. */ static const char *version = @@ -41,13 +43,17 @@ static int txdmacount = 128; static int rxdmacount /* = 0 */; +#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) + /* align rx buffers to 2 bytes so that IP header is aligned */ +# define RX_ALIGN +# define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed)) +#else +# define RxFD_ALIGNMENT +#endif + /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method. Lower values use more memory, but are faster. */ -#if defined(__alpha__) || defined(__sparc__) -static int rx_copybreak = 1518; -#else static int rx_copybreak = 200; -#endif /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static int max_interrupt_work = 20; @@ -370,18 +376,18 @@ /* The Speedo3 Rx and Tx frame/buffer descriptors. */ struct descriptor { /* A generic descriptor. */ - s32 cmd_status; /* All command and status fields. */ + volatile s32 cmd_status; /* All command and status fields. */ u32 link; /* struct descriptor * */ unsigned char params[0]; }; /* The Speedo3 Rx and Tx buffer descriptors. */ struct RxFD { /* Receive frame descriptor. */ - s32 status; + volatile s32 status; u32 link; /* struct RxFD * */ u32 rx_buf_addr; /* void * */ u32 count; -}; +} RxFD_ALIGNMENT; /* Selected elements of the Tx/RxFD.status word. */ enum RxFD_bits { @@ -1165,6 +1171,9 @@ for (i = 0; i < RX_RING_SIZE; i++) { struct sk_buff *skb; skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); +#ifdef RX_ALIGN + skb_reserve(skb, 2); /* Align IP on 16 byte boundary */ +#endif sp->rx_skbuff[i] = skb; if (skb == NULL) break; /* OK. Just initially short of Rx bufs. */ @@ -1590,6 +1599,9 @@ struct sk_buff *skb; /* Get a fresh skbuff to replace the consumed one. */ skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); +#ifdef RX_ALIGN + skb_reserve(skb, 2); /* Align IP on 16 byte boundary */ +#endif sp->rx_skbuff[entry] = skb; if (skb == NULL) { sp->rx_ringp[entry] = NULL; diff -urN linux-2.4.0-test12/drivers/net/simeth.c linux-2.4.0-test12-lia/drivers/net/simeth.c --- linux-2.4.0-test12/drivers/net/simeth.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/net/simeth.c Wed Nov 1 23:19:29 2000 @@ -0,0 +1,596 @@ +/* + * Simulated Ethernet Driver + * + * Copyright (C) 1999-2000 Hewlett-Packard Co + * Copyright (C) 1999-2000 Stephane Eranain + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SIMETH_RECV_MAX 10 + +/* + * Maximum possible received frame for Ethernet. + * We preallocate an sk_buff of that size to avoid costly + * memcpy for temporary buffer into sk_buff. We do basically + * what's done in other drivers, like eepro with a ring. + * The difference is, of course, that we don't have real DMA !!! + */ +#define SIMETH_FRAME_SIZE ETH_FRAME_LEN + + +#define SSC_NETDEV_PROBE 100 +#define SSC_NETDEV_SEND 101 +#define SSC_NETDEV_RECV 102 +#define SSC_NETDEV_ATTACH 103 +#define SSC_NETDEV_DETACH 104 + +#define NETWORK_INTR 8 + +/* + * This structure is need for the module version + * It hasn't been tested yet + */ +struct simeth_local { + struct net_device *next_module; + struct net_device_stats stats; + int simfd; /* descriptor in the simulator */ +}; + +static int simeth_probe1(void); +static int simeth_open(struct net_device *dev); +static int simeth_close(struct net_device *dev); +static int simeth_tx(struct sk_buff *skb, struct net_device *dev); +static int simeth_rx(struct net_device *dev); +static struct net_device_stats *simeth_get_stats(struct net_device *dev); +static void simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs); +static void set_multicast_list(struct net_device *dev); +static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr); + +static char *simeth_version="v0.2"; + +/* + * This variable is used to establish a mapping between the Linux/ia64 kernel + * and the host linux kernel. + * + * As of today, we support only one card, even though most of the code + * is ready for many more. The mapping is then: + * linux/ia64 -> linux/x86 + * eth0 -> eth1 + * + * In the future, we some string operations, we could easily support up + * to 10 cards (0-9). + * + * The default mapping can be changed on the kernel command line by + * specifying simeth=ethX (or whatever string you want). + */ +static char *simeth_device="eth0"; /* default host interface to use */ + + + +static volatile unsigned int card_count; /* how many cards "found" so far */ +static int simeth_debug=0; /* set to 1 to get debug information */ + +/* + * Used to catch IFF_UP & IFF_DOWN events + */ +static struct notifier_block simeth_dev_notifier = { + simeth_device_event, + 0 +}; + + +/* + * Function used when using a kernel command line option. + * + * Format: simeth=interface_name (like eth0) + */ +static int __init +simeth_setup(char *str) +{ + simeth_device = str; + return 1; +} + +__setup("simeth=", simeth_setup); + +/* + * Function used to probe for simeth devices when not installed + * as a loadable module + */ + +int __init +simeth_probe (void) +{ + return simeth_probe1(); +} + +extern long ia64_ssc (long, long, long, long, int); +extern void ia64_ssc_connect_irq (long intr, long irq); + +static inline int +netdev_probe(char *name, unsigned char *ether) +{ + return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE); +} + + +static inline int +netdev_connect(int irq) +{ + /* XXX Fix me + * this does not support multiple cards + * also no return value + */ + ia64_ssc_connect_irq(NETWORK_INTR, irq); + return 0; +} + +static inline int +netdev_attach(int fd, int irq, unsigned int ipaddr) +{ + /* this puts the host interface in the right mode (start interupting) */ + return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH); +} + + +static inline int +netdev_detach(int fd) +{ + /* + * inactivate the host interface (don't interrupt anymore) */ + return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH); +} + +static inline int +netdev_send(int fd, unsigned char *buf, unsigned int len) +{ + return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND); +} + +static inline int +netdev_read(int fd, unsigned char *buf, unsigned int len) +{ + return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV); +} + +/* + * Function shared with module code, so cannot be in init section + * + * So far this function "detects" only one card (test_&_set) but could + * be extended easily. + * + * Return: + * - -ENODEV is no device found + * - -ENOMEM is no more memory + * - 0 otherwise + */ +static int +simeth_probe1(void) +{ + unsigned char mac_addr[ETH_ALEN]; + struct simeth_local *local; + struct net_device *dev; + int fd, i; + + /* + * XXX Fix me + * let's support just one card for now + */ + if (test_and_set_bit(0, &card_count)) + return -ENODEV; + + /* + * check with the simulator for the device + */ + fd = netdev_probe(simeth_device, mac_addr); + if (fd == -1) + return -ENODEV; + + dev = init_etherdev(NULL, sizeof(struct simeth_local)); + if (!dev) + return -ENOMEM; + + memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr)); + + dev->irq = ia64_alloc_irq(); + + /* + * attach the interrupt in the simulator, this does enable interrupts + * until a netdev_attach() is called + */ + netdev_connect(dev->irq); + + memset(dev->priv, 0, sizeof(struct simeth_local)); + + local = dev->priv; + local->simfd = fd; /* keep track of underlying file descriptor */ + local->next_module = NULL; + + dev->open = simeth_open; + dev->stop = simeth_close; + dev->hard_start_xmit = simeth_tx; + dev->get_stats = simeth_get_stats; + dev->set_multicast_list = set_multicast_list; /* no yet used */ + + /* Fill in the fields of the device structure with ethernet-generic values. */ + ether_setup(dev); + + printk("simeth: %s alpha\n", simeth_version); + printk("%s: hosteth=%s simfd=%d, HwAddr", dev->name, simeth_device, local->simfd); + for(i = 0; i < ETH_ALEN; i++) { + printk(" %2.2x", dev->dev_addr[i]); + } + printk(", IRQ %d\n", dev->irq); + +#ifdef MODULE + local->next_module = simeth_dev; + simeth_dev = dev; +#endif + /* + * XXX Fix me + * would not work with more than one device ! + */ + register_netdevice_notifier(&simeth_dev_notifier); + + return 0; +} + +/* + * actually binds the device to an interrupt vector + */ +static int +simeth_open(struct net_device *dev) +{ + if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) { + printk ("simeth: unable to get IRQ %d.\n", dev->irq); + return -EAGAIN; + } + + netif_start_queue(dev); + MOD_INC_USE_COUNT; + + return 0; +} + +/* copied from lapbether.c */ +static __inline__ int dev_is_ethdev(struct net_device *dev) +{ + return ( dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5)); +} + + +/* + * Handler for IFF_UP or IFF_DOWN + * + * The reason for that is that we don't want to be interrupted when the + * interface is down. There is no way to unconnect in the simualtor. Instead + * we use this function to shutdown packet processing in the frame filter + * in the simulator. Thus no interrupts are generated + * + * + * That's also the place where we pass the IP address of this device to the + * simulator so that that we can start filtering packets for it + * + * There may be a better way of doing this, but I don't know which yet. + */ +static int +simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) +{ + struct net_device *dev = (struct net_device *)ptr; + struct simeth_local *local; + struct in_device *in_dev; + struct in_ifaddr **ifap = NULL; + struct in_ifaddr *ifa = NULL; + int r; + + + if ( ! dev ) { + printk(KERN_WARNING "simeth_device_event dev=0\n"); + return NOTIFY_DONE; + } + + if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE; + + /* + * Check whether or not it's for an ethernet device + * + * XXX Fixme: This works only as long as we support one + * type of ethernet device. + */ + if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE; + + if ((in_dev=dev->ip_ptr) != NULL) { + for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next) + if (strcmp(dev->name, ifa->ifa_label) == 0) break; + } + if ( ifa == NULL ) { + printk("simeth_open: can't find device %s's ifa\n", dev->name); + return NOTIFY_DONE; + } + + printk("simeth_device_event: %s ipaddr=0x%x\n", dev->name, htonl(ifa->ifa_local)); + + /* + * XXX Fix me + * if the device was up, and we're simply reconfiguring it, not sure + * we get DOWN then UP. + */ + + local = dev->priv; + /* now do it for real */ + r = event == NETDEV_UP ? + netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)): + netdev_detach(local->simfd); + + printk("simeth: netdev_attach/detach: event=%s ->%d\n", event == NETDEV_UP ? "attach":"detach", r); + + return NOTIFY_DONE; +} + +static int +simeth_close(struct net_device *dev) +{ + netif_stop_queue(dev); + + free_irq(dev->irq, dev); + + MOD_DEC_USE_COUNT; + + return 0; +} + +/* + * Only used for debug + */ +static void +frame_print(unsigned char *from, unsigned char *frame, int len) +{ + int i; + + printk("%s: (%d) %02x", from, len, frame[0] & 0xff); + for(i=1; i < 6; i++ ) { + printk(":%02x", frame[i] &0xff); + } + printk(" %2x", frame[6] &0xff); + for(i=7; i < 12; i++ ) { + printk(":%02x", frame[i] &0xff); + } + printk(" [%02x%02x]\n", frame[12], frame[13]); + + for(i=14; i < len; i++ ) { + printk("%02x ", frame[i] &0xff); + if ( (i%10)==0) printk("\n"); + } + printk("\n"); +} + + +/* + * Function used to transmit of frame, very last one on the path before + * going to the simulator. + */ +static int +simeth_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct simeth_local *local = (struct simeth_local *)dev->priv; + +#if 0 + /* ensure we have at least ETH_ZLEN bytes (min frame size) */ + unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + /* Where do the extra padding bytes comes from inthe skbuff ? */ +#else + /* the real driver in the host system is going to take care of that + * or maybe it's the NIC itself. + */ + unsigned int length = skb->len; +#endif + + local->stats.tx_bytes += skb->len; + local->stats.tx_packets++; + + + if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length); + + netdev_send(local->simfd, skb->data, length); + + /* + * we are synchronous on write, so we don't simulate a + * trasnmit complete interrupt, thus we don't need to arm a tx + */ + + dev_kfree_skb(skb); + return 0; +} + +static inline struct sk_buff * +make_new_skb(struct net_device *dev) +{ + struct sk_buff *nskb; + + /* + * The +2 is used to make sure that the IP header is nicely + * aligned (on 4byte boundary I assume 14+2=16) + */ + nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2); + if ( nskb == NULL ) { + printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name); + return NULL; + } + nskb->dev = dev; + + skb_reserve(nskb, 2); /* Align IP on 16 byte boundaries */ + + skb_put(nskb,SIMETH_FRAME_SIZE); + + return nskb; +} + +/* + * called from interrupt handler to process a received frame + */ +static int +simeth_rx(struct net_device *dev) +{ + struct simeth_local *local; + struct sk_buff *skb; + int len; + int rcv_count = SIMETH_RECV_MAX; + + local = (struct simeth_local *)dev->priv; + /* + * the loop concept has been borrowed from other drivers + * looks to me like it's a throttling thing to avoid pushing to many + * packets at one time into the stack. Making sure we can process them + * upstream and make forward progress overall + */ + do { + if ( (skb=make_new_skb(dev)) == NULL ) { + printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name); + local->stats.rx_dropped++; + return 0; + } + /* + * Read only one frame at a time + */ + len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE); + if ( len == 0 ) { + if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n", dev->name, SIMETH_RECV_MAX-rcv_count); + break; + } +#if 0 + /* + * XXX Fix me + * Should really do a csum+copy here + */ + memcpy(skb->data, frame, len); +#endif + skb->protocol = eth_type_trans(skb, dev); + + if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len); + + /* + * push the packet up & trigger software interrupt + */ + netif_rx(skb); + + local->stats.rx_packets++; + local->stats.rx_bytes += len; + + } while ( --rcv_count ); + + return len; /* 0 = nothing left to read, otherwise, we can try again */ +} + +/* + * Interrupt handler (Yes, we can do it too !!!) + */ +static void +simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + struct net_device *dev = dev_id; + + if ( dev == NULL ) { + printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq); + return; + } + + /* + * very simple loop because we get interrupts only when receving + */ + while (simeth_rx(dev)); +} + +static struct net_device_stats * +simeth_get_stats(struct net_device *dev) +{ + struct simeth_local *local = (struct simeth_local *) dev->priv; + + return &local->stats; +} + +/* fake multicast ability */ +static void +set_multicast_list(struct net_device *dev) +{ + printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name); +} + +#ifdef CONFIG_NET_FASTROUTE +static int +simeth_accept_fastpath(struct net_device *dev, struct dst_entry *dst) +{ + printk(KERN_WARNING "%s: simeth_accept_fastpath called\n", dev->name); + return -1; +} +#endif + + +#ifdef MODULE +static int +simeth_init(void) +{ + unsigned int cards_found = 0; + + /* iterate over probe */ + + while ( simeth_probe1() == 0 ) cards_found++; + + return cards_found ? 0 : -ENODEV; +} + + +int +init_module(void) +{ + simeth_dev = NULL; + + /* the register_netdev is done "indirectly by ether_initdev() */ + + return simeth_init(); +} + +void +cleanup_module(void) +{ + struct net_device *next; + + while ( simeth_dev ) { + + next = ((struct simeth_private *)simeth_dev->priv)->next_module; + + unregister_netdev(simeth_dev); + + kfree(simeth_dev); + + simeth_dev = next; + } + /* + * XXX fix me + * not clean wihen multiple devices + */ + unregister_netdevice_notifier(&simeth_dev_notifier); +} +#else /* !MODULE */ +__initcall(simeth_probe); +#endif /* !MODULE */ diff -urN linux-2.4.0-test12/drivers/net/tulip/tulip_core.c linux-2.4.0-test12-lia/drivers/net/tulip/tulip_core.c --- linux-2.4.0-test12/drivers/net/tulip/tulip_core.c Wed Dec 13 17:30:06 2000 +++ linux-2.4.0-test12-lia/drivers/net/tulip/tulip_core.c Wed Dec 6 18:37:08 2000 @@ -73,9 +73,9 @@ #if defined(__alpha__) || defined(__ia64__) static int csr0 = 0x01A00000 | 0xE000; -#elif defined(__i386__) || defined(__powerpc__) +#elif defined(__i386__) || defined(__powerpc__) || defined(__hppa__) static int csr0 = 0x01A00000 | 0x8000; -#elif defined(__sparc__) || defined(__hppa__) +#elif defined(__sparc__) /* The UltraSparc PCI controllers will disconnect at every 64-byte * crossing anyways so it makes no sense to tell Tulip to burst * any more than that. diff -urN linux-2.4.0-test12/drivers/scsi/Makefile linux-2.4.0-test12-lia/drivers/scsi/Makefile --- linux-2.4.0-test12/drivers/scsi/Makefile Wed Dec 13 17:30:09 2000 +++ linux-2.4.0-test12-lia/drivers/scsi/Makefile Thu Dec 14 14:42:31 2000 @@ -52,6 +52,7 @@ obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o +obj-$(CONFIG_SCSI_SIM) += simscsi.o obj-$(CONFIG_SCSI_SIM710) += sim710.o obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o obj-$(CONFIG_SCSI_PCI2000) += pci2000.o @@ -124,7 +125,7 @@ scsi_obsolete.o scsi_queue.o scsi_lib.o \ scsi_merge.o scsi_dma.o scsi_scan.o \ scsi_syms.o - + sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o a100u2w-objs := inia100.o i60uscsi.o diff -urN linux-2.4.0-test12/drivers/scsi/ql12160_fw.h linux-2.4.0-test12-lia/drivers/scsi/ql12160_fw.h --- linux-2.4.0-test12/drivers/scsi/ql12160_fw.h Mon Feb 7 19:45:28 2000 +++ linux-2.4.0-test12-lia/drivers/scsi/ql12160_fw.h Mon Oct 30 22:17:11 2000 @@ -1,56 +1,93 @@ /* + ************************************************************************ + * * + * --- ISP12160 Initiator Firmware --- * + * 32 LUN Support * + * * + ************************************************************************ + * * + * Copyright (C) 1999,2000 Qlogic, Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that the following conditions are met: + * 1. Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products + + * 2. Redistribution in binary form must reproduce the above copyright + + * notice, this list of conditions and the following disclaimer in the + + * documentation and/or other materials provided with the distribution. + + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * * + ************************************************************************ + */ + /* - * Firmware Version 10.01.19 (12:38 Oct 12, 1999) + * Firmware Version 10.04.08 (11:30 May 31, 2000) */ #ifdef UNIQUE_FW_NAME -unsigned short fw12160i_version = 10*1024+1; +unsigned short fw12160i_version = 10*1024+4; #else -unsigned short risc_code_version = 10*1024+1; +unsigned short risc_code_version = 10*1024+4; #endif #ifdef UNIQUE_FW_NAME -unsigned char fw12160i_version_str[] = {10,1,19}; +unsigned char fw12160i_version_str[] = {10,4,8}; #else -unsigned char firmware_version[] = {10,1,19}; +unsigned char firmware_version[] = {10,4,8}; #endif #ifdef UNIQUE_FW_NAME -#define fw12160i_VERSION_STRING "10.1.19" +#define fw12160i_VERSION_STRING "10.04.08" #else -#define FW_VERSION_STRING "10.1.19" +#define FW_VERSION_STRING "10.04.08" #endif #ifdef UNIQUE_FW_NAME @@ -64,1326 +101,1383 @@ #else unsigned short risc_code01[] = { #endif - 0x0804, 0x1041, 0x0000, 0x32f8, 0x0000, 0x2043, 0x4f50, 0x5952, + 0x0804, 0x1041, 0x0000, 0x34e5, 0x0000, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350, 0x3132, 0x3136, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, - 0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3031, 0x2020, 0x2043, + 0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020, - 0x2400, 0x20c9, 0x8cff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001, + 0x2400, 0x20c9, 0x8eff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2, - 0x20c1, 0x0020, 0x2089, 0x1223, 0x2071, 0x0010, 0x70c3, 0x0004, + 0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a, 0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128, - 0xa1a2, 0x4300, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, - 0xa192, 0x8d00, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1d83, - 0x2218, 0x2079, 0x4300, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, + 0xa1a2, 0x4500, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, + 0xa192, 0x8f00, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1dcf, + 0x2218, 0x2079, 0x4500, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102, 0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd, - 0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4340, 0x080c, - 0x42d8, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4380, - 0x2071, 0x0100, 0x080c, 0x42d8, 0x7814, 0xc0d4, 0x7816, 0x00de, + 0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4540, 0x080c, + 0x44bd, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4580, + 0x2071, 0x0100, 0x080c, 0x44bd, 0x7814, 0xc0d4, 0x7816, 0x00de, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002, - 0x2009, 0x0002, 0x2069, 0x4340, 0x681b, 0x0003, 0x6823, 0x0007, - 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000, - 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0500, - 0x68d3, 0x000a, 0x68c3, 0x43c0, 0x2079, 0x4300, 0x68d7, 0x762d, - 0x68c7, 0x48c0, 0x68cb, 0x47c0, 0x68cf, 0x88c0, 0x68ab, 0x8b44, - 0x68af, 0x8b49, 0x68b3, 0x8b44, 0x68b7, 0x8b44, 0x68a7, 0x0001, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4380, 0x0860, - 0x68d3, 0x000a, 0x68c3, 0x45c0, 0x68d7, 0x7839, 0x68c7, 0x68c0, - 0x68cb, 0x4840, 0x68cf, 0x89d0, 0x68ab, 0x8b49, 0x68af, 0x8b4e, - 0x68b3, 0x8b49, 0x68b7, 0x8b49, 0x68a7, 0x0001, 0x00e6, 0x2069, - 0x47c0, 0x2071, 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021, - 0x0009, 0x1120, 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1cf3, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4840, 0x2071, - 0x0100, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021, 0x0009, 0x1120, - 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1cf3, 0x00ee, 0x2011, - 0x0002, 0x2069, 0x48c0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, - 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, - 0x0100, 0x681f, 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, - 0xade8, 0x0010, 0x1f04, 0x1137, 0x8109, 0x1d38, 0x2001, 0x01ff, - 0x2004, 0xd0fc, 0x1128, 0x8211, 0x0118, 0x2069, 0x68c0, 0x08d8, - 0x080c, 0x2254, 0x080c, 0x3e39, 0x080c, 0x1b0f, 0x080c, 0x42a0, - 0x2091, 0x2200, 0x2079, 0x4300, 0x2071, 0x0050, 0x2091, 0x2400, - 0x2079, 0x4300, 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, - 0x2071, 0x4340, 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4380, - 0x2091, 0x2000, 0x2079, 0x4300, 0x2071, 0x0010, 0x3200, 0xa085, - 0x303d, 0x2090, 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118e, - 0x70c0, 0xa086, 0x0002, 0x1110, 0x080c, 0x13a3, 0x2039, 0x0000, - 0x080c, 0x129c, 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119c, 0x786c, - 0xa065, 0x0110, 0x080c, 0x1ffe, 0x080c, 0x1da4, 0x0e04, 0x11b1, - 0x786c, 0xa065, 0x0110, 0x080c, 0x1ffe, 0x0e04, 0x11b1, 0x2009, - 0x4347, 0x2011, 0x4387, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, - 0x1c21, 0x2071, 0x4340, 0x70a4, 0xa005, 0x01e8, 0x7450, 0xa485, - 0x0000, 0x01c8, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c, - 0x303d, 0x2190, 0x080c, 0x260d, 0x2091, 0x8000, 0x2091, 0x303d, - 0x0e04, 0x11d3, 0x2079, 0x4300, 0x786c, 0xa065, 0x0120, 0x2071, - 0x0010, 0x080c, 0x1ffe, 0x1d04, 0x11db, 0x2079, 0x4300, 0x2071, - 0x0010, 0x080c, 0x40ed, 0x2071, 0x4380, 0x70a4, 0xa005, 0x0188, - 0x7050, 0xa025, 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4, - 0xa28c, 0x303d, 0x2190, 0x080c, 0x260d, 0x2091, 0x8000, 0x2091, - 0x303d, 0x2079, 0x4300, 0x2071, 0x0010, 0x0e04, 0x11fc, 0x786c, - 0xa065, 0x0110, 0x080c, 0x1ffe, 0x1d04, 0x1190, 0x080c, 0x40ed, - 0x0804, 0x1190, 0x3c00, 0xa084, 0x0007, 0x0002, 0x120e, 0x120e, - 0x1210, 0x1210, 0x1215, 0x1215, 0x121a, 0x121a, 0x080c, 0x243b, - 0x2091, 0x2400, 0x080c, 0x3e9c, 0x0005, 0x2091, 0x2200, 0x080c, - 0x3e9c, 0x0005, 0x2091, 0x2200, 0x080c, 0x3e9c, 0x2091, 0x2400, - 0x080c, 0x3e9c, 0x0005, 0x1243, 0x1243, 0x1244, 0x1244, 0x124f, - 0x124f, 0x124f, 0x124f, 0x1258, 0x1258, 0x1263, 0x1263, 0x124f, - 0x124f, 0x124f, 0x124f, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, - 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, - 0x1272, 0x1272, 0x1272, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, - 0x2800, 0x080c, 0x2458, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, - 0x0106, 0x0126, 0x080c, 0x1202, 0x012e, 0x010e, 0x000e, 0x000d, - 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2458, 0x012e, - 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, - 0x080c, 0x2458, 0x2091, 0x2800, 0x080c, 0x2458, 0x012e, 0x010e, - 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x00e6, 0x00f6, 0x2079, - 0x4300, 0x2071, 0x0200, 0x2069, 0x4340, 0x3d00, 0xd08c, 0x1120, - 0x2069, 0x4380, 0x2071, 0x0100, 0x080c, 0x42d8, 0x00fe, 0x00ee, - 0x012e, 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, - 0x0002, 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, - 0x70c3, 0x4002, 0x0804, 0x13a6, 0x0e04, 0x1308, 0x2061, 0x0000, - 0x6018, 0xd084, 0x1904, 0x1308, 0x7828, 0xa005, 0x1120, 0x0004, - 0x1309, 0x0804, 0x1308, 0xd0fc, 0x0148, 0x0006, 0x080c, 0x1aa9, - 0x000e, 0x0168, 0x2001, 0x4007, 0x0804, 0x13a5, 0x0006, 0x080c, - 0x1a9b, 0x000e, 0x0120, 0x2001, 0x4007, 0x0804, 0x13a5, 0x7910, - 0xd0fc, 0x1128, 0x2061, 0x4340, 0xc19c, 0xc7fc, 0x0020, 0x2061, - 0x4380, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x15d0, 0x7912, 0x6083, - 0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x1120, 0x00c6, 0x080c, - 0x18c9, 0x00ce, 0x782b, 0x0000, 0x607c, 0xa065, 0x0190, 0x00c6, - 0x609c, 0x080c, 0x1b76, 0x00ce, 0x609f, 0x0000, 0x080c, 0x19db, - 0x2009, 0x0018, 0x6087, 0x0103, 0x080c, 0x1ab7, 0x1198, 0x080c, - 0x1b02, 0x7810, 0xd09c, 0x1118, 0x2061, 0x4340, 0x0020, 0x2061, - 0x4380, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0c4, 0x0130, - 0xc0c4, 0x60d6, 0x2001, 0x4005, 0x0804, 0x13a5, 0x0804, 0x13a3, - 0x0005, 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, - 0xa08a, 0x0040, 0x1a04, 0x1355, 0x0002, 0x13a3, 0x13f1, 0x13bf, - 0x1425, 0x1459, 0x1459, 0x13b7, 0x19f3, 0x1463, 0x13b1, 0x13c3, - 0x13c4, 0x13c5, 0x13c6, 0x19f7, 0x13b1, 0x1470, 0x14c5, 0x18e4, - 0x19ed, 0x13c7, 0x1795, 0x17cb, 0x17fa, 0x183d, 0x1752, 0x175f, - 0x1772, 0x1784, 0x159a, 0x13b1, 0x14f7, 0x1502, 0x1510, 0x151e, - 0x1535, 0x1543, 0x1546, 0x1554, 0x1562, 0x156c, 0x1580, 0x158c, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x15a7, 0x15b8, 0x15d2, 0x1606, - 0x162f, 0x1641, 0x1644, 0x1677, 0x16aa, 0x16bc, 0x1720, 0x1730, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x1742, 0x2100, 0xa08a, 0x0040, - 0x1a04, 0x13b1, 0x0002, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x1a19, 0x1a1f, 0x13b1, 0x13b1, 0x13b1, 0x1a23, 0x1a63, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13ec, 0x1454, 0x146b, 0x14c0, 0x18df, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x1a67, 0x1a0b, 0x1a15, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, - 0x13b1, 0x13b1, 0x13b1, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, - 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13a6, + 0x2009, 0x0002, 0x2069, 0x4540, 0x681b, 0x0003, 0x6823, 0x0007, + 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006, + 0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a, + 0x68bf, 0x45c0, 0x2079, 0x4500, 0x68d3, 0x762d, 0x68c3, 0x4ac0, + 0x68c7, 0x49c0, 0x68cb, 0x8ac0, 0x68a7, 0x8d44, 0x68ab, 0x8d49, + 0x68af, 0x8d44, 0x68b3, 0x8d44, 0x68a3, 0x0001, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4580, 0x0870, 0x68cf, 0x000a, + 0x68bf, 0x47c0, 0x68d3, 0x7839, 0x68c3, 0x6ac0, 0x68c7, 0x4a40, + 0x68cb, 0x8bd0, 0x68a7, 0x8d49, 0x68ab, 0x8d4e, 0x68af, 0x8d49, + 0x68b3, 0x8d49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x49c0, 0x2071, + 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021, 0x0009, 0x1120, + 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1d3f, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4a40, 0x2071, 0x0100, 0x70ec, + 0xd0e4, 0x2019, 0x1c09, 0x2021, 0x0009, 0x1120, 0x2019, 0x1c0c, + 0x2021, 0x000c, 0x080c, 0x1d3f, 0x00ee, 0x2011, 0x0002, 0x2069, + 0x4ac0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, + 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f, + 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, + 0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc, + 0x1128, 0x8211, 0x0118, 0x2069, 0x6ac0, 0x08d8, 0x080c, 0x22b7, + 0x080c, 0x3fba, 0x080c, 0x1b51, 0x080c, 0x4489, 0x2091, 0x2200, + 0x2079, 0x4500, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4500, + 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4540, + 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4580, 0x2091, 0x2000, + 0x2079, 0x4500, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, + 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086, + 0x0002, 0x1110, 0x080c, 0x13b3, 0x2039, 0x0000, 0x080c, 0x12ab, + 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110, + 0x080c, 0x2061, 0x080c, 0x1df0, 0x0e04, 0x11af, 0x786c, 0xa065, + 0x0110, 0x080c, 0x2061, 0x0e04, 0x11af, 0x2009, 0x4547, 0x2011, + 0x4587, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c63, 0x2071, + 0x4540, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8, + 0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190, + 0x080c, 0x26ff, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1, + 0x2079, 0x4500, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c, + 0x2061, 0x1d04, 0x11d9, 0x2079, 0x4500, 0x2071, 0x0010, 0x080c, + 0x42c7, 0x2071, 0x4580, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025, + 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, + 0x2190, 0x080c, 0x26ff, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, + 0x4500, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110, + 0x080c, 0x2061, 0x1d04, 0x118e, 0x080c, 0x42c7, 0x0804, 0x118e, + 0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e, + 0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x252b, 0x2091, 0x2400, + 0x080c, 0x4052, 0x0005, 0x2091, 0x2200, 0x080c, 0x4052, 0x0005, + 0x2091, 0x2200, 0x080c, 0x4052, 0x2091, 0x2400, 0x080c, 0x4052, + 0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d, + 0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d, + 0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, + 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, + 0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c, + 0x2548, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, + 0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, + 0x0126, 0x2091, 0x2600, 0x080c, 0x2548, 0x012e, 0x010e, 0x000e, + 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2548, + 0x2091, 0x2800, 0x080c, 0x2548, 0x012e, 0x010e, 0x000e, 0x000d, + 0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4500, + 0x2071, 0x0200, 0x2069, 0x4540, 0x3d00, 0xd08c, 0x0130, 0x70ec, + 0xa084, 0x1c00, 0x78e2, 0x080c, 0x44bd, 0x3d00, 0xd084, 0x0150, + 0x2069, 0x4580, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6, + 0x080c, 0x44bd, 0x080c, 0x24dc, 0x00fe, 0x00ee, 0x00de, 0x012e, + 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002, + 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3, + 0x4002, 0x0804, 0x13b6, 0x0e04, 0x1317, 0x2061, 0x0000, 0x6018, + 0xd084, 0x1904, 0x1317, 0x7828, 0xa005, 0x1120, 0x0004, 0x1318, + 0x0804, 0x1317, 0xd0fc, 0x0148, 0x0006, 0x080c, 0x1aeb, 0x000e, + 0x0168, 0x2001, 0x4007, 0x0804, 0x13b5, 0x0006, 0x080c, 0x1add, + 0x000e, 0x0120, 0x2001, 0x4007, 0x0804, 0x13b5, 0x7910, 0xd0fc, + 0x1128, 0x2061, 0x4540, 0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4580, + 0xc19d, 0xc7fd, 0x6060, 0xa005, 0x15d0, 0x7912, 0x607f, 0x0000, + 0x7828, 0xc0fc, 0xa086, 0x0018, 0x1120, 0x00c6, 0x080c, 0x190a, + 0x00ce, 0x782b, 0x0000, 0x6078, 0xa065, 0x0190, 0x00c6, 0x609c, + 0x080c, 0x1bb8, 0x00ce, 0x609f, 0x0000, 0x080c, 0x1a1b, 0x2009, + 0x0018, 0x6087, 0x0103, 0x080c, 0x1af9, 0x1198, 0x080c, 0x1b44, + 0x7810, 0xd09c, 0x1118, 0x2061, 0x4540, 0x0020, 0x2061, 0x4580, + 0xc09c, 0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, + 0x60d2, 0x2001, 0x4005, 0x0804, 0x13b5, 0x0804, 0x13b3, 0x0005, + 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, + 0xa08a, 0x0040, 0x1a04, 0x1365, 0x0002, 0x13b3, 0x1401, 0x13cf, + 0x1435, 0x1469, 0x1469, 0x13c7, 0x1a33, 0x1473, 0x13c1, 0x13d3, + 0x13d4, 0x13d5, 0x13d6, 0x1a37, 0x13c1, 0x1480, 0x14d5, 0x1925, + 0x1a2d, 0x13d7, 0x17b4, 0x17ea, 0x1819, 0x185c, 0x1771, 0x177e, + 0x1791, 0x17a3, 0x15aa, 0x13c1, 0x1507, 0x1512, 0x1520, 0x152e, + 0x1545, 0x1553, 0x1556, 0x1564, 0x1572, 0x157c, 0x1590, 0x159c, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x15b7, 0x15c8, 0x15e2, 0x1616, + 0x163f, 0x1651, 0x1654, 0x167f, 0x16b8, 0x16ca, 0x173f, 0x174f, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x1761, 0x2100, 0xa08a, 0x0040, + 0x1a04, 0x13c1, 0x0002, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, + 0x1a59, 0x1a5f, 0x13c1, 0x13c1, 0x13c1, 0x1a63, 0x1aa3, 0x13c1, + 0x13c1, 0x13c1, 0x13c1, 0x13fc, 0x1464, 0x147b, 0x14d0, 0x1920, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x1aa7, 0x1a4b, 0x1a55, 0x18ef, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, + 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, 0x13c1, + 0x13c1, 0x13c1, 0x13c1, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, + 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13b6, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x0005, 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, 0x70c3, 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, 0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, - 0x2020, 0x70d3, 0x000a, 0x2001, 0x0001, 0x70d6, 0x2079, 0x0000, + 0x2020, 0x70d3, 0x000a, 0x2001, 0x0004, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, - 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13a3, + 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13b3, 0xa182, 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, - 0x0002, 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13a6, - 0x24a8, 0x53a5, 0x0c10, 0x0804, 0x13a3, 0x2029, 0x0000, 0x2520, + 0x0002, 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13b6, + 0x24a8, 0x53a5, 0x0c10, 0x0804, 0x13b3, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, - 0x0040, 0x7007, 0x0006, 0x81ff, 0x0904, 0x13a3, 0xa182, 0x0040, + 0x0040, 0x7007, 0x0006, 0x81ff, 0x0904, 0x13b3, 0xa182, 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, - 0x70c3, 0x4002, 0x0804, 0x13a6, 0x75d8, 0x74dc, 0x75da, 0x74de, + 0x70c3, 0x4002, 0x0804, 0x13b6, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, - 0x72ca, 0x0804, 0x13a2, 0x70c7, 0x000a, 0x70cb, 0x0001, 0x70cf, - 0x0013, 0x0804, 0x13a3, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, + 0x72ca, 0x0804, 0x13b2, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, + 0x0008, 0x0804, 0x13b3, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x05f0, 0xa40a, 0x0110, 0x1a04, - 0x13a5, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, - 0x78ae, 0x2001, 0x4005, 0x0804, 0x13a5, 0x7b7e, 0x7a7a, 0x7e86, + 0x13b5, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, + 0x78ae, 0x2001, 0x4005, 0x0804, 0x13b5, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, - 0xfffc, 0x78ae, 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13a3, + 0xfffc, 0x78ae, 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13b3, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, - 0xa005, 0x0500, 0xa40a, 0x0110, 0x1a04, 0x13a5, 0x8001, 0x7892, + 0xa005, 0x0500, 0xa40a, 0x0110, 0x1a04, 0x13b5, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, - 0x0804, 0x13a5, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, + 0x0804, 0x13b5, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, - 0x78ae, 0x0018, 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13a3, 0x2009, + 0x78ae, 0x0018, 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13b3, 0x2009, 0x0000, 0x786c, 0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, - 0x0804, 0x13a1, 0x2009, 0x4348, 0x210c, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x4388, 0x2214, 0x0804, 0x13a1, - 0x2009, 0x4349, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, - 0x13a2, 0x2011, 0x4389, 0x2214, 0x0804, 0x13a1, 0x2061, 0x4340, + 0x0804, 0x13b1, 0x2009, 0x4548, 0x210c, 0x2001, 0x01ff, 0x2004, + 0xd0fc, 0x1904, 0x13b2, 0x2011, 0x4588, 0x2214, 0x0804, 0x13b1, + 0x2009, 0x4549, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, + 0x13b2, 0x2011, 0x4589, 0x2214, 0x0804, 0x13b1, 0x2061, 0x4540, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1148, 0x2061, 0x4380, 0x6328, 0x73da, 0x632c, 0x831c, - 0x831c, 0x831c, 0x73de, 0x0804, 0x13a1, 0x2009, 0x434c, 0x210c, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x438c, - 0x2214, 0x0804, 0x13a1, 0x7918, 0x0804, 0x13a2, 0x2009, 0x434d, - 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, - 0x438d, 0x2214, 0x0804, 0x13a1, 0x2009, 0x434e, 0x210c, 0x2001, - 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x438e, 0x2214, - 0x0804, 0x13a1, 0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, - 0x13a2, 0x7a24, 0x0804, 0x13a1, 0x2011, 0x4840, 0x71c4, 0xd1fc, - 0x1110, 0x2011, 0x47c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13a0, - 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, - 0x8001, 0x2708, 0x0804, 0x13a0, 0x2061, 0x4340, 0x6118, 0x2001, - 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2061, 0x4380, 0x6218, - 0x0804, 0x13a1, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6908, - 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0804, 0x13a0, 0x71c4, - 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x1a04, 0x139c, 0x080c, - 0x230e, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13a0, - 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x1a04, 0x139c, 0xd1bc, - 0x1120, 0x2011, 0x4348, 0x2204, 0x0020, 0x2011, 0x4388, 0x2204, - 0xc0bd, 0x0006, 0x2100, 0xc0bc, 0x2012, 0x080c, 0x22b4, 0x001e, - 0x0804, 0x13a2, 0x71c4, 0x2021, 0x4349, 0x2404, 0x70c6, 0x2019, - 0x0000, 0x0030, 0x71c8, 0x2021, 0x4389, 0x2404, 0x70ca, 0xc3fd, - 0x2011, 0x15fe, 0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, - 0x1f04, 0x15e4, 0x71c4, 0x72c8, 0x0804, 0x139b, 0xa292, 0x15fe, - 0x0026, 0x2122, 0x001e, 0x080c, 0x22c6, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1110, 0xd3fc, 0x09f0, 0x0804, 0x13a3, 0x03e8, 0x00fa, - 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4340, + 0xd0fc, 0x1148, 0x2061, 0x4580, 0x6328, 0x73da, 0x632c, 0x831c, + 0x831c, 0x831c, 0x73de, 0x0804, 0x13b1, 0x2009, 0x454c, 0x210c, + 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b2, 0x2011, 0x458c, + 0x2214, 0x0804, 0x13b1, 0x7918, 0x0804, 0x13b2, 0x2009, 0x0202, + 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b2, 0x2011, + 0x0102, 0x2214, 0x0804, 0x13b1, 0x2009, 0x454d, 0x210c, 0x2001, + 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b2, 0x2011, 0x458d, 0x2214, + 0x0804, 0x13b1, 0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, + 0x13b2, 0x7a24, 0x0804, 0x13b1, 0x2011, 0x4a40, 0x71c4, 0xd1fc, + 0x1110, 0x2011, 0x49c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, + 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13b0, + 0x77c4, 0x080c, 0x1b5f, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, + 0x8001, 0x2708, 0x0804, 0x13b0, 0x2061, 0x4540, 0x6118, 0x2001, + 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b2, 0x2061, 0x4580, 0x6218, + 0x0804, 0x13b1, 0x77c4, 0x080c, 0x1b5f, 0x2091, 0x8000, 0x6908, + 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0804, 0x13b0, 0x71c4, + 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x1a04, 0x13ac, 0x080c, + 0x2373, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b0, + 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x1a04, 0x13ac, 0xd1bc, + 0x1120, 0x2011, 0x4548, 0x2204, 0x0020, 0x2011, 0x4588, 0x2204, + 0xc0bd, 0x0006, 0x2100, 0xc0bc, 0x2012, 0x080c, 0x2319, 0x001e, + 0x0804, 0x13b2, 0x71c4, 0x2021, 0x4549, 0x2404, 0x70c6, 0x2019, + 0x0000, 0x0030, 0x71c8, 0x2021, 0x4589, 0x2404, 0x70ca, 0xc3fd, + 0x2011, 0x160e, 0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, + 0x1f04, 0x15f4, 0x71c4, 0x72c8, 0x0804, 0x13ab, 0xa292, 0x160e, + 0x0026, 0x2122, 0x001e, 0x080c, 0x232b, 0x2001, 0x01ff, 0x2004, + 0xd0fc, 0x1110, 0xd3fc, 0x09f0, 0x0804, 0x13b3, 0x03e8, 0x00fa, + 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4540, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, 0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, - 0x11a0, 0x0026, 0x0016, 0x2061, 0x4380, 0x6128, 0x622c, 0x8214, + 0x11a0, 0x0026, 0x0016, 0x2061, 0x4580, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, - 0x602e, 0x71da, 0x72de, 0x001e, 0x002e, 0x0804, 0x13a1, 0x2061, - 0x4340, 0x6130, 0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, - 0x1904, 0x13a2, 0x2061, 0x4380, 0x6230, 0x70c8, 0x6032, 0x0804, - 0x13a1, 0x7918, 0x0804, 0x13a2, 0x71c4, 0xa184, 0xffcf, 0x0148, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x139c, 0x72c8, 0x0804, - 0x139b, 0x2011, 0x434d, 0x2204, 0x2112, 0x0006, 0x2019, 0x0000, - 0x080c, 0x2302, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x001e, - 0x0804, 0x13a2, 0x71c8, 0xa184, 0xffcf, 0x0128, 0x0006, 0x2110, - 0x71c4, 0x0804, 0x139b, 0x2011, 0x438d, 0x2204, 0x2112, 0x0006, - 0xc3fd, 0x080c, 0x2302, 0x002e, 0x001e, 0x0804, 0x13a1, 0x71c4, + 0x602e, 0x71da, 0x72de, 0x001e, 0x002e, 0x0804, 0x13b1, 0x2061, + 0x4540, 0x6130, 0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, + 0x1904, 0x13b2, 0x2061, 0x4580, 0x6230, 0x70c8, 0x6032, 0x0804, + 0x13b1, 0x7918, 0x0804, 0x13b2, 0x71c4, 0xa184, 0xf0cf, 0x0148, + 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13ac, 0x72c8, 0x0804, + 0x13ab, 0x0006, 0x2019, 0x0000, 0x080c, 0x2367, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13b2, 0x71c8, 0xa184, + 0xf0cf, 0x0128, 0x0006, 0x2110, 0x71c4, 0x0804, 0x13ab, 0x0006, + 0xc3fd, 0x080c, 0x2367, 0x002e, 0x001e, 0x0804, 0x13b1, 0x71c4, 0xa182, 0x0010, 0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, - 0x139c, 0x72c8, 0x0804, 0x139b, 0x2011, 0x434e, 0x2204, 0x0006, - 0x2112, 0x2019, 0x0000, 0x080c, 0x22ef, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13a2, 0x71c8, 0xa182, 0x0010, - 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x139b, 0x2011, 0x438e, - 0x2204, 0x0006, 0x2112, 0xc3fd, 0x080c, 0x22ef, 0x002e, 0x001e, - 0x0804, 0x13a1, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x1904, 0x139b, - 0xa284, 0xfffd, 0x1904, 0x139b, 0x2100, 0x7920, 0x7822, 0x2200, - 0x7a24, 0x7826, 0x0804, 0x13a1, 0x2011, 0x4840, 0x71c4, 0xd1fc, - 0x1110, 0x2011, 0x47c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa268, 0x72c8, 0x73cc, 0x74d8, 0x71c6, 0x6800, 0x70ca, - 0x73ce, 0x74da, 0x2091, 0x8000, 0x6a02, 0xd2ac, 0x1118, 0x2021, - 0x0000, 0x0078, 0xa484, 0x00ff, 0xa082, 0x0002, 0x16e8, 0x843f, - 0xa7bc, 0x00ff, 0x0130, 0xa786, 0x0002, 0x15b0, 0xa484, 0x00ff, - 0x0598, 0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, - 0x0009, 0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, - 0xa084, 0x00ff, 0x1110, 0xa73d, 0x11f8, 0x2041, 0x001d, 0x8307, - 0xa084, 0x00ff, 0x0150, 0xa842, 0x02b8, 0xa3bc, 0x00ff, 0x2500, - 0xa702, 0x0290, 0x2600, 0xa702, 0x1278, 0x2039, 0x003a, 0x6804, - 0xa705, 0x6806, 0x6b0a, 0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, - 0x2091, 0x8001, 0x0804, 0x13a3, 0x2091, 0x8001, 0x0804, 0x139d, - 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, - 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0804, 0x13a0, - 0x70c4, 0x2061, 0x4340, 0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1904, 0x13a2, 0x70c8, 0x2061, 0x4380, 0x6218, 0x601a, - 0x0804, 0x13a1, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, - 0x139c, 0x080c, 0x2332, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, - 0x0804, 0x13a0, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, - 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0804, 0x13a1, 0x77c4, - 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, - 0x6804, 0xa005, 0x0110, 0x080c, 0x2233, 0x2091, 0x8001, 0x2708, - 0x0804, 0x13a1, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, - 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x2233, 0x2091, - 0x8001, 0x2708, 0x0804, 0x13a1, 0x77c4, 0x2041, 0x0001, 0x2049, - 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b35, 0x2091, - 0x8001, 0x2708, 0x6a08, 0x0804, 0x13a1, 0x77c4, 0xd7fc, 0x0128, - 0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, - 0x0804, 0x13a5, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, - 0x1bad, 0x11e8, 0x6818, 0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, - 0x2351, 0x007e, 0x1170, 0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, - 0x4340, 0x0018, 0xc0fd, 0x2061, 0x4380, 0x782a, 0x2091, 0x8001, - 0x0005, 0x2091, 0x8001, 0x2001, 0x4005, 0x0804, 0x13a5, 0x2091, - 0x8001, 0x0804, 0x13a3, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1aa9, - 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, 0x0804, 0x13a5, - 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, - 0x8000, 0x080c, 0x1b35, 0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, - 0x4340, 0x0018, 0x2061, 0x4380, 0xc1fd, 0x6067, 0x0003, 0x607f, - 0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x080c, 0x2233, 0x2091, - 0x8001, 0x0005, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128, - 0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, - 0x0804, 0x13a5, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, - 0xd7fc, 0x1118, 0x2061, 0x4340, 0x0018, 0x2061, 0x4380, 0xc1fd, - 0x607f, 0x0000, 0x6067, 0x0002, 0x6776, 0x6083, 0x000f, 0x792a, - 0x080c, 0x2233, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, - 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118, 0x60d4, - 0xc0fd, 0x60d6, 0x080c, 0x1b35, 0x70c8, 0x6836, 0x8738, 0xa784, - 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, 0x72c8, 0xd284, 0x0128, - 0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, - 0x0804, 0x13a5, 0x72c8, 0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508, - 0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, - 0x0004, 0x2051, 0x0008, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6808, - 0xc0d4, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, - 0x1d90, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, - 0x1d50, 0x2091, 0x8000, 0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, - 0x2069, 0x0200, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, - 0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, - 0x1f04, 0x1885, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, - 0x0110, 0x1f04, 0x188e, 0x20a9, 0x00fa, 0x1f04, 0x1895, 0x2079, - 0x4300, 0x2009, 0x0018, 0x72c8, 0xd284, 0x1118, 0x2061, 0x4340, - 0x0018, 0x2061, 0x4380, 0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083, - 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, - 0x0160, 0xc0b4, 0x60d6, 0x00c6, 0x60b8, 0xa065, 0x6008, 0xc0d4, - 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x60d4, 0xa084, 0x7eff, - 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x681b, 0x0054, 0x2091, 0x8001, - 0x0005, 0xd7fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, 0x4380, - 0x71c4, 0x71c6, 0x6916, 0x81ff, 0x1110, 0x68a7, 0x0001, 0x78ac, - 0xc08c, 0x78ae, 0xd084, 0x1110, 0x080c, 0x1c00, 0x0005, 0x75d8, - 0x74dc, 0x75da, 0x74de, 0x0018, 0x2029, 0x0000, 0x2520, 0x71c4, - 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4300, 0x7dde, - 0x7cda, 0x7bd6, 0x7ad2, 0x080c, 0x1afa, 0x0904, 0x19d7, 0x20a9, - 0x0005, 0x20a1, 0x4314, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, - 0x2009, 0x0040, 0x080c, 0x1cbf, 0x0120, 0x080c, 0x1b02, 0x0804, - 0x19d7, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x1120, 0x0006, - 0x080c, 0x1fe3, 0x000e, 0xa084, 0xff00, 0x8007, 0x8009, 0x0904, - 0x1981, 0x00c6, 0x2c68, 0x080c, 0x1afa, 0x05a8, 0x2c00, 0x689e, - 0x8109, 0x1dc0, 0x609f, 0x0000, 0x00ce, 0x00c6, 0x7ddc, 0x7cd8, - 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, - 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c, - 0xa065, 0x0904, 0x1980, 0x2009, 0x0040, 0x080c, 0x1cbf, 0x1550, - 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x1168, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x000a, 0x1120, 0x0016, 0x080c, 0x1fe0, 0x001e, - 0x2d00, 0x6002, 0x0898, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1b76, - 0x00ce, 0x609f, 0x0000, 0x080c, 0x19db, 0x2009, 0x0018, 0x6008, - 0xc0cd, 0x600a, 0x6004, 0x6086, 0x080c, 0x1ab7, 0x080c, 0x1b02, - 0x0804, 0x19d7, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1b76, 0x00ce, - 0x609f, 0x0000, 0x080c, 0x19db, 0x2009, 0x0018, 0x6087, 0x0103, - 0x601b, 0x0003, 0x080c, 0x1ab7, 0x080c, 0x1b02, 0x0804, 0x19d7, - 0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1aa9, 0x01b8, 0x0018, - 0x080c, 0x1a9b, 0x0198, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, - 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x080c, 0x1ab7, - 0x080c, 0x1b02, 0x2001, 0x4007, 0x0804, 0x13a5, 0x74c4, 0x73c8, - 0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, - 0x1118, 0x2071, 0x4340, 0x0018, 0x2071, 0x4380, 0xc1fd, 0x792a, - 0x7067, 0x0005, 0x71d4, 0xa18c, 0xfe7f, 0x71d6, 0x736a, 0x726e, - 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530, - 0x611c, 0xa184, 0x0060, 0x0110, 0x080c, 0x3de5, 0x00ee, 0x6596, + 0x13ac, 0x72c8, 0x0804, 0x13ab, 0x2011, 0x454d, 0x2204, 0x0006, + 0x8104, 0x1208, 0x8108, 0x2112, 0x2019, 0x0000, 0x080c, 0x2354, + 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13b2, + 0x71c8, 0xa182, 0x0010, 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, + 0x13ab, 0x2011, 0x458d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, + 0x2112, 0xc3fd, 0x080c, 0x2354, 0x002e, 0x001e, 0x0804, 0x13b1, + 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x1904, 0x13ab, 0xa284, 0xfffd, + 0x1904, 0x13ab, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, 0x7826, + 0x0804, 0x13b1, 0x2011, 0x4a40, 0x71c4, 0xd1fc, 0x1110, 0x2011, + 0x49c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, + 0x72c8, 0x73cc, 0x74d8, 0x71c6, 0x6800, 0x70ca, 0x73ce, 0x74da, + 0x2091, 0x8000, 0x6a02, 0xd2ac, 0x1118, 0x2021, 0x0000, 0x0090, + 0xa484, 0x00ff, 0xa082, 0x0002, 0x1a04, 0x173b, 0x843f, 0xa7bc, + 0x00ff, 0x0140, 0xa786, 0x0002, 0x1904, 0x173b, 0xa484, 0x00ff, + 0x0904, 0x173b, 0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, + 0x2029, 0x0009, 0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, + 0x8307, 0xa084, 0x00ff, 0x1110, 0xa73d, 0x1138, 0x2041, 0x001d, + 0xa384, 0x00ff, 0xa082, 0x001a, 0x0210, 0xa4a4, 0x00ff, 0x8307, + 0xa084, 0x00ff, 0x0188, 0xa842, 0x02f0, 0xa086, 0x0010, 0x1120, + 0xa39c, 0x00ff, 0xa39d, 0x0f00, 0xa3bc, 0x00ff, 0x2500, 0xa702, + 0x0290, 0x2600, 0xa702, 0x1278, 0x2039, 0x003a, 0x6804, 0xa705, + 0x6806, 0x6b0a, 0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, 0x2091, + 0x8001, 0x0804, 0x13b3, 0x2091, 0x8001, 0x0804, 0x13ad, 0x77c4, + 0x080c, 0x1b5f, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, + 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0804, 0x13b0, 0x70c4, + 0x2061, 0x4540, 0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, 0xd0fc, + 0x1904, 0x13b2, 0x70c8, 0x2061, 0x4580, 0x6218, 0x601a, 0x0804, + 0x13b1, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, 0x13ac, + 0x080c, 0x2397, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, + 0x13b0, 0x77c4, 0x080c, 0x1b5f, 0x2091, 0x8000, 0x6a08, 0xc28d, + 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b1, 0x77c4, 0x080c, + 0x1b5f, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, + 0xa005, 0x0110, 0x080c, 0x2296, 0x2091, 0x8001, 0x2708, 0x0804, + 0x13b1, 0x77c4, 0x080c, 0x1b5f, 0x2091, 0x8000, 0x6a08, 0xc295, + 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x2296, 0x2091, 0x8001, + 0x2708, 0x0804, 0x13b1, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, + 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b77, 0x2091, 0x8001, + 0x2708, 0x6a08, 0x0804, 0x13b1, 0x77c4, 0xd7fc, 0x0128, 0x080c, + 0x1aeb, 0x0138, 0x0804, 0x13b5, 0x080c, 0x1add, 0x0110, 0x0804, + 0x13b5, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, 0x1bef, + 0x11e8, 0x6818, 0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, 0x23b6, + 0x007e, 0x1170, 0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, 0x4540, + 0x0018, 0xc0fd, 0x2061, 0x4580, 0x782a, 0x2091, 0x8001, 0x0005, + 0x2091, 0x8001, 0x2001, 0x4005, 0x0804, 0x13b5, 0x2091, 0x8001, + 0x0804, 0x13b3, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1aeb, 0x0138, + 0x0804, 0x13b5, 0x080c, 0x1add, 0x0110, 0x0804, 0x13b5, 0x77c6, + 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, + 0x080c, 0x1b77, 0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, 0x4540, + 0x0018, 0x2061, 0x4580, 0xc1fd, 0x6063, 0x0003, 0x607b, 0x0000, + 0x6772, 0x607f, 0x000f, 0x792a, 0x080c, 0x2296, 0x2091, 0x8001, + 0x0005, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128, 0x080c, + 0x1aeb, 0x0138, 0x0804, 0x13b5, 0x080c, 0x1add, 0x0110, 0x0804, + 0x13b5, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, + 0x1118, 0x2061, 0x4540, 0x0018, 0x2061, 0x4580, 0xc1fd, 0x607b, + 0x0000, 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a, 0x080c, + 0x2296, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, + 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118, 0x60d0, 0xc0fd, + 0x60d2, 0x080c, 0x1b77, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, + 0x1dc0, 0x2091, 0x8001, 0x0005, 0x2019, 0x0000, 0x72c8, 0xd284, + 0x0128, 0x080c, 0x1aeb, 0x0138, 0x0804, 0x13b5, 0x080c, 0x1add, + 0x0110, 0x0804, 0x13b5, 0x72c8, 0x72ca, 0x78ac, 0xa084, 0x0003, + 0x1508, 0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd, 0x2041, 0x0021, + 0x2049, 0x0004, 0x2051, 0x0008, 0x080c, 0x1b5f, 0x2091, 0x8000, + 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, + 0x001f, 0x1d90, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, + 0x0f00, 0x1d50, 0x2091, 0x8000, 0x72c8, 0x2069, 0x0100, 0xd284, + 0x1110, 0x2069, 0x0200, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, + 0xd0b4, 0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, + 0x0110, 0x1f04, 0x18a6, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, + 0xd084, 0x0110, 0x1f04, 0x18af, 0x20a9, 0x00fa, 0x1f04, 0x18b6, + 0x2079, 0x4500, 0x2009, 0x0018, 0x72c8, 0xd284, 0x1118, 0x2061, + 0x4540, 0x0018, 0x2061, 0x4580, 0xc1fd, 0x607b, 0x0000, 0x792a, + 0x6063, 0x0001, 0x607f, 0x000f, 0x60a3, 0x0000, 0x60a4, 0x60ae, + 0x60b2, 0x60d0, 0xd0b4, 0x0160, 0xc0b4, 0x60d2, 0x00c6, 0x60b4, + 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, + 0x60d0, 0xa084, 0x7eff, 0x60d2, 0x78ac, 0xc08d, 0x78ae, 0x83ff, + 0x0108, 0x0005, 0x681b, 0x0054, 0x2091, 0x8001, 0x0005, 0x73cc, + 0x080c, 0x185e, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a, 0xa185, + 0x0040, 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff, 0x1f04, + 0x18ff, 0x8421, 0x1dd0, 0x8319, 0x1db0, 0x69ee, 0x6a4a, 0x2091, + 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2069, 0x4540, 0x0010, 0x2069, + 0x4580, 0x71c4, 0x71c6, 0x6916, 0x81ff, 0x1110, 0x68a3, 0x0001, + 0x78ac, 0xc08c, 0x78ae, 0xd084, 0x1110, 0x080c, 0x1c42, 0x0005, + 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018, 0x2029, 0x0000, 0x2520, + 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4500, + 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c, 0x1b3c, 0x0904, 0x1a17, + 0x20a9, 0x0005, 0x20a1, 0x4514, 0x2091, 0x8000, 0x41a1, 0x2091, + 0x8001, 0x2009, 0x0040, 0x080c, 0x1d0b, 0x0120, 0x080c, 0x1b44, + 0x0804, 0x1a17, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x1120, + 0x0006, 0x080c, 0x2046, 0x000e, 0xa084, 0xff00, 0x8007, 0x8009, + 0x0904, 0x19c2, 0x00c6, 0x2c68, 0x080c, 0x1b3c, 0x05a8, 0x2c00, + 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000, 0x00ce, 0x00c6, 0x7ddc, + 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, + 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, + 0x689c, 0xa065, 0x0904, 0x19c1, 0x2009, 0x0040, 0x080c, 0x1d0b, + 0x1550, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x1168, 0x6004, + 0xa084, 0x00ff, 0xa086, 0x000a, 0x1120, 0x0016, 0x080c, 0x2043, + 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce, 0x00c6, 0x609c, 0x080c, + 0x1bb8, 0x00ce, 0x609f, 0x0000, 0x080c, 0x1a1b, 0x2009, 0x0018, + 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086, 0x080c, 0x1af9, 0x080c, + 0x1b44, 0x0804, 0x1a17, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bb8, + 0x00ce, 0x609f, 0x0000, 0x080c, 0x1a1b, 0x2009, 0x0018, 0x6087, + 0x0103, 0x601b, 0x0003, 0x080c, 0x1af9, 0x080c, 0x1b44, 0x0804, + 0x1a17, 0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1aeb, 0x01b8, + 0x0018, 0x080c, 0x1add, 0x0198, 0x2029, 0x0000, 0x2520, 0x2009, + 0x0018, 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x080c, + 0x1af9, 0x080c, 0x1b44, 0x2001, 0x4007, 0x0804, 0x13b5, 0x74c4, + 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, + 0xd0fc, 0x1118, 0x2071, 0x4540, 0x0018, 0x2071, 0x4580, 0xc1fd, + 0x792a, 0x7063, 0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, + 0x746e, 0x7072, 0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, + 0x611c, 0xa184, 0x0060, 0x0110, 0x080c, 0x3f66, 0x00ee, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, - 0x6023, 0x0000, 0x080c, 0x2233, 0x2091, 0x8001, 0x0005, 0x70c3, - 0x4005, 0x0804, 0x13a6, 0x20a9, 0x0005, 0x2099, 0x4314, 0x2091, + 0x6023, 0x0000, 0x080c, 0x2296, 0x2091, 0x8001, 0x0005, 0x70c3, + 0x4005, 0x0804, 0x13b6, 0x20a9, 0x0005, 0x2099, 0x4514, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, - 0x791e, 0x0804, 0x13a3, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, + 0x791e, 0x0804, 0x13b3, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000, 0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, - 0x70ca, 0x0804, 0x13a6, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, - 0x1a04, 0x139c, 0x7966, 0x0804, 0x13a3, 0x7964, 0x71c6, 0x0804, - 0x13a3, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0804, 0x13a3, 0x7900, - 0x71c6, 0x0804, 0x13a3, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, + 0x70ca, 0x0804, 0x13b6, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, + 0x1a04, 0x13ac, 0x7966, 0x0804, 0x13b3, 0x7964, 0x71c6, 0x0804, + 0x13b3, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0804, 0x13b3, 0x7900, + 0x71c6, 0x0804, 0x13b3, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c, 0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, - 0x810c, 0x81ff, 0x1904, 0x139d, 0x8210, 0x7a0e, 0xd28c, 0x0538, + 0x810c, 0x81ff, 0x1904, 0x13ad, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, - 0x01c0, 0x8108, 0x2019, 0x0041, 0x2011, 0x8b4e, 0x2312, 0x2019, + 0x01c0, 0x8108, 0x2019, 0x0041, 0x2011, 0x8d4e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, - 0x0006, 0x2011, 0x8b53, 0x2112, 0x2011, 0x8b73, 0x2312, 0x7904, - 0x7806, 0x0804, 0x13a2, 0x7804, 0x70c6, 0x0804, 0x13a3, 0x71c4, - 0xd1fc, 0x1118, 0x2011, 0x47c0, 0x0010, 0x2011, 0x4840, 0x8107, + 0x0006, 0x2011, 0x8d53, 0x2112, 0x2011, 0x8d73, 0x2312, 0x7904, + 0x7806, 0x0804, 0x13b2, 0x7804, 0x70c6, 0x0804, 0x13b3, 0x71c4, + 0xd1fc, 0x1118, 0x2011, 0x49c0, 0x0010, 0x2011, 0x4a40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc, 0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, - 0x0001, 0x6b0c, 0x0804, 0x13a0, 0x0016, 0x7814, 0xd0f4, 0x0138, - 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0050, 0xd0fc, - 0x0138, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0008, - 0xa006, 0x001e, 0x0005, 0x0016, 0x7814, 0xd0f4, 0x0138, 0x2001, - 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e, - 0x0005, 0x0016, 0x7814, 0xd0fc, 0x0138, 0x2001, 0x4007, 0x70db, - 0x0001, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e, 0x0005, 0x7112, - 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, - 0x0001, 0x8108, 0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, - 0x0000, 0x6084, 0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, - 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, - 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, - 0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, - 0xa421, 0x7008, 0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, - 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, - 0x01e0, 0x0005, 0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, - 0x0000, 0x0005, 0x00f6, 0x2079, 0x4300, 0x7848, 0x2062, 0x2c00, - 0xa005, 0x1110, 0x080c, 0x243b, 0x784a, 0x00fe, 0x0005, 0x2011, - 0x8d00, 0x7a4a, 0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, - 0x2010, 0x0cc8, 0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, - 0x1118, 0x2011, 0x48c0, 0x0010, 0x2011, 0x68c0, 0xa784, 0x0f00, - 0x800b, 0xa784, 0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, - 0xa105, 0xa268, 0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, - 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, - 0xd7fc, 0x1128, 0x2009, 0x4353, 0x2071, 0x4340, 0x0020, 0x2009, - 0x4393, 0x2071, 0x4380, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, - 0x1138, 0x2060, 0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, - 0x2009, 0x0000, 0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, - 0x0421, 0x080c, 0x1d30, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, - 0x6812, 0x1d88, 0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, - 0x2d00, 0x2060, 0x080c, 0x2580, 0x00ee, 0x0005, 0xa065, 0x0160, - 0x2008, 0x609c, 0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, - 0x0cc0, 0x7848, 0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, - 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, - 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, - 0x1128, 0x2071, 0x4340, 0x2031, 0x43c0, 0x0020, 0x2071, 0x4380, - 0x2031, 0x45c0, 0x7050, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, - 0x8000, 0x7052, 0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, - 0x2079, 0x4340, 0x0010, 0x2079, 0x4380, 0x080c, 0x1b1d, 0x2091, - 0x8000, 0x6804, 0x780a, 0xa065, 0x0904, 0x1bfe, 0x0030, 0x2c00, - 0x780a, 0x2060, 0x6000, 0xa065, 0x05c8, 0x6010, 0xa306, 0x1db8, - 0x600c, 0xa206, 0x1da0, 0x2c28, 0x784c, 0xac06, 0x1108, 0x0458, - 0x6804, 0xac06, 0x1140, 0x6000, 0x2060, 0x6806, 0xa005, 0x1118, - 0x6803, 0x0000, 0x0048, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486, - 0x0000, 0x1110, 0x2c00, 0x6802, 0x2560, 0x00fe, 0x080c, 0x1b85, - 0x00f6, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe, 0x080c, 0x1d30, - 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812, 0x1118, - 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, 0x00fe, 0x0005, - 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108, 0xc7fd, 0x2041, - 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x080c, - 0x1b35, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc, 0xff00, 0x873f, - 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091, 0x8001, 0x007e, - 0x0005, 0x786c, 0x2009, 0x8b74, 0x210c, 0xa10d, 0x0118, 0xa065, - 0x0804, 0x1ffe, 0x2061, 0x0000, 0x6018, 0xd084, 0x11b8, 0x7810, - 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4340, 0x0028, - 0xc08d, 0x7812, 0x2069, 0x4380, 0xc7fd, 0x2091, 0x8000, 0x681c, - 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108, 0x0005, 0xa08c, - 0xfff0, 0x0110, 0x080c, 0x243b, 0x0002, 0x1c5d, 0x1c60, 0x1c66, - 0x1c6a, 0x1c5e, 0x1c6e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c73, 0x1c9f, - 0x1ca2, 0x1ca7, 0x1c5e, 0x1c5e, 0x1c5e, 0x0005, 0x080c, 0x243b, - 0x080c, 0x1c00, 0x2001, 0x8001, 0x0804, 0x1cb0, 0x2001, 0x8003, - 0x0804, 0x1cb0, 0x2001, 0x8004, 0x0804, 0x1cb0, 0x080c, 0x1c00, - 0x2001, 0x8006, 0x04e8, 0x2091, 0x8000, 0x0076, 0xd7fc, 0x1128, - 0x2069, 0x4340, 0x2039, 0x0009, 0x0020, 0x2069, 0x4380, 0x2039, - 0x0009, 0x6800, 0xa086, 0x0000, 0x0128, 0x000e, 0x6f1e, 0x2091, - 0x8001, 0x0005, 0x6874, 0x007e, 0xa0bc, 0xff00, 0x2041, 0x0021, - 0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1b35, 0x8738, 0xa784, - 0x001f, 0x1dd0, 0x2091, 0x8001, 0x2001, 0x800a, 0x0088, 0x2001, - 0x800c, 0x0070, 0x080c, 0x1c00, 0x2001, 0x800d, 0x0048, 0xd7fc, - 0x0110, 0x78ec, 0x0008, 0x78e4, 0x70c6, 0x2001, 0x800e, 0x0000, - 0x70c2, 0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010, 0x70db, 0x0001, - 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x0005, 0xac80, - 0x0001, 0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, - 0x07ff, 0x0100, 0x7018, 0x0006, 0x701c, 0x0006, 0x7020, 0x0006, - 0x7024, 0x0006, 0x7112, 0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, - 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, - 0x0002, 0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, - 0x7007, 0x0004, 0x000e, 0x7026, 0x000e, 0x7022, 0x000e, 0x701e, - 0x000e, 0x701a, 0x0005, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, - 0x6c0e, 0x681f, 0x0201, 0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, - 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, 0x1d80, 0x0005, - 0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160, - 0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019, - 0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019, - 0x1c0c, 0x2021, 0x000c, 0x0030, 0x2019, 0x1c09, 0x2021, 0x0009, - 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005, - 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, 0x7868, 0xa005, 0x796a, - 0x0110, 0x2c02, 0x0008, 0x796e, 0x0005, 0x00c6, 0x2061, 0x4300, - 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, - 0x0110, 0x2d02, 0x0008, 0x616e, 0x00ce, 0x0005, 0x2091, 0x8000, - 0x2c04, 0x786e, 0xa005, 0x1108, 0x786a, 0x2091, 0x8001, 0x609c, - 0xa005, 0x0188, 0x00c6, 0x2060, 0x2008, 0x609c, 0xa005, 0x0138, - 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848, - 0x794a, 0x2062, 0x00ce, 0x7848, 0x2062, 0x609f, 0x0000, 0xac85, - 0x0000, 0x1110, 0x080c, 0x243b, 0x784a, 0x0005, 0x20a9, 0x0010, - 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x1d7a, - 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, - 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, - 0x1d8a, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x1d8a, 0x0006, - 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, - 0x3200, 0xa085, 0x1000, 0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904, - 0x1e5b, 0x7810, 0x2050, 0x7800, 0xd08c, 0x0100, 0x080c, 0x1afa, - 0x0904, 0x1e5b, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, 0x2009, - 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, 0x2009, - 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, - 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0110, - 0x080c, 0x1afa, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0x2091, - 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, 0x88ff, - 0x0904, 0x1e48, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, - 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1e48, 0xa046, 0x7218, 0x731c, - 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, - 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0118, - 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1e48, 0x8cff, - 0x0110, 0x080c, 0x1b02, 0x00ce, 0x080c, 0x1b02, 0xa046, 0x7888, - 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, 0xdac4, - 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, - 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, - 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, 0x1118, - 0x2069, 0x4340, 0x0010, 0x2069, 0x4380, 0x2091, 0x8000, 0x681f, - 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, 0x788b, - 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0098, - 0x00ce, 0x788b, 0x0000, 0x080c, 0x1fb9, 0x6004, 0xa084, 0x000f, - 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f, - 0x0019, 0x0804, 0x1da4, 0x0005, 0x0002, 0x1e6d, 0x1e88, 0x1ea1, - 0x1e6d, 0x1eae, 0x1e7e, 0x1e6d, 0x1e6d, 0x1e6d, 0x1e86, 0x1e9f, - 0x1e6d, 0x1e6d, 0x1e6d, 0x1e6d, 0x1e6d, 0x2039, 0x0400, 0x78bc, - 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1eea, 0x609c, - 0x78ba, 0x609f, 0x0000, 0x080c, 0x1fa5, 0x0005, 0x78bc, 0xd0c4, - 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, 0x1fe3, - 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, 0x8007, - 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1eea, 0x0120, - 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f05, 0x0005, 0x080c, - 0x1fe0, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, 0x0828, - 0x080c, 0x1eea, 0x1110, 0x0804, 0x1f05, 0x0005, 0x78bc, 0xd0c4, - 0x0110, 0x0804, 0x1e6d, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, - 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, 0xff00, - 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011, - 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, 0x080c, - 0x1b1d, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, - 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, - 0x1f04, 0x1ed2, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c, - 0x1b02, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, - 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, - 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, 0xc0c4, - 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, 0x2530, - 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984, - 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c, 0x3de5, 0x6596, - 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4380, 0xd7fc, 0x1110, - 0x2071, 0x4340, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0120, - 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, - 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, - 0x60c2, 0x2091, 0x8000, 0x6e08, 0xd684, 0x0170, 0xd9fc, 0x1160, - 0x2091, 0x8001, 0x080c, 0x1b85, 0x2091, 0x8000, 0x080c, 0x1d30, - 0x2091, 0x8001, 0x0804, 0x1fa3, 0x6024, 0xa096, 0x0001, 0x1110, - 0x8000, 0x6026, 0x6a10, 0x6814, 0xa202, 0x0268, 0x0160, 0x2091, - 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, - 0x1fa5, 0x0804, 0x1fa3, 0x2c08, 0xd9fc, 0x01f0, 0x6800, 0xa065, - 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0168, 0x704c, 0xa206, - 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002, 0xa005, 0x1108, 0x6902, - 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060, 0x080c, 0x2580, 0x6e08, - 0x2160, 0x6202, 0x6906, 0x0050, 0x6800, 0x6902, 0xa065, 0x0110, - 0x6102, 0x0008, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc, - 0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a, - 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0128, 0xa6b6, 0x0040, - 0x6e0a, 0x080c, 0x1b96, 0x00ee, 0x0005, 0x6008, 0xa705, 0x600a, - 0x2091, 0x8000, 0x080c, 0x1d30, 0x2091, 0x8001, 0x78b8, 0xa065, - 0x0128, 0x609c, 0x78ba, 0x609f, 0x0000, 0x0c78, 0x78b6, 0x78ba, - 0x0005, 0x7970, 0x7874, 0x2818, 0xd384, 0x0118, 0x8000, 0xa112, - 0x0220, 0x8000, 0xa112, 0x1278, 0xc384, 0x7a7c, 0x721a, 0x7a78, - 0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222, 0x7a80, 0x7226, 0xa006, - 0xd384, 0x0108, 0x8000, 0x7876, 0x70d2, 0x781c, 0xa005, 0x0138, - 0x8001, 0x781e, 0x1120, 0x0e04, 0x1fdf, 0x2091, 0x4080, 0x0005, - 0x2039, 0x1ff5, 0x0010, 0x2039, 0x1ffb, 0x2704, 0xa005, 0x0160, - 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, - 0x6916, 0x680e, 0x8738, 0x0c88, 0x0005, 0x0003, 0x0009, 0x000f, - 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, - 0x780c, 0x0002, 0x21a7, 0x2182, 0x2006, 0x2076, 0x2039, 0x8b74, - 0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086, 0x0103, 0x1904, 0x2060, - 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, 0x11d8, 0x0804, 0x2060, - 0x8603, 0xa080, 0x8b55, 0x620c, 0x2202, 0x8000, 0x6210, 0x2202, - 0x080c, 0x1d4e, 0x8630, 0xa68e, 0x000f, 0x0904, 0x20e1, 0x786c, - 0xa065, 0x1d08, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, - 0x0005, 0xa682, 0x0003, 0x1a04, 0x20e1, 0x2091, 0x8000, 0x2069, - 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8b55, 0x2204, 0x70c6, - 0x8210, 0x2204, 0x70ca, 0xd684, 0x1130, 0x8210, 0x2204, 0x70da, - 0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, - 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, - 0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x0804, 0x20e1, - 0x263a, 0x080c, 0x21ad, 0x1904, 0x21c9, 0x786c, 0xa065, 0x1904, - 0x200b, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, - 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804, 0x21c9, 0x2039, 0x8b74, - 0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086, 0x0103, 0x1904, 0x20cb, - 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, 0x11b8, 0x0804, 0x20cb, - 0xa680, 0x8b55, 0x620c, 0x2202, 0x080c, 0x1d4e, 0x8630, 0xa68e, - 0x001e, 0x0904, 0x20e1, 0x786c, 0xa065, 0x1d28, 0x7808, 0xa602, - 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0006, 0x1a04, - 0x20e1, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, - 0x2011, 0x8b55, 0x2009, 0x8b4e, 0x26a8, 0x211c, 0x2204, 0x201a, - 0x8108, 0x8210, 0x1f04, 0x20ad, 0xa685, 0x8030, 0x70c2, 0x681b, - 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, - 0x8001, 0xa006, 0x2009, 0x8b75, 0x200a, 0x203a, 0x0005, 0x7810, - 0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c, 0x21ad, 0x1904, 0x21c9, - 0x786c, 0xa065, 0x1904, 0x207b, 0x2091, 0x8000, 0x7810, 0xa084, - 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804, - 0x21c9, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, 0x70d4, 0xa102, - 0x0228, 0x0168, 0x7b90, 0xa302, 0x1150, 0x0010, 0x8002, 0x1138, - 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0005, 0xa184, - 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, - 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a, - 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0130, 0x7aa4, 0xa211, - 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, 0x7003, 0x0000, - 0x2009, 0x8b54, 0x260a, 0x8109, 0x2198, 0x2104, 0xd084, 0x0108, - 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603, 0x7012, 0x7007, - 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, 0x1208, 0xa006, 0x2028, + 0x0001, 0x6b0c, 0x6800, 0x70da, 0x0804, 0x13b0, 0x0016, 0x7814, + 0xd0f4, 0x0138, 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, + 0x0050, 0xd0fc, 0x0138, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, + 0x0001, 0x0008, 0xa006, 0x001e, 0x0005, 0x0016, 0x7814, 0xd0f4, + 0x0138, 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0008, + 0xa006, 0x001e, 0x0005, 0x0016, 0x7814, 0xd0fc, 0x0138, 0x2001, + 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e, + 0x0005, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0110, 0x7422, + 0x7526, 0xac80, 0x0001, 0x8108, 0x810c, 0x81a9, 0x8098, 0x20a1, + 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x797c, - 0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0120, 0x7b84, 0xa319, - 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x01d0, - 0x7d10, 0x2031, 0x8b54, 0x2634, 0x78a8, 0x8000, 0x78aa, 0xd08c, - 0x1138, 0x7007, 0x0006, 0x7004, 0xd094, 0x1de8, 0x0804, 0x20e3, - 0x2069, 0x4347, 0x206b, 0x0003, 0x78ac, 0xa085, 0x0300, 0x78ae, - 0xa006, 0x0048, 0x2030, 0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10, - 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001, 0x78aa, 0x7007, 0x0006, - 0x263a, 0x7003, 0x0001, 0x711a, 0x721e, 0xd5c4, 0x0110, 0x7322, - 0x7426, 0x0005, 0x6084, 0xa086, 0x0103, 0x11d8, 0x6114, 0x6018, - 0xa105, 0x11b8, 0x2069, 0x0000, 0x6818, 0xd084, 0x1190, 0x600c, - 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, - 0x4080, 0x080c, 0x1d4e, 0x0e04, 0x21a0, 0x786c, 0xa065, 0x1d10, - 0x0005, 0x0059, 0x1530, 0x786c, 0xa065, 0x19e0, 0x0410, 0x0029, - 0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0, 0x6084, 0xa086, 0x0103, - 0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, 0x1138, 0x7804, - 0xd0a4, 0x0120, 0x080c, 0x1d4e, 0xa006, 0x0005, 0x0079, 0x1118, - 0xa085, 0x0001, 0x0005, 0x00b9, 0x1110, 0x2041, 0x0001, 0x7d10, - 0x0005, 0x88ff, 0x0110, 0x2091, 0x4080, 0x0005, 0x7b90, 0x7994, - 0x70d4, 0xa102, 0x1118, 0xa385, 0x0000, 0x0005, 0x0210, 0xa302, - 0x0005, 0x8002, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, - 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, - 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, - 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005, 0x0110, 0x2009, - 0x0040, 0x080c, 0x1ab7, 0x01d0, 0x78a8, 0x8000, 0x78aa, 0xd08c, - 0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, - 0x4380, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac, - 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0068, 0x78ab, 0x0000, - 0x080c, 0x1d4e, 0x7990, 0x7894, 0x8000, 0xa10a, 0x1208, 0xa006, - 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, 0x0005, - 0x2138, 0xd7fc, 0x1118, 0x2009, 0x4359, 0x0010, 0x2009, 0x4399, - 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, 0x4380, 0x2079, 0x0100, - 0xd7fc, 0x1120, 0x2009, 0x4340, 0x2079, 0x0200, 0x2104, 0xa086, - 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0x4345, 0x0010, 0x2009, - 0x4385, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084, 0x00c0, 0x1110, - 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, 0x0002, 0x2069, 0x4300, - 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x22a9, 0x2071, 0x4380, - 0x2079, 0x0100, 0x2021, 0x45bf, 0x784b, 0x000f, 0x2001, 0x01ff, - 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3c3b, 0x0030, 0x20a1, 0x012b, - 0x2019, 0x3c3b, 0xd184, 0x0110, 0x20a1, 0x022b, 0x2304, 0xa005, - 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, - 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, - 0x0000, 0x78af, 0x2020, 0x1f04, 0x2287, 0x7003, 0x0000, 0x0016, - 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c, 0x23bd, 0x001e, - 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, 0x7806, 0x780f, 0x9000, - 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, 0x0308, 0x7456, 0x7053, - 0x0000, 0x8109, 0x0140, 0x2071, 0x4340, 0x2079, 0x0200, 0x2021, - 0x43bf, 0x0804, 0x2264, 0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, - 0x1110, 0x2011, 0x0201, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, - 0xa105, 0x2012, 0x001e, 0x080c, 0x23bd, 0x0005, 0x2011, 0x0101, - 0xd3fc, 0x1110, 0x2011, 0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, - 0x22ce, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, - 0x0005, 0x2019, 0x0002, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, - 0x1f04, 0x22df, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, - 0x200a, 0x8319, 0x0118, 0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, - 0x0101, 0xd3fc, 0x1110, 0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, - 0x1f04, 0x22f7, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, - 0x2012, 0x0005, 0x2011, 0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, - 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, - 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, - 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, + 0xa108, 0x7a78, 0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0120, 0x7b84, + 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8, 0x7003, 0x0001, + 0x7007, 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0110, 0x7322, + 0x7426, 0xa084, 0x01e0, 0x0005, 0x7848, 0xa065, 0x0120, 0x2c04, + 0x784a, 0x2063, 0x0000, 0x0005, 0x00f6, 0x2079, 0x4500, 0x7848, + 0x2062, 0x2c00, 0xa005, 0x1110, 0x080c, 0x252b, 0x784a, 0x00fe, + 0x0005, 0x2011, 0x8f00, 0x7a4a, 0x7bc4, 0x8319, 0x0128, 0xa280, + 0x0032, 0x2012, 0x2010, 0x0cc8, 0x2013, 0x0000, 0x0005, 0x0016, + 0x0026, 0xd7fc, 0x1118, 0x2011, 0x4ac0, 0x0010, 0x2011, 0x6ac0, + 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0120, 0x8003, 0x8003, + 0x8003, 0x8003, 0xa105, 0xa268, 0x002e, 0x001e, 0x0005, 0x0c39, + 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, + 0x690a, 0x00e6, 0xd7fc, 0x1128, 0x2009, 0x4552, 0x2071, 0x4540, + 0x0020, 0x2009, 0x4592, 0x2071, 0x4580, 0x210c, 0x6804, 0xa005, + 0x0148, 0xa116, 0x1138, 0x2060, 0x6000, 0x6806, 0x0016, 0x200b, + 0x0000, 0x0018, 0x2009, 0x0000, 0x0016, 0x6804, 0xa065, 0x0178, + 0x6000, 0x6806, 0x0421, 0x080c, 0x1d7c, 0x6810, 0x7908, 0x8109, + 0x790a, 0x8001, 0x6812, 0x1d88, 0x7910, 0xc1a5, 0x7912, 0x001e, + 0x6902, 0x6906, 0x2d00, 0x2060, 0x080c, 0x2672, 0x00ee, 0x0005, + 0xa065, 0x0160, 0x2008, 0x609c, 0xa005, 0x0128, 0x2062, 0x609f, + 0x0000, 0xa065, 0x0cc0, 0x7848, 0x794a, 0x2062, 0x0005, 0x6007, + 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, + 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x0005, + 0x00e6, 0xd7fc, 0x1128, 0x2071, 0x4540, 0x2031, 0x45c0, 0x0020, + 0x2071, 0x4580, 0x2031, 0x47c0, 0x704c, 0xa08c, 0x0200, 0x1128, + 0xa608, 0x2d0a, 0x8000, 0x704e, 0xa006, 0x00ee, 0x0005, 0x00f6, + 0xd7fc, 0x1118, 0x2079, 0x4540, 0x0010, 0x2079, 0x4580, 0x080c, + 0x1b5f, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0904, 0x1c40, + 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065, 0x05c8, 0x6010, + 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0, 0x2c28, 0x7848, 0xac06, + 0x1108, 0x0458, 0x6804, 0xac06, 0x1140, 0x6000, 0x2060, 0x6806, + 0xa005, 0x1118, 0x6803, 0x0000, 0x0048, 0x6400, 0x7808, 0x2060, + 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00, 0x6802, 0x2560, 0x00fe, + 0x080c, 0x1bc7, 0x00f6, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe, + 0x080c, 0x1d7c, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, + 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, + 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108, + 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, + 0x8000, 0x080c, 0x1b77, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc, + 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091, + 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8d74, 0x210c, 0xa10d, + 0x0118, 0xa065, 0x0804, 0x2061, 0x2061, 0x0000, 0x6018, 0xd084, + 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069, + 0x4540, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4580, 0xc7fd, 0x2091, + 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108, + 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x252b, 0x0002, 0x1c9f, + 0x1ca2, 0x1ca8, 0x1cac, 0x1ca0, 0x1cb0, 0x1ca0, 0x1ca0, 0x1ca0, + 0x1cb6, 0x1ce2, 0x1ce5, 0x1cea, 0x1cf3, 0x1ca0, 0x1ca0, 0x0005, + 0x080c, 0x252b, 0x080c, 0x1c42, 0x2001, 0x8001, 0x0804, 0x1cfc, + 0x2001, 0x8003, 0x0804, 0x1cfc, 0x2001, 0x8004, 0x0804, 0x1cfc, + 0x080c, 0x1c42, 0x2001, 0x8006, 0x0804, 0x1cfc, 0x2091, 0x8000, + 0x0076, 0xd7fc, 0x1128, 0x2069, 0x4540, 0x2039, 0x0009, 0x0020, + 0x2069, 0x4580, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0128, + 0x000e, 0x6f1e, 0x2091, 0x8001, 0x0005, 0x6870, 0x007e, 0xa0bc, + 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x080c, + 0x1b77, 0x8738, 0xa784, 0x001f, 0x1dd0, 0x2091, 0x8001, 0x2001, + 0x800a, 0x00d0, 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c42, 0x2001, + 0x800d, 0x0090, 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0, 0x70c6, + 0x2001, 0x800e, 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008, 0x78e8, + 0x70c6, 0x2001, 0x000d, 0x0000, 0x70c2, 0xd7fc, 0x1118, 0x70db, + 0x0000, 0x0010, 0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, + 0x2091, 0x4080, 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518, 0x2099, + 0x0030, 0x20a0, 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018, 0x0006, + 0x701c, 0x0006, 0x7020, 0x0006, 0x7024, 0x0006, 0x7112, 0x81ac, + 0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, + 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x1110, + 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x000e, 0x7026, + 0x000e, 0x7022, 0x000e, 0x701e, 0x000e, 0x701a, 0x0005, 0x2011, + 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201, 0x6803, + 0xfd20, 0x6807, 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, + 0x0004, 0x8109, 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520, 0x2029, + 0x0001, 0x7814, 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019, 0x0c0a, + 0x2021, 0x000a, 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x0070, + 0x70ec, 0xd0e4, 0x1128, 0x2019, 0x1c0c, 0x2021, 0x000c, 0x0030, + 0x2019, 0x1c09, 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, + 0x6d1e, 0x6807, 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08, 0x2063, + 0x0000, 0x7868, 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008, 0x796e, + 0x0005, 0x00c6, 0x2061, 0x4500, 0x6887, 0x0103, 0x2d08, 0x206b, + 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, + 0x00ce, 0x0005, 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005, 0x1108, + 0x786a, 0x2091, 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6, 0x2060, + 0x2008, 0x609c, 0xa005, 0x0138, 0x2062, 0x609f, 0x0000, 0xa065, + 0x609c, 0xa005, 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce, 0x7848, + 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x1110, 0x080c, 0x252b, + 0x784a, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, + 0x1208, 0xa200, 0x1f04, 0x1dc6, 0x8086, 0x818e, 0x0005, 0x0156, + 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, + 0x0228, 0xa11a, 0x1220, 0x1f04, 0x1dd6, 0x0028, 0xa11a, 0x2308, + 0x8210, 0x1f04, 0x1dd6, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, + 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, + 0x7d74, 0x70d0, 0xa506, 0x0904, 0x1ea4, 0x7810, 0x2050, 0x080c, + 0x1b3c, 0x0904, 0x1ea4, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, + 0x2009, 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, + 0x2009, 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, + 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, + 0x0110, 0x080c, 0x1b3c, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, + 0x2091, 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, + 0x88ff, 0x0904, 0x1e91, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, + 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1e91, 0xa046, 0x7218, + 0x731c, 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, + 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, + 0x0118, 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1e91, + 0x8cff, 0x0110, 0x080c, 0x1b44, 0x00ce, 0x080c, 0x1b44, 0xa046, + 0x7888, 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, + 0xdac4, 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, + 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, + 0x731e, 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, + 0x1118, 0x2069, 0x4540, 0x0010, 0x2069, 0x4580, 0x2091, 0x8000, + 0x681f, 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, + 0x788b, 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, + 0x0098, 0x00ce, 0x788b, 0x0000, 0x080c, 0x201c, 0x6004, 0xa084, + 0x000f, 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, + 0x000f, 0x0019, 0x0804, 0x1df0, 0x0005, 0x0002, 0x1eb6, 0x1ed1, + 0x1eea, 0x1eb6, 0x1ef7, 0x1ec7, 0x1eb6, 0x1eb6, 0x1eb6, 0x1ecf, + 0x1ee8, 0x1eb6, 0x1eb6, 0x1eb6, 0x1eb6, 0x1eb6, 0x2039, 0x0400, + 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1f33, + 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, 0x2008, 0x0005, 0x78bc, + 0xd0c4, 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, + 0x2046, 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, + 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1f33, + 0x0120, 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f4e, 0x0005, + 0x080c, 0x2043, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, + 0x0828, 0x080c, 0x1f33, 0x1110, 0x0804, 0x1f4e, 0x0005, 0x78bc, + 0xd0c4, 0x0110, 0x0804, 0x1eb6, 0x78bf, 0x0000, 0x6714, 0x2011, + 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, + 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, + 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, + 0x080c, 0x1b5f, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, + 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, + 0x8001, 0x1f04, 0x1f1b, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, + 0x080c, 0x1b44, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, + 0x78b6, 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, + 0xad06, 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, + 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, + 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, + 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c, 0x3f66, + 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4580, 0xd7fc, + 0x1110, 0x2071, 0x4540, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, + 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0, 0xa168, + 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c4, + 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138, 0xd7fc, + 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08, 0xd684, + 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1bc7, 0x2091, + 0x8000, 0x080c, 0x1d7c, 0x2091, 0x8001, 0x7814, 0xd0c4, 0x0904, + 0x2006, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x2006, 0xd0fc, + 0x1110, 0x0804, 0x2006, 0x601b, 0x0021, 0x0804, 0x2006, 0x6024, + 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814, 0xa202, + 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, + 0x609f, 0x0000, 0x080c, 0x2008, 0x0804, 0x2006, 0x2c08, 0xd9fc, + 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002, + 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002, + 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060, + 0x080c, 0x2672, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050, 0x6800, + 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160, 0x6003, + 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, + 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, + 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1bd8, 0x00ee, 0x0005, + 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1d7c, 0x2091, + 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f, 0x0000, + 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818, 0xd384, + 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278, 0xc384, + 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222, + 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876, 0x70d2, + 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04, 0x2042, + 0x2091, 0x4080, 0x0005, 0x2039, 0x2058, 0x0010, 0x2039, 0x205e, + 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, + 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88, 0x0005, + 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, + 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x220a, 0x21e5, 0x2069, + 0x20d9, 0x2039, 0x8d74, 0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086, + 0x0103, 0x1904, 0x20c3, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, + 0x11d8, 0x0804, 0x20c3, 0x8603, 0xa080, 0x8d55, 0x620c, 0x2202, + 0x8000, 0x6210, 0x2202, 0x080c, 0x1d9a, 0x8630, 0xa68e, 0x000f, + 0x0904, 0x2144, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602, 0x1220, + 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04, 0x2144, + 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, + 0x8d55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684, 0x1130, + 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685, 0x8020, + 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, + 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad, + 0x7812, 0x0804, 0x2144, 0x263a, 0x080c, 0x2210, 0x1904, 0x222c, + 0x786c, 0xa065, 0x1904, 0x206e, 0x2091, 0x8000, 0x7810, 0xa084, + 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804, + 0x222c, 0x2039, 0x8d74, 0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086, + 0x0103, 0x1904, 0x212e, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, + 0x11b8, 0x0804, 0x212e, 0xa680, 0x8d55, 0x620c, 0x2202, 0x080c, + 0x1d9a, 0x8630, 0xa68e, 0x001e, 0x0904, 0x2144, 0x786c, 0xa065, + 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, + 0xa682, 0x0006, 0x1a04, 0x2144, 0x2091, 0x8000, 0x2069, 0x0000, + 0x6818, 0xd084, 0x11f8, 0x2011, 0x8d55, 0x2009, 0x8d4e, 0x26a8, + 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2110, 0xa685, + 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, + 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8d75, 0x200a, + 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c, + 0x2210, 0x1904, 0x222c, 0x786c, 0xa065, 0x1904, 0x20de, 0x2091, + 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, + 0x2091, 0x8001, 0x0804, 0x222c, 0x2091, 0x8000, 0x7007, 0x0004, + 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302, 0x1150, + 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, + 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, + 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, + 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, + 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, + 0x0030, 0x7003, 0x0000, 0x2009, 0x8d54, 0x260a, 0x8109, 0x2198, + 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, + 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, + 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f, + 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, + 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4, + 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8, + 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8d54, 0x2634, 0x78a8, + 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004, 0xd094, + 0x1de8, 0x0804, 0x2146, 0x2069, 0x4547, 0x206b, 0x0003, 0x78ac, + 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6, 0x2091, + 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001, + 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e, + 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086, 0x0103, + 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000, 0x6818, + 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, + 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1d9a, 0x0e04, 0x2203, + 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c, 0xa065, + 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0, + 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086, + 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1d9a, 0xa006, + 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9, 0x1110, + 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091, 0x4080, + 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385, 0x0000, + 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184, 0xff00, + 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, + 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, + 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, + 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1af9, 0x01d0, 0x78a8, + 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069, + 0x4540, 0x0010, 0x2069, 0x4580, 0x2091, 0x8000, 0x681f, 0x0003, + 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, + 0x0068, 0x78ab, 0x0000, 0x080c, 0x1d9a, 0x7990, 0x7894, 0x8000, + 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, + 0x2091, 0x8001, 0x0005, 0x2138, 0xd7fc, 0x1118, 0x2009, 0x4558, + 0x0010, 0x2009, 0x4598, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, + 0x4580, 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4540, 0x2079, + 0x0200, 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, + 0x4545, 0x0010, 0x2009, 0x4585, 0x2104, 0xa005, 0x1130, 0x7830, + 0xa084, 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, + 0x0002, 0x2069, 0x4500, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, + 0x230c, 0x2071, 0x4580, 0x2079, 0x0100, 0x2021, 0x47bf, 0x784b, + 0x000f, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3dc2, + 0x0030, 0x20a1, 0x012b, 0x2019, 0x3dc2, 0xd184, 0x0110, 0x20a1, + 0x022b, 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, + 0x2398, 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, + 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x22ea, + 0x7003, 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, + 0x080c, 0x2422, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, + 0x7806, 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, + 0x2f08, 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4540, + 0x2079, 0x0200, 0x2021, 0x45bf, 0x0804, 0x22c7, 0x080c, 0x24dc, + 0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201, + 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e, + 0x080c, 0x2422, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011, + 0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, 0x2333, 0xa18c, 0x0e00, + 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002, + 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x2344, 0xa294, + 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118, + 0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, + 0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x235c, 0xa18c, + 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011, + 0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa084, 0xf0cf, + 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, + 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, + 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, + 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, + 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, - 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, - 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, - 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, - 0xa28c, 0x0020, 0x0118, 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, - 0x1108, 0xc3ed, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, - 0x0005, 0x2091, 0x8000, 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, - 0x23a1, 0xd1fc, 0x0118, 0x2061, 0x8ad0, 0x0010, 0x2061, 0x89c0, - 0x080c, 0x23a9, 0x0538, 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, - 0x89d0, 0x0010, 0x2061, 0x88c0, 0x00c6, 0x04d9, 0x0128, 0x00ce, - 0x8c60, 0x1f04, 0x236c, 0x0468, 0x000e, 0xd1fc, 0x0128, 0xa082, - 0x89d0, 0x2071, 0x4380, 0x0020, 0xa082, 0x88c0, 0x2071, 0x4340, - 0x707a, 0x7176, 0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x080c, - 0x2228, 0x00a0, 0xd1fc, 0x1118, 0x2071, 0x4340, 0x0010, 0x2071, - 0x4380, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e, 0x2001, - 0x0006, 0x7066, 0x7083, 0x000f, 0x080c, 0x2228, 0x2001, 0x0000, - 0x0010, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, - 0x0005, 0x2c04, 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, - 0x600c, 0xa206, 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, - 0x6000, 0x0c80, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, - 0x2079, 0x4380, 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4340, - 0x2071, 0x0200, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, - 0x001e, 0x0060, 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, - 0x0800, 0xd0bc, 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, - 0x0005, 0x00e6, 0x2001, 0x4301, 0x2004, 0xd0ac, 0x1904, 0x2439, - 0x68e4, 0xd0ac, 0x0904, 0x2439, 0xa084, 0x0006, 0x1904, 0x2439, - 0x6014, 0xd0fc, 0x1118, 0x2071, 0x47c0, 0x0010, 0x2071, 0x4840, - 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, - 0xa084, 0x000a, 0x15b0, 0x7108, 0xa194, 0xff00, 0x0590, 0xa18c, - 0x00ff, 0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, - 0x01a0, 0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, - 0x0190, 0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, - 0x0180, 0x0090, 0x2009, 0x000c, 0x0088, 0x2009, 0x0012, 0x0070, - 0x2009, 0x0014, 0x0058, 0x2009, 0x0019, 0x0040, 0x2009, 0x0020, - 0x0028, 0x2009, 0x003f, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, - 0x700a, 0x00ee, 0x0005, 0x0e04, 0x243b, 0x2091, 0x8000, 0x2071, + 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0118, + 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed, 0x62ae, + 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091, 0x8000, + 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2406, 0xd1fc, 0x0118, + 0x2061, 0x8cd0, 0x0010, 0x2061, 0x8bc0, 0x080c, 0x240e, 0x0538, + 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8bd0, 0x0010, 0x2061, + 0x8ac0, 0x00c6, 0x04d9, 0x0128, 0x00ce, 0x8c60, 0x1f04, 0x23d1, + 0x0468, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8bd0, 0x2071, 0x4580, + 0x0020, 0xa082, 0x8ac0, 0x2071, 0x4540, 0x7076, 0x7172, 0x2001, + 0x0004, 0x7062, 0x707f, 0x000f, 0x080c, 0x228b, 0x00a0, 0xd1fc, + 0x1118, 0x2071, 0x4540, 0x0010, 0x2071, 0x4580, 0x6020, 0xc0dd, + 0x6022, 0x7172, 0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, + 0x000f, 0x080c, 0x228b, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001, + 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005, 0x2c04, 0xa005, + 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c, 0xa206, 0x1128, + 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000, 0x0c80, 0xa085, + 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079, 0x4580, 0x2071, + 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4540, 0x2071, 0x0200, 0x7920, + 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e, 0x0060, 0x810b, + 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800, 0xd0bc, 0x1110, + 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005, 0x2001, 0x4501, + 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120, 0xa084, 0x0006, + 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036, 0x2018, 0x2071, + 0x4a40, 0xd0fc, 0x1110, 0x2071, 0x49c0, 0x8007, 0xa084, 0x000f, + 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a, 0x1904, + 0x24d9, 0x7108, 0xa194, 0xff00, 0x0904, 0x24d9, 0xa18c, 0x00ff, + 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085, 0x003a, 0x7006, + 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a, 0xa102, 0x16d0, + 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084, 0x00ff, 0x701e, + 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a, 0xa106, 0x01a8, + 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012, 0xa106, 0x0198, + 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019, 0xa106, 0x0188, + 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009, 0x000c, 0x00d0, + 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0, 0x2009, 0x0019, + 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f, 0x0058, 0x2009, + 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009, 0x0019, 0x0010, + 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004, 0xa085, 0x000a, + 0x7006, 0x2071, 0x4500, 0x7004, 0xd0bc, 0x0158, 0xd3fc, 0x1120, + 0x73ea, 0x2071, 0x4540, 0x0018, 0x73ee, 0x2071, 0x4580, 0x701f, + 0x800f, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff, 0x2004, 0xd0fc, + 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x12a0, 0x2071, + 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c, 0x810c, 0x2079, + 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004, 0x8004, 0xa105, + 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x252a, 0x2511, 0x252a, + 0x2511, 0x2504, 0x251e, 0x2504, 0x7008, 0xa084, 0xc3ff, 0xa085, + 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x3000, 0x780a, + 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x700a, 0x7808, + 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005, 0x7008, 0xa084, + 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, + 0x0c00, 0x780a, 0x0005, 0x0e04, 0x252b, 0x2091, 0x8000, 0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071, 0x0010, - 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a01, 0x70df, - 0x0013, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0cf8, - 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592, 0x7496, - 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc, 0x1128, - 0xa784, 0x007d, 0x1904, 0x3ace, 0x0871, 0xa49c, 0x000f, 0xa382, + 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a04, 0x70df, + 0x0008, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0cf8, + 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a, 0x758e, 0x7492, + 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc, 0x1128, + 0xa784, 0x007d, 0x1904, 0x3c3a, 0x0871, 0xa49c, 0x000f, 0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507, 0xa084, - 0x000f, 0x0002, 0x2a4f, 0x2b10, 0x2b38, 0x2d71, 0x30cc, 0x3112, - 0x31a7, 0x3220, 0x32db, 0x33a6, 0x248d, 0x248a, 0x285b, 0x295c, - 0x30a0, 0x248a, 0x080c, 0x243b, 0x0005, 0xa006, 0x0038, 0x7808, - 0xc08d, 0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, - 0xa005, 0x1904, 0x25d9, 0x7064, 0xa084, 0x0007, 0x0002, 0x24a7, - 0x2513, 0x251b, 0x2524, 0x252d, 0x25bf, 0x2536, 0x2513, 0x7830, - 0xd0bc, 0x1d10, 0x71d4, 0xd1b4, 0x1904, 0x24f0, 0x70a4, 0xa086, - 0x0001, 0x09d0, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, - 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, - 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, - 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804, 0x270a, 0x7060, 0xa005, - 0x1904, 0x248c, 0x00c6, 0x00d6, 0x70b4, 0xa06d, 0x6800, 0xa065, + 0x000f, 0x0002, 0x2b40, 0x2c01, 0x2c29, 0x2e64, 0x31f1, 0x3243, + 0x32e8, 0x3361, 0x341f, 0x34f6, 0x257d, 0x257a, 0x294d, 0x2a4d, + 0x31c5, 0x257a, 0x080c, 0x252b, 0x0005, 0xa006, 0x0038, 0x7808, + 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042, 0x70ce, 0x705c, + 0xa005, 0x1904, 0x26cb, 0x7060, 0xa084, 0x0007, 0x0002, 0x2597, + 0x2605, 0x260d, 0x2616, 0x261f, 0x26b1, 0x2628, 0x2605, 0x7830, + 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4, 0x1904, 0x25e2, + 0x70a0, 0xa086, 0x0001, 0x09c0, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, - 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0804, 0x270a, - 0x080c, 0x3a8d, 0x1904, 0x248c, 0x781b, 0x0068, 0x70bc, 0xa06d, + 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804, 0x27fc, + 0x705c, 0xa005, 0x1904, 0x257c, 0x00c6, 0x00d6, 0x70b0, 0xa06d, + 0x6800, 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, + 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, + 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, + 0x0804, 0x27fc, 0x080c, 0x3bf9, 0x1904, 0x257c, 0x781b, 0x0068, + 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, + 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, 0x703e, 0xc1b4, + 0x71d2, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x7003, 0x0002, 0x2d00, + 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x080c, 0x3bf9, 0x1120, + 0x781b, 0x0054, 0x7003, 0x0004, 0x0005, 0x080c, 0x3bf9, 0x1128, + 0x2011, 0x000c, 0x0419, 0x7003, 0x0004, 0x0005, 0x080c, 0x3bf9, + 0x1128, 0x2011, 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, + 0x3bf9, 0x1128, 0x2011, 0x000d, 0x0089, 0x7003, 0x0004, 0x0005, + 0x080c, 0x3bf9, 0x1150, 0x2011, 0x0006, 0x0041, 0x7078, 0x707b, + 0x0000, 0x2068, 0x704a, 0x7003, 0x0001, 0x0005, 0x7170, 0xc1fc, + 0x8107, 0x7882, 0x789b, 0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, + 0x2001, 0x0001, 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, + 0xa286, 0x000d, 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, + 0x0020, 0x7174, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, + 0x78aa, 0x785b, 0x0004, 0x781b, 0x0113, 0x080c, 0x3c0c, 0x707f, + 0x000f, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4, + 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, + 0x00ce, 0x0005, 0x7014, 0xa005, 0x1138, 0x70d0, 0xd0b4, 0x0128, + 0x70b4, 0xac06, 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a0, 0xa186, + 0x0001, 0x0528, 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001, 0xa212, + 0x70b0, 0x2068, 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, + 0x0cc8, 0x00c6, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, + 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, + 0x0041, 0x0cb0, 0x70a3, 0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, + 0x0005, 0xade8, 0x0005, 0x70a8, 0xad06, 0x1110, 0x70a4, 0x2068, + 0x0005, 0x080c, 0x3bf9, 0x1904, 0x257c, 0x7078, 0x2068, 0x7770, + 0x080c, 0x3b35, 0x2c50, 0x080c, 0x3c94, 0x789b, 0x0080, 0x6814, + 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, + 0x0004, 0x0804, 0x2801, 0x080c, 0x3bf9, 0x1904, 0x257c, 0x789b, + 0x0080, 0x705c, 0x2068, 0x6f14, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, + 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x6018, 0x8001, 0x601a, 0x00ce, 0x080c, 0x3b35, 0x2c50, 0x080c, + 0x3c94, 0x6824, 0xa005, 0x0130, 0xa082, 0x0006, 0x0208, 0x0010, + 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, + 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0804, 0x2801, 0xc28d, + 0x72d2, 0x72bc, 0xa200, 0xa015, 0x7150, 0x8108, 0xa12a, 0x0208, + 0x71bc, 0x2164, 0x6504, 0x85ff, 0x1170, 0x7152, 0x8421, 0x1da8, + 0x70d0, 0xd08c, 0x0128, 0x70cc, 0xa005, 0x1110, 0x70cf, 0x000a, + 0x0005, 0x2200, 0x0c90, 0x70d0, 0xc08c, 0x70d2, 0x70cf, 0x0000, + 0x6034, 0xa005, 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, + 0x1d80, 0xa784, 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, + 0x0004, 0x0d38, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, + 0xa784, 0x0100, 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, + 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, + 0x0128, 0x601c, 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, + 0x2d58, 0x2c50, 0x7152, 0xd7bc, 0x1110, 0x7028, 0x6022, 0xc7bc, + 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, + 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, + 0x0110, 0xa39c, 0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, + 0x000e, 0x1904, 0x27b3, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a0, + 0xa786, 0x0001, 0x1178, 0x70d0, 0xd0b4, 0x1160, 0x7000, 0xa082, + 0x0002, 0x1240, 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, + 0x0804, 0x27fa, 0x8739, 0x77a2, 0x2750, 0x77ac, 0xa7b0, 0x0005, + 0x70a8, 0xa606, 0x1108, 0x76a4, 0x76ae, 0x2c3a, 0x8738, 0x2d3a, + 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, + 0x0150, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, + 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, + 0x1904, 0x2704, 0x0005, 0xd1dc, 0x0904, 0x3796, 0x2029, 0x0020, + 0xd69c, 0x1120, 0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, + 0x610c, 0x8108, 0xa18c, 0x00ff, 0x70c8, 0xa160, 0x2c64, 0x8cff, + 0x0188, 0x6014, 0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, + 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, + 0x2704, 0x0005, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, + 0x6008, 0xc0d5, 0x600a, 0x77a0, 0xa786, 0x0001, 0x1904, 0x278a, + 0x70d0, 0xd0b4, 0x1904, 0x278a, 0x7000, 0xa082, 0x0002, 0x1a04, + 0x278a, 0x7830, 0xd0bc, 0x1904, 0x278a, 0x789b, 0x0080, 0x7baa, + 0x7daa, 0x79aa, 0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, + 0x0008, 0x0006, 0x2960, 0x6104, 0x2a60, 0x080c, 0x3ca7, 0x1590, + 0xa184, 0x0018, 0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x393d, + 0x1548, 0xa184, 0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, + 0x080c, 0x385d, 0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, + 0x0800, 0x0178, 0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, + 0x6104, 0xa18d, 0x0010, 0x6106, 0x00ce, 0x080c, 0x393d, 0x1150, + 0x69a0, 0xa184, 0x0200, 0x0118, 0x080c, 0x38a0, 0x0018, 0xa184, + 0x0400, 0x19f0, 0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, + 0xff00, 0x810f, 0x080c, 0x2384, 0x002e, 0xa68c, 0x00e0, 0xa684, + 0x0060, 0x0128, 0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, + 0x0104, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, + 0x681a, 0xd6bc, 0x0168, 0xc0fc, 0x7083, 0x0000, 0xa08a, 0x000d, + 0x0328, 0xa08a, 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, + 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, + 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, + 0x2898, 0x25a0, 0xa286, 0x0020, 0x1508, 0x70d0, 0xc0b5, 0x70d2, + 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0xa286, 0x0002, 0x0904, 0x28d2, 0x70a0, 0x8000, 0x70a2, 0x74b0, + 0xa498, 0x0005, 0x70a8, 0xa306, 0x1108, 0x73a4, 0x73b2, 0xa286, + 0x0010, 0x0904, 0x257c, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, + 0x19e0, 0xa286, 0x0002, 0x1904, 0x28e9, 0x080c, 0x3bf9, 0x19a8, + 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, - 0x7808, 0xc08d, 0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, - 0xa065, 0x68c0, 0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, - 0x0009, 0x7046, 0x0005, 0x080c, 0x3a8d, 0x1120, 0x781b, 0x0054, - 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, 0x2011, 0x000c, - 0x0419, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, 0x2011, - 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, - 0x2011, 0x000d, 0x0089, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, - 0x1150, 0x2011, 0x0006, 0x0041, 0x707c, 0x707f, 0x0000, 0x2068, - 0x704e, 0x7003, 0x0001, 0x0005, 0x7174, 0xc1fc, 0x8107, 0x7882, - 0x789b, 0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, 0x2001, 0x0001, - 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, - 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, 0x0020, 0x7178, - 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, 0x785b, - 0x0004, 0x781b, 0x0113, 0x080c, 0x3aa0, 0x7083, 0x000f, 0x70d4, - 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, 0x70b8, 0xa065, 0x6008, - 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, - 0x7014, 0xa005, 0x1138, 0x70d4, 0xd0b4, 0x0128, 0x70b8, 0xac06, - 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a4, 0xa186, 0x0001, 0x0528, - 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068, - 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, 0x0cc8, 0x00c6, - 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, 0x0041, 0x0cb0, - 0x70a7, 0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, 0x0005, 0xade8, - 0x0005, 0x70ac, 0xad06, 0x1110, 0x70a8, 0x2068, 0x0005, 0x080c, - 0x3a8d, 0x1904, 0x248c, 0x707c, 0x2068, 0x7774, 0x080c, 0x396d, - 0x2c50, 0x080c, 0x3b28, 0x789b, 0x0080, 0x6814, 0xa084, 0x001f, - 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0804, - 0x270f, 0x080c, 0x3a8d, 0x1904, 0x248c, 0x789b, 0x0080, 0x7060, - 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, - 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, - 0x601a, 0x00ce, 0x080c, 0x396d, 0x2c50, 0x080c, 0x3b28, 0x6824, - 0xa005, 0x0130, 0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005, - 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, - 0x0001, 0x2001, 0x0003, 0x0804, 0x270f, 0xc28d, 0x72d6, 0x72c0, - 0xa200, 0xa015, 0x7154, 0x8108, 0xa12a, 0x0208, 0x71c0, 0x2164, - 0x6504, 0x85ff, 0x1170, 0x7156, 0x8421, 0x1da8, 0x70d4, 0xd08c, - 0x0128, 0x70d0, 0xa005, 0x1110, 0x70d3, 0x000a, 0x0005, 0x2200, - 0x0c90, 0x70d4, 0xc08c, 0x70d6, 0x70d3, 0x0000, 0x6034, 0xa005, - 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, 0x1d80, 0xa784, - 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, 0x0004, 0x0d38, - 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, 0xa784, 0x0100, - 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, 0x670a, 0x2568, - 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128, 0x601c, - 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, 0x2d58, 0x2c50, - 0x7156, 0xd7bc, 0x1110, 0x7028, 0x6022, 0xc7bc, 0x670a, 0x68c0, - 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c, - 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c, - 0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, 0x000e, 0x1904, - 0x26c1, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, - 0x1178, 0x70d4, 0xd0b4, 0x1160, 0x7000, 0xa082, 0x0002, 0x1240, - 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, 0x0804, 0x2708, - 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, 0x70ac, 0xa606, - 0x1108, 0x76a8, 0x76b2, 0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a, - 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091, - 0x8000, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, - 0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904, 0x2612, - 0x0005, 0xd1dc, 0x0904, 0x35d5, 0x2029, 0x0020, 0xd69c, 0x1120, - 0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, - 0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014, - 0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008, - 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, 0x2612, 0x0005, - 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5, - 0x600a, 0x77a4, 0xa786, 0x0001, 0x1904, 0x2698, 0x70d4, 0xd0b4, - 0x1904, 0x2698, 0x7000, 0xa082, 0x0002, 0x1a04, 0x2698, 0x7830, - 0xd0bc, 0x1904, 0x2698, 0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa, - 0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008, 0x0006, - 0x2960, 0x6104, 0x2a60, 0x080c, 0x3b3b, 0x1590, 0xa184, 0x0018, - 0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x3776, 0x1548, 0xa184, - 0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, 0x080c, 0x3696, - 0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, 0x0800, 0x0178, - 0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, - 0x0010, 0x6106, 0x00ce, 0x080c, 0x3776, 0x1150, 0x69a0, 0xa184, - 0x0200, 0x0118, 0x080c, 0x36d9, 0x0018, 0xa184, 0x0400, 0x19f0, - 0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, 0xff00, 0x810f, - 0x080c, 0x231f, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128, - 0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, - 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, - 0x0168, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, - 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, 0x3518, - 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, - 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, - 0xa286, 0x0020, 0x1508, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, - 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002, - 0x0904, 0x27e0, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa498, 0x0005, - 0x70ac, 0xa306, 0x1108, 0x73a8, 0x73b6, 0xa286, 0x0010, 0x0904, - 0x248c, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x19e0, 0xa286, - 0x0002, 0x1904, 0x27f7, 0x080c, 0x3a8d, 0x19a8, 0x6814, 0xc0fc, - 0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, - 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, - 0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, 0x70d4, 0xa084, - 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, 0x705a, 0x68bc, - 0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, - 0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, - 0x2091, 0x8000, 0x2090, 0x70a4, 0xa005, 0x1108, 0x0005, 0x8421, - 0x0de8, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0804, 0x2612, 0xa286, - 0x0010, 0x1560, 0x080c, 0x3a8d, 0x1904, 0x278b, 0x6814, 0xc0fc, - 0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a4, - 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, 0x1108, - 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, - 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, 0x6bb4, 0xa39d, - 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6, - 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, 0x2900, 0x705a, - 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0170, 0x70d4, - 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000, 0x0010, - 0x2009, 0x0001, 0xa284, 0x000f, 0x0023, 0xad80, 0x0009, 0x7046, - 0x0005, 0x2859, 0x3fb8, 0x3fb8, 0x3fa6, 0x3fb8, 0x2859, 0x2859, - 0x2859, 0x080c, 0x243b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6, - 0x2079, 0x4300, 0x78ac, 0x00fe, 0xd084, 0x01c0, 0x7064, 0xa086, - 0x0001, 0x1118, 0x7066, 0x0804, 0x293a, 0x7064, 0xa086, 0x0005, - 0x1158, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, 0x0000, 0x6820, - 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000, - 0x70a8, 0x70b2, 0x70b6, 0x080c, 0x256f, 0x0156, 0x2011, 0x0004, - 0x7164, 0xa186, 0x0001, 0x0170, 0xa186, 0x0007, 0x1118, 0x701f, - 0x0005, 0x0040, 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0c5, - 0x70d6, 0x0010, 0x7067, 0x0000, 0x2001, 0x430a, 0x2004, 0xa084, - 0x00ff, 0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, - 0x70a7, 0x0001, 0x0066, 0x080c, 0x3d52, 0x20a9, 0x0010, 0x2039, - 0x0000, 0x080c, 0x3861, 0xa7b8, 0x0100, 0x1f04, 0x28b1, 0x006e, - 0x7000, 0x0002, 0x28ee, 0x28cc, 0x28cc, 0x28c4, 0x28ee, 0x28ee, - 0x28ee, 0x28c2, 0x080c, 0x243b, 0x7060, 0xa005, 0x0538, 0xad06, - 0x1118, 0x6800, 0x7062, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, - 0x080c, 0x396d, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x35ab, 0x0020, - 0x705c, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, - 0xd0fc, 0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, - 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d3d, 0xb284, 0x0800, - 0x0118, 0x2021, 0x8ad0, 0x0010, 0x2021, 0x89c0, 0x080c, 0x293f, - 0xb284, 0x0800, 0x0118, 0x2021, 0x4398, 0x0010, 0x2021, 0x4358, - 0x04f1, 0x20a9, 0x0101, 0xb284, 0x0800, 0x0118, 0x2021, 0x89d0, - 0x0010, 0x2021, 0x88c0, 0x0499, 0x8420, 0x1f04, 0x290b, 0xb284, - 0x0600, 0x0118, 0x2061, 0x48c0, 0x0010, 0x2061, 0x68c0, 0x2021, - 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016, - 0x0006, 0x2011, 0x4302, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, - 0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4304, 0x2204, 0xc0a5, - 0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x291b, 0x8421, - 0x1d00, 0x015e, 0x7003, 0x0000, 0x704f, 0x0000, 0x0005, 0x0046, - 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a, 0x6817, + 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, + 0x70d0, 0xa084, 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, + 0x7056, 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, + 0x0009, 0x7042, 0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d0, + 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0x70a0, 0xa005, 0x1108, + 0x0005, 0x8421, 0x0de8, 0x724c, 0x70bc, 0xa200, 0xa015, 0x0804, + 0x2704, 0xa286, 0x0010, 0x1560, 0x080c, 0x3bf9, 0x1904, 0x287d, + 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, + 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, + 0x780a, 0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa490, 0x0005, 0x70a8, + 0xa206, 0x1108, 0x72a4, 0x72b2, 0x2900, 0x7056, 0x68bc, 0x703e, + 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, + 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, + 0x2900, 0x7056, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, + 0x0170, 0x70d0, 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, + 0x0000, 0x0010, 0x2009, 0x0001, 0xa284, 0x000f, 0x0023, 0xad80, + 0x0009, 0x7042, 0x0005, 0x294b, 0x4180, 0x4180, 0x416e, 0x4180, + 0x294b, 0x294b, 0x294b, 0x080c, 0x252b, 0x7808, 0xa084, 0xfffd, + 0x780a, 0x00f6, 0x2079, 0x4500, 0x78ac, 0x00fe, 0xd084, 0x01b0, + 0x7060, 0xa086, 0x0001, 0x0904, 0x2a29, 0x7060, 0xa086, 0x0005, + 0x1158, 0x7078, 0x2068, 0x681b, 0x0004, 0x6817, 0x0000, 0x6820, + 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063, 0x0000, 0x70a3, 0x0000, + 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x2661, 0x0156, 0x2011, 0x0004, + 0x7160, 0xa186, 0x0001, 0x0160, 0xa186, 0x0007, 0x1118, 0x701f, + 0x0005, 0x0030, 0x701f, 0x0001, 0x70d0, 0xc0c5, 0x70d2, 0x0000, + 0x2001, 0x450a, 0x2004, 0xa084, 0x00ff, 0xa086, 0x0018, 0x0130, + 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3, 0x0001, 0x0066, 0x080c, + 0x3ed9, 0x20a9, 0x0010, 0x2039, 0x0000, 0x080c, 0x3a29, 0xa7b8, + 0x0100, 0x1f04, 0x299d, 0x006e, 0x7000, 0x0002, 0x29da, 0x29b8, + 0x29b8, 0x29b0, 0x29da, 0x29da, 0x29da, 0x29ae, 0x080c, 0x252b, + 0x705c, 0xa005, 0x0538, 0xad06, 0x1118, 0x6800, 0x705e, 0x0080, + 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c, 0x3b35, 0x6008, 0xc0d4, + 0x600a, 0x080c, 0x376c, 0x0020, 0x7058, 0x2060, 0x6800, 0x6002, + 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, 0x0108, 0x6a1a, 0x6817, + 0x0000, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, + 0x080c, 0x1d89, 0x2011, 0x0004, 0xb284, 0x0800, 0x0118, 0x2021, + 0x8cd0, 0x0010, 0x2021, 0x8bc0, 0x080c, 0x2a30, 0xb284, 0x0800, + 0x0118, 0x2021, 0x4597, 0x0010, 0x2021, 0x4557, 0x080c, 0x2a30, + 0x20a9, 0x0101, 0xb284, 0x0800, 0x0118, 0x2021, 0x8bd0, 0x0010, + 0x2021, 0x8ac0, 0x04a9, 0x8420, 0x1f04, 0x29fa, 0xb284, 0x0600, + 0x0118, 0x2061, 0x4ac0, 0x0010, 0x2061, 0x6ac0, 0x2021, 0x0002, + 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016, 0x0006, + 0x2011, 0x4502, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, 0xa102, + 0x0338, 0x6012, 0x1128, 0x2011, 0x4504, 0x2204, 0xc0a5, 0x2012, + 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a0a, 0x8421, 0x1d00, + 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000, 0x0005, + 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a, + 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, + 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d89, 0x000e, + 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310, + 0x080c, 0x252b, 0x2300, 0x0002, 0x2a57, 0x2ad4, 0x2aee, 0xa282, + 0x0002, 0x0110, 0x080c, 0x252b, 0x7060, 0x7063, 0x0000, 0x707f, + 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2a6e, 0x2a6e, + 0x2a70, 0x2aa8, 0x37a0, 0x2a6e, 0x2aa8, 0x2a6e, 0x080c, 0x252b, + 0x7770, 0x080c, 0x3a29, 0x7770, 0xa7bc, 0x8f00, 0x080c, 0x3b35, + 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8bc0, 0x0010, + 0x2021, 0x8cd0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2b08, + 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x8ac0, + 0x0010, 0x2021, 0x8bd0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010, + 0x080c, 0x2b08, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2a93, 0x015e, + 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x257f, 0x0804, 0x257f, + 0x7770, 0x080c, 0x3b35, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118, + 0x2021, 0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x2009, 0x0005, 0x2011, + 0x0020, 0x080c, 0x2b08, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc, + 0x1118, 0x2021, 0x8ac0, 0x0010, 0x2021, 0x8bd0, 0x0046, 0x2009, + 0x0005, 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420, 0x1f04, + 0x2ac6, 0x015e, 0x0804, 0x257f, 0x2200, 0x0002, 0x2ad9, 0x2adb, + 0x2adb, 0x080c, 0x252b, 0x2009, 0x0012, 0x7060, 0xa086, 0x0002, + 0x0110, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a, 0x7063, + 0x0000, 0x70d0, 0xc0c5, 0x70d2, 0x0804, 0x3bab, 0x2200, 0x0002, + 0x2af5, 0x2adb, 0x2af3, 0x080c, 0x252b, 0x080c, 0x3ed9, 0x7000, + 0xa086, 0x0002, 0x1904, 0x3725, 0x080c, 0x3786, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x080c, 0x3717, 0x0904, 0x3725, 0x0804, 0x257f, + 0x2404, 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814, 0xa706, + 0x0118, 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, - 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d3d, 0x000e, 0x0c48, - 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310, 0x080c, - 0x243b, 0x2300, 0x0002, 0x2966, 0x29e3, 0x29fd, 0xa282, 0x0002, - 0x0110, 0x080c, 0x243b, 0x7064, 0x7067, 0x0000, 0x7083, 0x0000, - 0x0022, 0x77d4, 0xc7c5, 0x77d6, 0x0002, 0x297d, 0x297d, 0x297f, - 0x29b7, 0x35df, 0x297d, 0x29b7, 0x297d, 0x080c, 0x243b, 0x7774, - 0x080c, 0x3861, 0x7774, 0xa7bc, 0x8f00, 0x080c, 0x396d, 0x6018, - 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x89c0, 0x0010, 0x2021, - 0x8ad0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2a17, 0x01b8, - 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x88c0, 0x0010, - 0x2021, 0x89d0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, - 0x2a17, 0x004e, 0x0118, 0x8420, 0x1f04, 0x29a2, 0x015e, 0x8738, - 0xa784, 0x001f, 0x1990, 0x0804, 0x248f, 0x0804, 0x248f, 0x7774, - 0x080c, 0x396d, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118, 0x2021, - 0x89c0, 0x0010, 0x2021, 0x8ad0, 0x2009, 0x0005, 0x2011, 0x0020, - 0x080c, 0x2a17, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, - 0x2021, 0x88c0, 0x0010, 0x2021, 0x89d0, 0x0046, 0x2009, 0x0005, - 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420, 0x1f04, 0x29d5, - 0x015e, 0x0804, 0x248f, 0x2200, 0x0002, 0x29e8, 0x29ea, 0x29ea, - 0x080c, 0x243b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0110, - 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a, 0x7067, 0x0000, - 0x70d4, 0xc0c5, 0x70d6, 0x0804, 0x3a3f, 0x2200, 0x0002, 0x2a04, - 0x29ea, 0x2a02, 0x080c, 0x243b, 0x080c, 0x3d52, 0x7000, 0xa086, - 0x0002, 0x1904, 0x356d, 0x080c, 0x35c5, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x080c, 0x355f, 0x0904, 0x356d, 0x0804, 0x248f, 0x2404, - 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814, 0xa706, 0x0118, - 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a, 0x6817, 0x0000, - 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, - 0x00ff, 0xa205, 0x6822, 0x080c, 0x1d3d, 0x2021, 0x4302, 0x241c, - 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128, 0x2021, 0x4304, - 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x080c, - 0x258b, 0x080c, 0x35c5, 0x0005, 0xa085, 0x0001, 0x0ce0, 0x2300, - 0x0002, 0x2a56, 0x2a54, 0x2abc, 0x080c, 0x243b, 0x78e4, 0xa005, - 0x1708, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x248c, 0x0010, - 0x0304, 0x248c, 0x2008, 0xa084, 0x0030, 0x1110, 0x0804, 0x30a0, - 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x2100, 0xa084, 0x0007, 0x0002, - 0x2a9f, 0x2aa8, 0x2a95, 0x2a78, 0x3a83, 0x3a83, 0x2a78, 0x2ab2, - 0x080c, 0x243b, 0x7000, 0xa086, 0x0004, 0x1190, 0x7064, 0xa086, - 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x295c, - 0x7064, 0xa086, 0x0006, 0x0db0, 0x7064, 0xa086, 0x0004, 0x0d90, - 0x79e4, 0x2001, 0x0003, 0x0804, 0x2daa, 0x6818, 0xd0fc, 0x0110, - 0x681b, 0x001d, 0x080c, 0x3837, 0x781b, 0x006e, 0x0005, 0x6818, - 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3837, 0x0804, 0x3a61, - 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3837, 0x781b, - 0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, - 0x3837, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000, - 0x0002, 0x248f, 0x2ac9, 0x2acb, 0x356d, 0x356d, 0x356d, 0x2ac9, - 0x2ac9, 0x080c, 0x243b, 0x080c, 0x35c5, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x080c, 0x355f, 0x0904, 0x356d, 0x0804, 0x248f, 0x78e4, - 0xa005, 0x1b04, 0x2a7a, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, - 0x2a7a, 0x0010, 0x0304, 0x2a7a, 0x2008, 0xa084, 0x0030, 0x1118, - 0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x2100, - 0xa184, 0x0007, 0x0002, 0x2b02, 0x2b06, 0x2afd, 0x2afb, 0x3a83, - 0x3a83, 0x2afb, 0x3a7d, 0x080c, 0x243b, 0x080c, 0x383d, 0x781b, - 0x006e, 0x0005, 0x080c, 0x383d, 0x0804, 0x3a61, 0x080c, 0x383d, - 0x781b, 0x00fa, 0x0005, 0x080c, 0x383d, 0x781b, 0x00cb, 0x0005, - 0x2300, 0x0002, 0x2b17, 0x2b15, 0x2b19, 0x080c, 0x243b, 0x0804, - 0x3220, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, - 0x0904, 0x3220, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3220, 0xa184, - 0x0100, 0x0d98, 0xa184, 0x0007, 0x0002, 0x2b35, 0x2b06, 0x2a95, - 0x3a3f, 0x3a83, 0x3a83, 0x3a3f, 0x3a7d, 0x080c, 0x3a4b, 0x0005, - 0xa282, 0x0005, 0x0310, 0x080c, 0x243b, 0x7898, 0x2040, 0x2300, - 0x0002, 0x2b44, 0x2d41, 0x2d4b, 0x2200, 0x0002, 0x2b60, 0x2b4d, - 0x2b60, 0x2b4b, 0x2d25, 0x080c, 0x243b, 0x789b, 0x0018, 0x78a8, - 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04, 0x3809, 0xa08a, - 0x0004, 0x1a04, 0x3809, 0x0002, 0x3809, 0x3809, 0x3809, 0x37bf, - 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148, 0x0804, 0x3809, - 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804, 0x33b2, 0xa184, - 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3809, 0x0002, 0x2b88, 0x2b86, - 0x2b9a, 0x2b9e, 0x2c3c, 0x3809, 0x3809, 0x2c3e, 0x3809, 0x3809, - 0x2d21, 0x2d21, 0x3809, 0x3809, 0x3809, 0x2d23, 0x080c, 0x243b, - 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, - 0x00c6, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90, - 0x0804, 0x3a3f, 0x681b, 0x001d, 0x0804, 0x3831, 0x6920, 0x6922, - 0xa684, 0x1800, 0x15e0, 0x6820, 0xd084, 0x1904, 0x2be7, 0x6818, - 0xa086, 0x0008, 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, 0xd6bc, - 0x0558, 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, - 0x0718, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, - 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, 0x3208, - 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, - 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, - 0x53a6, 0x014e, 0x013e, 0x015e, 0x781b, 0x0071, 0x0005, 0xd6e4, - 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083, 0x0005, 0xa684, - 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, 0x7e5a, - 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084, 0x007f, 0xa108, - 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, - 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, - 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3d52, 0x080c, 0x3fb8, - 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c, 0x4083, 0x6ab0, - 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120, 0x2200, 0xa422, - 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, - 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0080, - 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118, 0x080c, 0x3fb8, - 0x0005, 0x080c, 0x3fe5, 0x0005, 0x080c, 0x243b, 0x0804, 0x2cbd, - 0x00c6, 0x7058, 0x2060, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, - 0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000, - 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x36f6, 0x080c, 0x379a, - 0x0804, 0x2cb1, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, - 0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104, - 0xa18c, 0x0010, 0x0548, 0x080c, 0x3969, 0x080c, 0x3776, 0x88ff, - 0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, - 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, - 0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, - 0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, - 0xa006, 0x2010, 0x080c, 0x379a, 0xa286, 0x0001, 0x0158, 0x6104, - 0xa18c, 0x0008, 0x01b0, 0x080c, 0x3969, 0x080c, 0x3696, 0x88ff, - 0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, - 0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, - 0x36f6, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, - 0x781b, 0x0083, 0x0005, 0x0804, 0x382d, 0x2808, 0x789b, 0x0080, - 0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x1188, - 0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, 0xa102, - 0x0a04, 0x2c40, 0x0904, 0x2c40, 0x24a8, 0x7aa8, 0x1f04, 0x2cd5, - 0x0c48, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082, - 0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, 0x0ad0, - 0xa286, 0x0023, 0x0980, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, - 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, - 0x78a0, 0x8001, 0x0904, 0x2cb1, 0x20a8, 0x7998, 0x789b, 0x0060, - 0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, - 0x7a98, 0x1f04, 0x2d03, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, - 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, 0xa302, - 0x0a04, 0x2cc2, 0xa284, 0x0080, 0x1904, 0x3831, 0x78a0, 0xa005, - 0x08c8, 0x0804, 0x3831, 0x0804, 0x3809, 0x7058, 0xa04d, 0x789b, - 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c, - 0x243b, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, - 0x0005, 0x1a04, 0x3809, 0x0002, 0x3809, 0x3615, 0x3809, 0x3726, - 0x3b83, 0xa282, 0x0000, 0x1110, 0x080c, 0x243b, 0x080c, 0x3837, - 0x781b, 0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x243b, - 0xd4fc, 0x11d0, 0x7064, 0xa005, 0x0110, 0x080c, 0x243b, 0x6f14, - 0x7776, 0xa7bc, 0x8f00, 0x080c, 0x396d, 0x6008, 0xa085, 0x0021, - 0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x383a, 0x7067, - 0x0002, 0x701f, 0x0009, 0x0010, 0x080c, 0x3846, 0x781b, 0x0082, - 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x243b, 0x2300, 0x0002, - 0x2d7b, 0x2eff, 0x2f3b, 0xa286, 0x0003, 0x0560, 0x7200, 0x7cd8, - 0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x00f0, 0x7868, 0xa084, 0x00ff, - 0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b, - 0x0059, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, - 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x00de, - 0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001, - 0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0, - 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002, - 0x2ee0, 0x2dc5, 0x2dc2, 0x3012, 0x3085, 0x248f, 0x2dc0, 0x2dc0, - 0x080c, 0x243b, 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7048, - 0xa086, 0x0014, 0x11e8, 0x080c, 0x3d52, 0x2009, 0x0000, 0x6818, - 0xd0fc, 0x0108, 0x7048, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086, - 0x0008, 0x1904, 0x2ea2, 0x7858, 0xd09c, 0x0904, 0x2ea2, 0x6820, - 0xd0ac, 0x0904, 0x2ea2, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8, - 0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008, - 0xc0a4, 0x600a, 0x080c, 0x355f, 0x0540, 0x080c, 0x35c5, 0x080c, - 0x3d52, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78, - 0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084, - 0x0904, 0x248f, 0xc084, 0x6822, 0x080c, 0x2580, 0x705c, 0x00c6, - 0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00, - 0x1108, 0x6002, 0x6006, 0x0804, 0x248f, 0x0016, 0x81ff, 0x15e0, - 0x7000, 0xa086, 0x0030, 0x05c0, 0x71d4, 0xd1b4, 0x11e8, 0x7060, - 0xa005, 0x1590, 0x70a4, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000, - 0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x24b2, - 0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d4, 0xd1b4, - 0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3a8d, 0x11a8, 0x781b, - 0x0068, 0x00d6, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, - 0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x2f63, 0x001e, 0x81ff, - 0x0904, 0x2ea2, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, - 0xa186, 0x0002, 0x15c0, 0x6818, 0xa086, 0x0014, 0x1130, 0x2008, - 0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3850, 0x080c, - 0x258b, 0x6820, 0xd0dc, 0x1538, 0x8717, 0xa294, 0x000f, 0x8213, - 0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x47c0, 0x0010, - 0xa290, 0x4840, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0130, 0x8210, - 0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138, 0x68a0, - 0xd0c4, 0x1120, 0x080c, 0x2fcb, 0x0804, 0x248f, 0x6008, 0xc08d, - 0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7048, - 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168, 0x2009, - 0x4302, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, - 0x4304, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118, 0x8001, - 0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x1130, - 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x705c, 0x2060, - 0x6800, 0x6002, 0x2061, 0x4300, 0x6887, 0x0103, 0x2d08, 0x206b, - 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, - 0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904, 0x248f, - 0x7003, 0x0002, 0x704c, 0x2068, 0x68c4, 0x2060, 0x0005, 0x7003, - 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, - 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, 0xa282, - 0x0004, 0x0210, 0x080c, 0x243b, 0x2200, 0x0002, 0x2f0a, 0x2f19, - 0x2f25, 0x2f19, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300, 0x1d90, - 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3837, 0x781b, - 0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007, 0x8001, - 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, - 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804, 0x3809, - 0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff, 0x1118, - 0x080c, 0x3837, 0x0030, 0x8211, 0x0110, 0x080c, 0x243b, 0x080c, - 0x3846, 0x781b, 0x0082, 0x0005, 0x080c, 0x3aa0, 0x7830, 0xa084, - 0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e, 0x0118, - 0x0104, 0x2f60, 0x0010, 0x0304, 0x2f60, 0x791a, 0xa006, 0x0005, - 0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f, 0x0000, - 0x6833, 0x0000, 0x0804, 0x2fca, 0xd6dc, 0x1198, 0x68b4, 0xd0dc, - 0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x1130, - 0x2200, 0xa105, 0x0904, 0x3d52, 0x704b, 0x0015, 0x0804, 0x3d52, - 0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, - 0x0000, 0x0804, 0x3d52, 0x68b4, 0xa084, 0x4000, 0xa635, 0xd6f4, - 0x1da0, 0x7048, 0xa005, 0x1110, 0x704b, 0x0015, 0xd6dc, 0x1128, - 0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0804, - 0x3d52, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, - 0x3d52, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0, 0x7048, - 0xa005, 0x1110, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700, 0x8007, - 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, - 0xa205, 0x1110, 0x0804, 0x3d52, 0x7000, 0xa086, 0x0006, 0x0110, - 0x0804, 0x3d52, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0108, - 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, - 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, - 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, - 0x7000, 0x0002, 0x248f, 0x2ffa, 0x2ff4, 0x2ff2, 0x2ff2, 0x2ff2, - 0x2ff2, 0x2ff2, 0x080c, 0x243b, 0x6820, 0xd084, 0x1118, 0x080c, - 0x35ab, 0x0030, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, - 0x3208, 0xa18c, 0x0600, 0x0118, 0x2021, 0x4358, 0x0010, 0x2021, - 0x4398, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b, - 0x0000, 0x0005, 0x080c, 0x35b1, 0x080c, 0x35c5, 0x6008, 0xc0cc, - 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, - 0x6944, 0x6916, 0x3208, 0xa18c, 0x0600, 0x0118, 0x2009, 0x0000, - 0x0010, 0x2009, 0x0001, 0x080c, 0x40b1, 0xd6dc, 0x0118, 0x691c, - 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0148, 0x7868, 0xa08c, 0x00ff, - 0x0118, 0x681b, 0x001e, 0x0010, 0x681b, 0x0000, 0xb284, 0x0600, - 0x1118, 0x2021, 0x4398, 0x0010, 0x2021, 0x4358, 0x6800, 0x2022, - 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, - 0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6, - 0x00f6, 0x0156, 0x0146, 0x2079, 0x4300, 0x080c, 0x1b35, 0x014e, - 0x015e, 0x00fe, 0x70cc, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204, - 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820, - 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7067, - 0x0003, 0x707f, 0x0000, 0x7776, 0x7083, 0x000f, 0x71d4, 0xc1c4, - 0x71d6, 0x080c, 0x1d3d, 0x0804, 0x248f, 0x7cd8, 0x7ddc, 0x7fd0, - 0x080c, 0x2f63, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x080c, - 0x3aa4, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7048, - 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0804, 0x248f, - 0x7000, 0xa005, 0x1110, 0x0804, 0x248f, 0xa006, 0x080c, 0x3d52, - 0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, - 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, - 0x248f, 0x30c2, 0x30c2, 0x30c5, 0x30c5, 0x30c5, 0x30c0, 0x30c0, - 0x080c, 0x243b, 0x6818, 0x0804, 0x2daa, 0x6008, 0xc0a4, 0x600a, - 0x6817, 0x0000, 0x0804, 0x357a, 0x2300, 0x0002, 0x30d1, 0x30d3, - 0x3110, 0x080c, 0x243b, 0xd6fc, 0x1904, 0x2bee, 0x7000, 0xa00d, - 0x0002, 0x248f, 0x30e3, 0x30e3, 0x3104, 0x30e3, 0x310d, 0x30e1, - 0x30e1, 0x080c, 0x243b, 0xa684, 0x0060, 0xa086, 0x0060, 0x11d0, - 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, 0x681e, 0xa186, - 0x0002, 0x0110, 0x080c, 0x3d52, 0x080c, 0x3fb8, 0x781b, 0x0083, - 0x71d4, 0xd1b4, 0x1904, 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, - 0x24ce, 0x0005, 0xd6ec, 0x0d30, 0x6818, 0xd0fc, 0x0130, 0x681b, - 0x0015, 0xd6f4, 0x0110, 0x681b, 0x0007, 0x080c, 0x3a4b, 0x0005, - 0x080c, 0x243b, 0x2300, 0x0002, 0x3119, 0x3134, 0x3182, 0x080c, - 0x243b, 0x7000, 0x0002, 0x3123, 0x3125, 0x3125, 0x3123, 0x3123, - 0x3123, 0x3123, 0x3123, 0x080c, 0x243b, 0x080c, 0x3fb8, 0x681c, - 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x1904, 0x248c, 0x70a4, 0xa086, - 0x0001, 0x1904, 0x24ce, 0x0005, 0xd6fc, 0x15e0, 0x7000, 0xa00d, - 0x0002, 0x248f, 0x3149, 0x3143, 0x316a, 0x3149, 0x316f, 0x3141, - 0x3141, 0x080c, 0x243b, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, - 0x78da, 0xa684, 0x0060, 0xa086, 0x0060, 0x11d0, 0xa6b4, 0xbfbf, - 0xc6ed, 0x7e5a, 0xa186, 0x0002, 0x0110, 0x080c, 0x3d52, 0x080c, - 0x3fb8, 0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, - 0x1904, 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, 0x24ce, 0x0005, - 0xd6ec, 0x0d30, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b, - 0x00fb, 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, - 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, - 0x0083, 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x0083, - 0x0804, 0x248c, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, - 0x1150, 0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, - 0x0083, 0x0804, 0x248c, 0x6820, 0xc095, 0x6822, 0x080c, 0x39ca, - 0xc6dd, 0x080c, 0x3837, 0x781b, 0x0082, 0x0804, 0x248c, 0x2300, - 0x0002, 0x31ac, 0x31ae, 0x31b0, 0x080c, 0x243b, 0x0804, 0x3831, - 0x7d98, 0xd6d4, 0x11f8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, 0xa084, - 0x0003, 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, - 0xa684, 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, 0x78ec, - 0xa084, 0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2daa, 0xa184, - 0x0007, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, - 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384, 0x0001, 0x11d0, - 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009, 0xffdf, 0x0058, - 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028, 0xa386, 0x0003, - 0x1148, 0x2009, 0xffef, 0x00c6, 0x7058, 0x2060, 0x6004, 0xa104, - 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, - 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff, 0x6922, 0x7d9a, - 0x0804, 0x3a3f, 0x2a9f, 0x2aa8, 0x3214, 0x321a, 0x3212, 0x3212, - 0x3a3f, 0x3a3f, 0x080c, 0x243b, 0x6920, 0xa18c, 0xfcff, 0x6922, - 0x0804, 0x3a45, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3a3f, - 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1558, - 0x7000, 0xa086, 0x0004, 0x1190, 0x7064, 0xa086, 0x0002, 0x1130, - 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x295c, 0x7064, 0xa086, - 0x0006, 0x0db0, 0x7064, 0xa086, 0x0004, 0x0d90, 0x7000, 0xa086, - 0x0000, 0x0904, 0x248c, 0x6920, 0xa184, 0x0420, 0x0128, 0xc1d4, - 0x6922, 0x6818, 0x0804, 0x2daa, 0x6818, 0xc0fd, 0x681a, 0x2001, - 0x0014, 0x0804, 0x2daa, 0xa184, 0x0007, 0x0002, 0x3a3f, 0x3a3f, - 0x325e, 0x3a3f, 0x3a83, 0x3a83, 0x3a3f, 0x3a3f, 0xd6bc, 0x0570, - 0x7184, 0x81ff, 0x0558, 0xa182, 0x000d, 0x1318, 0x7087, 0x0000, - 0x0028, 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, - 0x79aa, 0x0156, 0x0136, 0x0146, 0x7088, 0x8114, 0xa210, 0x728a, - 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, 0x0600, 0x0118, 0x20a1, - 0x022b, 0x0010, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, - 0x53a6, 0x014e, 0x013e, 0x015e, 0x0804, 0x3a45, 0xd6d4, 0x1904, - 0x32d1, 0x6820, 0xd084, 0x0904, 0x3a45, 0xa68c, 0x0060, 0xa684, - 0x0060, 0x0120, 0xa086, 0x0060, 0x1108, 0xc1f5, 0xc194, 0x795a, - 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, - 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0904, 0x35da, 0xa18c, - 0x00f8, 0x1904, 0x35da, 0x0156, 0x0136, 0x0146, 0x0016, 0x20a1, - 0x012b, 0x3208, 0xa18c, 0x0600, 0x0110, 0x20a1, 0x022b, 0x001e, - 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, - 0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804, - 0x3a45, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0008, 0x080c, 0x3837, - 0x781b, 0x00ed, 0x0005, 0x2300, 0x0002, 0x32e2, 0x3398, 0x32e0, - 0x080c, 0x243b, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x11f0, 0x7200, - 0xa286, 0x0003, 0x0904, 0x2d7f, 0x71d4, 0xd1b4, 0x00c0, 0x00d6, - 0x783b, 0x8800, 0x781b, 0x0059, 0x70bc, 0xa06d, 0x68b4, 0xc0a5, - 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, - 0x71d6, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200, 0x0020, 0x783b, - 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002, 0x3383, 0x3344, - 0x3318, 0x2da7, 0x3316, 0x3383, 0x3316, 0x3316, 0x080c, 0x243b, - 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, - 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002, 0x6008, 0xc0d4, - 0x600a, 0x681c, 0xa084, 0x000e, 0x1148, 0xb284, 0x0600, 0x0118, - 0x2009, 0x89c0, 0x0040, 0x2009, 0x8ad0, 0x0028, 0x7030, 0x68ba, - 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e, 0xd6dc, - 0x1118, 0xc6fc, 0x6eb6, 0x04f8, 0x6eb6, 0xa684, 0x0060, 0x05d8, + 0xa084, 0x00ff, 0xa205, 0x6822, 0x080c, 0x1d89, 0x2021, 0x4502, + 0x241c, 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128, 0x2021, + 0x4504, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, + 0x080c, 0x267d, 0x080c, 0x3786, 0x0005, 0xa085, 0x0001, 0x0ce0, + 0x2300, 0x0002, 0x2b47, 0x2b45, 0x2bad, 0x080c, 0x252b, 0x78e4, + 0xa005, 0x1708, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x257c, + 0x0010, 0x0304, 0x257c, 0x2008, 0xa084, 0x0030, 0x1110, 0x0804, + 0x31c5, 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x2100, 0xa084, 0x0007, + 0x0002, 0x2b90, 0x2b99, 0x2b86, 0x2b69, 0x3bef, 0x3bef, 0x2b69, + 0x2ba3, 0x080c, 0x252b, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, + 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, + 0x2a4d, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, + 0x0d90, 0x79e4, 0x2001, 0x0003, 0x0804, 0x2ea4, 0x6818, 0xd0fc, + 0x0110, 0x681b, 0x001d, 0x080c, 0x39ff, 0x781b, 0x006e, 0x0005, + 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x39ff, 0x0804, + 0x3bcd, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x39ff, + 0x781b, 0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, + 0x080c, 0x39ff, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, + 0x7000, 0x0002, 0x257f, 0x2bba, 0x2bbc, 0x3725, 0x3725, 0x3725, + 0x2bba, 0x2bba, 0x080c, 0x252b, 0x080c, 0x3786, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x080c, 0x3717, 0x0904, 0x3725, 0x0804, 0x257f, + 0x78e4, 0xa005, 0x1b04, 0x2b6b, 0x3208, 0xa18c, 0x0800, 0x0118, + 0x0104, 0x2b6b, 0x0010, 0x0304, 0x2b6b, 0x2008, 0xa084, 0x0030, + 0x1118, 0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, + 0x2100, 0xa184, 0x0007, 0x0002, 0x2bf3, 0x2bf7, 0x2bee, 0x2bec, + 0x3bef, 0x3bef, 0x2bec, 0x3be9, 0x080c, 0x252b, 0x080c, 0x3a05, + 0x781b, 0x006e, 0x0005, 0x080c, 0x3a05, 0x0804, 0x3bcd, 0x080c, + 0x3a05, 0x781b, 0x00fa, 0x0005, 0x080c, 0x3a05, 0x781b, 0x00cb, + 0x0005, 0x2300, 0x0002, 0x2c08, 0x2c06, 0x2c0a, 0x080c, 0x252b, + 0x0804, 0x3361, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, + 0x0030, 0x0904, 0x3361, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3361, + 0xa184, 0x0100, 0x0d98, 0xa184, 0x0007, 0x0002, 0x2c26, 0x2bf7, + 0x2b86, 0x3bab, 0x3bef, 0x3bef, 0x3bab, 0x3be9, 0x080c, 0x3bb7, + 0x0005, 0xa282, 0x0005, 0x0310, 0x080c, 0x252b, 0x7898, 0x2040, + 0x2300, 0x0002, 0x2c35, 0x2e34, 0x2e3e, 0x2200, 0x0002, 0x2c51, + 0x2c3e, 0x2c51, 0x2c3c, 0x2e16, 0x080c, 0x252b, 0x789b, 0x0018, + 0x78a8, 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04, 0x39d0, + 0xa08a, 0x0004, 0x1a04, 0x39d0, 0x0002, 0x39d0, 0x39d0, 0x39d0, + 0x3986, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148, 0x0804, + 0x39d0, 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804, 0x3502, + 0xa184, 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x39d0, 0x0002, 0x2c79, + 0x2c77, 0x2c8b, 0x2c8f, 0x2d2d, 0x39d0, 0x39d0, 0x2d2f, 0x39d0, + 0x39d0, 0x2e12, 0x2e12, 0x39d0, 0x39d0, 0x39d0, 0x2e14, 0x080c, + 0x252b, 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, + 0x781b, 0x00c7, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b, 0x001d, + 0x0c90, 0x0804, 0x3bab, 0x681b, 0x001d, 0x0804, 0x39f9, 0x6920, + 0x6922, 0xa684, 0x1800, 0x15e0, 0x6820, 0xd084, 0x1904, 0x2cd8, + 0x6818, 0xa086, 0x0008, 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, + 0xd6bc, 0x0558, 0x7083, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, + 0x000d, 0x0718, 0xa08a, 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, + 0x7186, 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, + 0x3208, 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, + 0x012b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, + 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x781b, 0x0071, 0x0005, + 0xd6e4, 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083, 0x0005, + 0xa684, 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, + 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084, 0x007f, + 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, + 0x2200, 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a, 0x6eb6, + 0x7000, 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3ed9, 0x080c, + 0x4180, 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c, 0x425d, + 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120, 0x2200, + 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, + 0x7bde, 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, + 0x0080, 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118, 0x080c, + 0x4180, 0x0005, 0x080c, 0x41ad, 0x0005, 0x080c, 0x252b, 0x0804, + 0x2dae, 0x00c6, 0x7054, 0x2060, 0x7aa8, 0xa294, 0x00ff, 0xa286, + 0x0004, 0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, + 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38bd, 0x080c, + 0x3961, 0x0804, 0x2da2, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, + 0xffdd, 0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, + 0x6104, 0xa184, 0x0010, 0x0548, 0x080c, 0x3b31, 0x080c, 0x393d, + 0x88ff, 0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, + 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, + 0x0082, 0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, + 0x6000, 0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, + 0x0000, 0xa006, 0x2010, 0x080c, 0x3961, 0xa286, 0x0001, 0x0158, + 0x6104, 0xa184, 0x0008, 0x01b0, 0x080c, 0x3b31, 0x080c, 0x385d, + 0x88ff, 0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, + 0x6922, 0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, + 0x080c, 0x38bd, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, + 0x0005, 0x781b, 0x0083, 0x0005, 0x0804, 0x39f5, 0x2808, 0x789b, + 0x0080, 0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, + 0x1188, 0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, + 0xa102, 0x0a04, 0x2d31, 0x0904, 0x2d31, 0x24a8, 0x7aa8, 0x1f04, + 0x2dc6, 0x0c48, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, + 0xa082, 0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, + 0x0ad0, 0xa286, 0x0023, 0x0980, 0x681c, 0xa084, 0xfff1, 0x681e, + 0x7e58, 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, + 0x600a, 0x78a0, 0x8001, 0x0904, 0x2da2, 0x20a8, 0x7998, 0x789b, + 0x0060, 0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, + 0x78aa, 0x7a98, 0x1f04, 0x2df4, 0xc695, 0x7e5a, 0xd6d4, 0x1118, + 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, + 0xa302, 0x0a04, 0x2db3, 0xa284, 0x0080, 0x1904, 0x39f9, 0x78a0, + 0xa005, 0x08c8, 0x0804, 0x39f9, 0x0804, 0x39d0, 0x7054, 0xa04d, + 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, + 0x080c, 0x252b, 0x7aa8, 0xa294, 0x00ff, 0x784b, 0x0008, 0x78a8, + 0xa084, 0x00ff, 0xa08a, 0x0005, 0x1a04, 0x39d0, 0x0002, 0x39d0, + 0x37d4, 0x39d0, 0x38ed, 0x3cef, 0xa282, 0x0000, 0x1110, 0x080c, + 0x252b, 0x080c, 0x39ff, 0x781b, 0x0082, 0x0005, 0xa282, 0x0003, + 0x1110, 0x080c, 0x252b, 0xd4fc, 0x11d0, 0x7060, 0xa005, 0x0110, + 0x080c, 0x252b, 0x6f14, 0x7772, 0xa7bc, 0x8f00, 0x080c, 0x3b35, + 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, + 0x080c, 0x3a02, 0x7063, 0x0002, 0x701f, 0x0009, 0x0010, 0x080c, + 0x3a0e, 0x781b, 0x0082, 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, + 0x252b, 0x2300, 0x0002, 0x2e6e, 0x3004, 0x3040, 0xa286, 0x0003, + 0x0598, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d0, 0xd1bc, 0x1528, + 0xd1b4, 0x0518, 0x2001, 0x4501, 0x2004, 0xd0c4, 0x11f0, 0x7868, + 0xa084, 0x00ff, 0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, + 0x8300, 0x781b, 0x0059, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, + 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, + 0x0030, 0x00de, 0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, + 0x0057, 0x2001, 0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, + 0x7046, 0x68a0, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, + 0x000f, 0x0002, 0x2fe5, 0x2ebf, 0x2ebc, 0x3117, 0x31aa, 0x257f, + 0x2eba, 0x2eba, 0x080c, 0x252b, 0x6008, 0xc0d4, 0x600a, 0xd6e4, + 0x0120, 0x7044, 0xa086, 0x0014, 0x11e8, 0x080c, 0x3ed9, 0x2009, + 0x0000, 0x6818, 0xd0fc, 0x0108, 0x7044, 0xa086, 0x0014, 0x0168, + 0x6818, 0xa086, 0x0008, 0x1904, 0x2fa7, 0x7858, 0xd09c, 0x0904, + 0x2fa7, 0x6820, 0xd0ac, 0x0904, 0x2fa7, 0x681b, 0x0014, 0x2009, + 0x0002, 0x04a8, 0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, + 0x1158, 0x6008, 0xc0a4, 0x600a, 0x080c, 0x3717, 0x0540, 0x080c, + 0x3786, 0x080c, 0x3ed9, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, + 0xa005, 0x0d78, 0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, + 0x6820, 0xd084, 0x0904, 0x257f, 0xc084, 0x6822, 0x080c, 0x2672, + 0x7058, 0x00c6, 0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, + 0xa005, 0x2d00, 0x1108, 0x6002, 0x6006, 0x0804, 0x257f, 0x0016, + 0x81ff, 0x15f0, 0x7000, 0xa086, 0x0030, 0x05d0, 0x71d0, 0xd1bc, + 0x15b8, 0xd1b4, 0x11e8, 0x705c, 0xa005, 0x1590, 0x70a0, 0xa086, + 0x0001, 0x0570, 0x7003, 0x0000, 0x0046, 0x0056, 0x0076, 0x0066, + 0x00c6, 0x00d6, 0x080c, 0x25a4, 0x00de, 0x00ce, 0x006e, 0x007e, + 0x005e, 0x004e, 0x71d0, 0xd1b4, 0x11d8, 0x7003, 0x0040, 0x00c0, + 0x080c, 0x3bf9, 0x11a8, 0x781b, 0x0068, 0x00d6, 0x70b8, 0xa06d, + 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, + 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x00de, + 0x080c, 0x3068, 0x001e, 0x81ff, 0x0904, 0x2fa7, 0xa684, 0xdf00, + 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x1904, 0x2fa8, + 0x6818, 0xa086, 0x0014, 0x1130, 0x2008, 0xd6e4, 0x0118, 0x7868, + 0xa08c, 0x00ff, 0x080c, 0x3a18, 0x080c, 0x267d, 0x6820, 0xd0dc, + 0x1578, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xb284, + 0x0600, 0x0118, 0xa290, 0x49c0, 0x0010, 0xa290, 0x4a40, 0xa290, + 0x0000, 0x221c, 0xd3c4, 0x0170, 0x6820, 0xd0e4, 0x0128, 0xa084, + 0xefff, 0x6822, 0xc3ac, 0x2312, 0x8210, 0x2204, 0xa085, 0x0038, + 0x2012, 0x8211, 0xd3d4, 0x0138, 0x68a0, 0xd0c4, 0x1120, 0x080c, + 0x30d0, 0x0804, 0x257f, 0x6008, 0xc08d, 0x600a, 0x0008, 0x692a, + 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, + 0x691e, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4502, 0x2104, 0x8001, + 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4504, 0x2404, 0xc0a5, + 0x2022, 0x6018, 0xa005, 0x0118, 0x8001, 0x601a, 0x1118, 0x6008, + 0xc0a4, 0x600a, 0x6820, 0xd084, 0x1130, 0x6800, 0xa005, 0x1108, + 0x6002, 0x6006, 0x0020, 0x7058, 0x2060, 0x6800, 0x6002, 0x2061, + 0x4500, 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, + 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, 0x7200, 0xa286, 0x0030, + 0x0158, 0xa286, 0x0040, 0x1904, 0x257f, 0x7003, 0x0002, 0x7048, + 0x2068, 0x68c4, 0x2060, 0x0005, 0x7003, 0x0002, 0x70b8, 0xa06d, + 0x68bc, 0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, + 0xad80, 0x0009, 0x7042, 0x0005, 0xa282, 0x0004, 0x0210, 0x080c, + 0x252b, 0x2200, 0x0002, 0x300f, 0x301e, 0x302a, 0x301e, 0xa586, + 0x1300, 0x0160, 0xa586, 0x8300, 0x1d90, 0x7003, 0x0000, 0x6018, + 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x7000, 0xa086, + 0x0005, 0x0128, 0x080c, 0x39ff, 0x781b, 0x0082, 0x0005, 0x781b, + 0x0083, 0x0005, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080, + 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0128, + 0xa186, 0x0000, 0x0110, 0x0804, 0x39d0, 0x781b, 0x0083, 0x0005, + 0x6820, 0xc095, 0x6822, 0x82ff, 0x1118, 0x080c, 0x39ff, 0x0030, + 0x8211, 0x0110, 0x080c, 0x252b, 0x080c, 0x3a0e, 0x781b, 0x0082, + 0x0005, 0x080c, 0x3c0c, 0x7830, 0xa084, 0x00c0, 0x1170, 0x0016, + 0x3208, 0xa18c, 0x0800, 0x001e, 0x0118, 0x0104, 0x3065, 0x0010, + 0x0304, 0x3065, 0x791a, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, + 0xa684, 0x0060, 0x1130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, + 0x30cf, 0xd6dc, 0x1198, 0x68b4, 0xd0dc, 0x1180, 0x6998, 0x6a94, + 0x692e, 0x6a32, 0x7044, 0xa005, 0x1130, 0x2200, 0xa105, 0x0904, + 0x3ed9, 0x7047, 0x0015, 0x0804, 0x3ed9, 0x0005, 0xd6ac, 0x01f0, + 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3ed9, + 0x68b4, 0xa084, 0x4000, 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, + 0x1110, 0x7047, 0x0015, 0xd6dc, 0x1128, 0x68b4, 0xd0dc, 0x0110, + 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0804, 0x3ed9, 0xd6f4, 0x0130, + 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3ed9, 0x68b4, 0xa084, + 0x4800, 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, + 0x0015, 0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, + 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x1110, 0x0804, + 0x3ed9, 0x7000, 0xa086, 0x0006, 0x0110, 0x0804, 0x3ed9, 0x0005, + 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0108, 0xc08d, 0x600a, 0x6818, + 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, + 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, + 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0002, 0x257f, + 0x30ff, 0x30f9, 0x30f7, 0x30f7, 0x30f7, 0x30f7, 0x30f7, 0x080c, + 0x252b, 0x6820, 0xd084, 0x1118, 0x080c, 0x376c, 0x0030, 0x7058, + 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, 0x3208, 0xa18c, 0x0600, + 0x0118, 0x2021, 0x4557, 0x0010, 0x2021, 0x4597, 0x2404, 0xa005, + 0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b, 0x0000, 0x0005, 0x080c, + 0x3772, 0x080c, 0x3786, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, + 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916, 0x3208, + 0xa18c, 0x0600, 0x0118, 0x2009, 0x0000, 0x0010, 0x2009, 0x0001, + 0x080c, 0x428b, 0xd6dc, 0x01c8, 0x691c, 0xc1ed, 0x691e, 0x6828, + 0xa082, 0x000e, 0x0290, 0x6848, 0xa084, 0x000f, 0xa086, 0x000b, + 0x1160, 0x685c, 0xa086, 0x0047, 0x1140, 0x2001, 0x4501, 0x2004, + 0xd0ac, 0x1118, 0x2700, 0x080c, 0x2454, 0x6818, 0xd0fc, 0x0140, + 0x681b, 0x0000, 0x7868, 0xa08c, 0x00ff, 0x0110, 0x681b, 0x001e, + 0xb284, 0x0600, 0x1118, 0x2021, 0x4597, 0x0010, 0x2021, 0x4557, + 0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, + 0x6000, 0xd0a4, 0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, + 0x0020, 0x00d6, 0x00f6, 0x0156, 0x0146, 0x2079, 0x4500, 0x080c, + 0x1b77, 0x014e, 0x015e, 0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101, + 0x0026, 0x2204, 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800, + 0x0cc8, 0x6820, 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, + 0x00de, 0x7063, 0x0003, 0x707b, 0x0000, 0x7772, 0x707f, 0x000f, + 0x71d0, 0xc1c4, 0x71d2, 0x6818, 0xa086, 0x0002, 0x1138, 0x6817, + 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e, 0x080c, 0x1d89, + 0x0804, 0x257f, 0x7cd8, 0x7ddc, 0x7fd0, 0x080c, 0x3068, 0x682b, + 0x0000, 0x789b, 0x000e, 0x6f14, 0x080c, 0x3c10, 0xa08c, 0x00ff, + 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, + 0x691e, 0x7063, 0x0000, 0x0804, 0x257f, 0x7000, 0xa005, 0x1110, + 0x0804, 0x257f, 0xa006, 0x080c, 0x3ed9, 0x6920, 0xd1ac, 0x1110, + 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, + 0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, 0x257f, 0x31e7, 0x31e7, + 0x31ea, 0x31ea, 0x31ea, 0x31e5, 0x31e5, 0x080c, 0x252b, 0x6818, + 0x0804, 0x2ea4, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804, + 0x373a, 0x2300, 0x0002, 0x31f6, 0x31f8, 0x3241, 0x080c, 0x252b, + 0xd6fc, 0x1904, 0x2cdf, 0x7000, 0xa00d, 0x0002, 0x257f, 0x3208, + 0x3208, 0x3231, 0x3208, 0x323e, 0x3206, 0x3206, 0x080c, 0x252b, + 0xa684, 0x0060, 0x0530, 0xa086, 0x0060, 0x1508, 0xc6ac, 0xc6f4, + 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0148, + 0x080c, 0x3ed9, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x41ad, + 0x0010, 0x080c, 0x4180, 0x781b, 0x0083, 0x71d0, 0xd1b4, 0x1904, + 0x257c, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25c0, 0x0005, 0xd6ec, + 0x09f8, 0x6818, 0xd0fc, 0x0150, 0xd6f4, 0x1130, 0x681b, 0x0015, + 0x781b, 0x0083, 0x0804, 0x257c, 0x681b, 0x0007, 0x080c, 0x3bb7, + 0x0005, 0x080c, 0x252b, 0x2300, 0x0002, 0x324a, 0x326c, 0x32c3, + 0x080c, 0x252b, 0x7000, 0x0002, 0x3254, 0x3256, 0x325d, 0x3254, + 0x3254, 0x3254, 0x3254, 0x3254, 0x080c, 0x252b, 0x69ac, 0x68b0, + 0xa115, 0x0118, 0x080c, 0x41ad, 0x0010, 0x080c, 0x4180, 0x681c, + 0xc0b4, 0x681e, 0x70d0, 0xd0b4, 0x1904, 0x257c, 0x70a0, 0xa086, + 0x0001, 0x1904, 0x25c0, 0x0005, 0xd6fc, 0x1904, 0x32b3, 0x7000, + 0xa00d, 0x0002, 0x257f, 0x3282, 0x327c, 0x32ab, 0x3282, 0x32b0, + 0x327a, 0x327a, 0x080c, 0x252b, 0x6894, 0x78d6, 0x78de, 0x6898, + 0x78d2, 0x78da, 0xa684, 0x0060, 0x0530, 0xa086, 0x0060, 0x1508, + 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0xa186, 0x0002, 0x0148, 0x080c, + 0x3ed9, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x41ad, 0x0010, + 0x080c, 0x4180, 0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d0, + 0xd1b4, 0x1904, 0x257c, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25c0, + 0x0005, 0xd6ec, 0x09f8, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, + 0x781b, 0x00fb, 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, + 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, + 0x781b, 0x0083, 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, + 0x0083, 0x0804, 0x257c, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, + 0x0008, 0x1150, 0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, + 0x781b, 0x0083, 0x0804, 0x257c, 0x6820, 0xc095, 0x6822, 0x080c, + 0x3ba2, 0xc6dd, 0x080c, 0x39ff, 0x781b, 0x0082, 0x0804, 0x257c, + 0x2300, 0x0002, 0x32ed, 0x32ef, 0x32f1, 0x080c, 0x252b, 0x0804, + 0x39f9, 0x7d98, 0xd6d4, 0x11f8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, + 0xa084, 0x0003, 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, + 0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, + 0x78ec, 0xa084, 0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2ea4, + 0xa184, 0x0007, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, + 0x79a8, 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384, 0x0001, + 0x11d0, 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009, 0xffdf, + 0x0058, 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028, 0xa386, + 0x0003, 0x1148, 0x2009, 0xffef, 0x00c6, 0x7054, 0x2060, 0x6004, + 0xa104, 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, + 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff, 0x6922, + 0x7d9a, 0x0804, 0x3bab, 0x2b90, 0x2b99, 0x3355, 0x335b, 0x3353, + 0x3353, 0x3bab, 0x3bab, 0x080c, 0x252b, 0x6920, 0xa18c, 0xfcff, + 0x6922, 0x0804, 0x3bb1, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, + 0x3bab, 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084, 0x0003, + 0x1570, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086, 0x0002, + 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a4d, 0x7060, + 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90, 0x7000, + 0xa086, 0x0000, 0x0904, 0x257c, 0x6920, 0xa184, 0x0420, 0x0128, + 0xc1d4, 0x6922, 0x6818, 0x0804, 0x2ea4, 0x6818, 0xa08e, 0x0002, + 0x0120, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0804, 0x2ea4, 0xa184, + 0x0007, 0x0002, 0x3bab, 0x3bab, 0x33a2, 0x3bab, 0x3bef, 0x3bef, + 0x3bab, 0x3bab, 0xd6bc, 0x0570, 0x7180, 0x81ff, 0x0558, 0xa182, + 0x000d, 0x1318, 0x7083, 0x0000, 0x0028, 0xa182, 0x000c, 0x7082, + 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x0156, 0x0136, 0x0146, + 0x7084, 0x8114, 0xa210, 0x7286, 0xa080, 0x000b, 0xad00, 0x2098, + 0xb284, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, + 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e, 0x013e, 0x015e, + 0x0804, 0x3bb1, 0xd6d4, 0x1904, 0x3415, 0x6820, 0xd084, 0x0904, + 0x3bb1, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0120, 0xa086, 0x0060, + 0x1108, 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, + 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, + 0x810c, 0x0904, 0x379b, 0xa18c, 0x00f8, 0x1904, 0x379b, 0x0156, + 0x0136, 0x0146, 0x0016, 0x20a1, 0x012b, 0x3208, 0xa18c, 0x0600, + 0x0110, 0x20a1, 0x022b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, + 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6814, + 0xc0fc, 0x8007, 0x7882, 0x0804, 0x3bb1, 0x6818, 0xd0fc, 0x0110, + 0x681b, 0x0008, 0x080c, 0x39ff, 0x781b, 0x00ed, 0x0005, 0x2300, + 0x0002, 0x3426, 0x34e8, 0x3424, 0x080c, 0x252b, 0x7cd8, 0x7ddc, + 0x7fd0, 0x82ff, 0x1528, 0x7200, 0xa286, 0x0003, 0x0904, 0x2e72, + 0x71d0, 0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001, 0x4501, 0x2004, + 0xd0c4, 0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b, 0x0059, 0x70b8, + 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, + 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x0030, + 0x7200, 0x0020, 0x783b, 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, + 0x0002, 0x34d3, 0x3490, 0x3463, 0x2ea1, 0x3461, 0x34d3, 0x3461, + 0x3461, 0x080c, 0x252b, 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, + 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, + 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, 0x000e, 0x1148, + 0xb284, 0x0600, 0x0118, 0x2009, 0x8bc0, 0x0040, 0x2009, 0x8cd0, + 0x0028, 0x7030, 0x68ba, 0x713c, 0x70c8, 0xa108, 0x2104, 0x6802, + 0x2d0a, 0x715a, 0xd6dc, 0x1120, 0xc6fc, 0x6eb6, 0x0804, 0x34d3, + 0x6eb6, 0xa684, 0x0060, 0x1120, 0xa684, 0x7fff, 0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, - 0x68aa, 0x080c, 0x3d52, 0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c, - 0x3d52, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510, + 0x68aa, 0x080c, 0x3ed9, 0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c, + 0x3ed9, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x69aa, - 0x6aa6, 0x080c, 0x3d52, 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, + 0x6aa6, 0x080c, 0x3ed9, 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, - 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030, 0x1904, 0x248f, - 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, - 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, + 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030, 0x1904, 0x257f, + 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065, + 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3831, 0x7047, 0x0000, - 0xa282, 0x0006, 0x0310, 0x080c, 0x243b, 0x2300, 0x0002, 0x33b2, - 0x33e4, 0x340f, 0x2200, 0x0002, 0x33ba, 0x3831, 0x33bc, 0x33ba, - 0x343f, 0x349d, 0x080c, 0x243b, 0x7003, 0x0005, 0xb284, 0x0600, - 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, 0x2068, 0x704e, - 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x33cb, + 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x39f9, 0x7043, 0x0000, + 0xa282, 0x0006, 0x0310, 0x080c, 0x252b, 0x2300, 0x0002, 0x3502, + 0x3534, 0x355f, 0x2200, 0x0002, 0x350a, 0x39f9, 0x350c, 0x350a, + 0x358f, 0x35f9, 0x080c, 0x252b, 0x7003, 0x0005, 0xb284, 0x0600, + 0x0118, 0x2001, 0x8ce0, 0x0010, 0x2001, 0x8d12, 0x2068, 0x704a, + 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x351b, 0x015e, 0xb284, 0x0600, 0x0118, 0x6817, 0x0000, 0x0010, 0x6817, - 0x8000, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800, - 0x6827, 0x0003, 0x0804, 0x3809, 0x7000, 0xa086, 0x0002, 0x1150, - 0x080c, 0x35c5, 0x0010, 0x080c, 0x3d52, 0x6008, 0xa084, 0xfbef, + 0x8000, 0xad80, 0x0009, 0x7042, 0x68b7, 0x0700, 0x6823, 0x0800, + 0x6827, 0x0003, 0x0804, 0x39d0, 0x7000, 0xa086, 0x0002, 0x1150, + 0x080c, 0x3786, 0x0010, 0x080c, 0x3ed9, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8, 0x7003, 0x0005, - 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, - 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0002, 0x3831, - 0x340d, 0x340d, 0x343f, 0x340d, 0x3831, 0x080c, 0x243b, 0x7000, - 0xa086, 0x0002, 0x1150, 0x080c, 0x35c5, 0x0010, 0x080c, 0x3d52, + 0xb284, 0x0600, 0x0118, 0x2001, 0x8ce0, 0x0010, 0x2001, 0x8d12, + 0x2068, 0x704a, 0xad80, 0x0009, 0x7042, 0x2200, 0x0002, 0x39f9, + 0x355d, 0x355d, 0x358f, 0x355d, 0x39f9, 0x080c, 0x252b, 0x7000, + 0xa086, 0x0002, 0x1150, 0x080c, 0x3786, 0x0010, 0x080c, 0x3ed9, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, - 0x0da8, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, - 0x0010, 0x2001, 0x8b12, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, - 0x2200, 0x0002, 0x343a, 0x3438, 0x3438, 0x343a, 0x3438, 0x343a, - 0x080c, 0x243b, 0x080c, 0x3846, 0x781b, 0x0082, 0x0005, 0x7000, - 0xa086, 0x0002, 0x1158, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, - 0x2d00, 0x70be, 0x0038, 0x080c, 0x3d52, 0x0020, 0x7000, 0xa086, + 0x0da8, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001, 0x8ce0, + 0x0010, 0x2001, 0x8d12, 0x2068, 0x704a, 0xad80, 0x0009, 0x7042, + 0x2200, 0x0002, 0x358a, 0x3588, 0x3588, 0x358a, 0x3588, 0x358a, + 0x080c, 0x252b, 0x080c, 0x3a0e, 0x781b, 0x0082, 0x0005, 0x7000, + 0xa086, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, + 0x2d00, 0x70ba, 0x0038, 0x080c, 0x3ed9, 0x0020, 0x7000, 0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, - 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x89c0, 0xb284, - 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8ad0, 0x2d04, 0x2d08, 0x715e, + 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x8bc0, 0xb284, + 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8cd0, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0500, 0x6800, 0x0cb8, 0x7003, - 0x0005, 0xd2fc, 0x1118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, - 0x2068, 0x704e, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, - 0x1f04, 0x347d, 0x015e, 0xad80, 0x0009, 0x7046, 0x6a16, 0x68b7, + 0x0005, 0xd2fc, 0x1118, 0x2001, 0x8ce0, 0x0010, 0x2001, 0x8d12, + 0x2068, 0x704a, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, + 0x1f04, 0x35cd, 0x015e, 0xad80, 0x0009, 0x7042, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6920, - 0xa184, 0x0c00, 0x0904, 0x3507, 0x681b, 0x0005, 0xc1ad, 0xc1d4, - 0x6922, 0x080c, 0x383d, 0x0804, 0x3507, 0x7200, 0xa286, 0x0002, - 0x1158, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, - 0x0030, 0x080c, 0x3d52, 0x0018, 0xa286, 0x0003, 0x0dd0, 0x7003, - 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, - 0x001f, 0xa215, 0xb284, 0x0600, 0x1108, 0xc2fd, 0x79a8, 0x79a8, - 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d, - 0x0128, 0x6814, 0xa206, 0x0538, 0x6800, 0x0cb8, 0x7003, 0x0005, - 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, - 0x2068, 0x704e, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, - 0x1f04, 0x34dd, 0x015e, 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008, - 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, - 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0178, - 0xd0dc, 0x0118, 0x080c, 0x3843, 0x0050, 0x681b, 0x0005, 0xc1ad, - 0xc1d4, 0x6922, 0x080c, 0x383d, 0x707f, 0x0000, 0x0000, 0xa6ac, - 0x0060, 0x05c8, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11c0, - 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0xa586, 0x0060, - 0x0550, 0xc6ed, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, - 0x0082, 0x2019, 0x0000, 0x2320, 0x791a, 0x080c, 0x3fb8, 0x0418, - 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01a0, 0x7bd2, - 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xc6f4, 0x7e5a, 0x2011, 0x0083, - 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000, 0x2320, 0x7a1a, - 0x080c, 0x3fe5, 0x0040, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0110, - 0x2009, 0x0082, 0x791a, 0x68c0, 0x705a, 0x2d00, 0x704e, 0x68c4, - 0x2060, 0x71d4, 0xd1b4, 0x1904, 0x248c, 0x2300, 0xa405, 0x0904, - 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, 0x24ce, 0x0005, 0x6020, + 0xa184, 0x0c00, 0x0904, 0x3670, 0x7060, 0xa086, 0x0006, 0x1128, + 0x7070, 0xa206, 0x1110, 0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad, + 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a05, 0x0804, + 0x3670, 0x7200, 0xa286, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, + 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0030, 0x080c, 0x3ed9, 0x0018, + 0xa286, 0x0003, 0x0dd0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, + 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0xb284, 0x0600, + 0x1108, 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8, + 0xa168, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, + 0x0538, 0x6800, 0x0cb8, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, + 0x2001, 0x8ce0, 0x0010, 0x2001, 0x8d12, 0x2068, 0x704a, 0x0156, + 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x363a, 0x015e, + 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd, 0x6a16, 0xad80, + 0x0009, 0x7042, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, + 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x01d8, 0xd0dc, 0x0178, 0x7060, + 0xa086, 0x0004, 0x1140, 0x7070, 0xa206, 0x1128, 0x7074, 0xa306, + 0x1110, 0x7062, 0x707a, 0x080c, 0x3a0b, 0x0050, 0x681b, 0x0005, + 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a05, 0x707b, 0x0000, 0x0000, + 0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x36b7, 0x6b98, 0x6c94, 0x69ac, + 0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586, + 0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, + 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, 0x0082, 0x2019, 0x0000, + 0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c, 0x4180, 0x0470, 0x68b0, + 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01f8, 0x7bd2, 0x7bda, + 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108, 0xc6ed, 0xc6f4, 0x7e5a, + 0x2011, 0x0083, 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000, + 0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c, 0x41ad, 0x0070, 0x2019, + 0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083, + 0xd69c, 0x0110, 0x2009, 0x0082, 0x791a, 0x68c0, 0x7056, 0x2d00, + 0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001, 0x4501, 0x2004, 0xd0c4, + 0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc, 0x0548, 0x7a80, 0xa294, + 0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0, 0xa504, 0x1558, 0x70d6, + 0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001, 0x852c, 0x0218, 0x8633, + 0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594, 0xff00, 0x0130, 0x2011, + 0x0008, 0x852f, 0x0c81, 0x8637, 0x0008, 0x0c69, 0x8217, 0x7880, + 0xa084, 0x0f00, 0xa206, 0x0170, 0x72da, 0x76d6, 0x0058, 0x7a80, + 0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0, 0x78e0, 0xa534, 0x0da8, + 0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x257c, 0x2300, 0xa405, 0x0904, + 0x257c, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25c0, 0x0005, 0x6020, 0xa005, 0x0150, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, - 0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3d52, + 0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3ed9, + 0x7000, 0xa086, 0x0002, 0x0120, 0x7060, 0xa086, 0x0005, 0x1150, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, - 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x248f, 0x358b, - 0x3588, 0x35a7, 0x3594, 0x248f, 0x3586, 0x3586, 0x080c, 0x243b, - 0x0441, 0x0409, 0x0028, 0x0429, 0x705c, 0x2060, 0x6800, 0x6002, - 0x080c, 0x1d3d, 0x0804, 0x248f, 0x7064, 0x7067, 0x0000, 0x7083, - 0x0000, 0x0002, 0x35a3, 0x35a3, 0x35a2, 0x35a2, 0x35a2, 0x35a3, - 0x35a2, 0x35a3, 0x2971, 0x7067, 0x0000, 0x0804, 0x248f, 0x681b, - 0x0000, 0x0804, 0x3012, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, - 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4302, 0x2104, 0x8001, - 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4304, 0x2404, 0xc0a5, - 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005, 0x0110, - 0x8001, 0x601a, 0x0005, 0x080c, 0x3aa0, 0x681b, 0x0018, 0x04a0, - 0x080c, 0x3aa0, 0x681b, 0x0019, 0x0478, 0x080c, 0x3aa0, 0x681b, - 0x001a, 0x0450, 0x080c, 0x3aa0, 0x681b, 0x0003, 0x0428, 0x7774, - 0x080c, 0x396d, 0x7178, 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0600, - 0x0118, 0xa1e8, 0x88c0, 0x0010, 0xa1e8, 0x89d0, 0x2d04, 0x2d08, - 0x2068, 0xa005, 0x1118, 0x707e, 0x0804, 0x248f, 0x6814, 0xc0fc, - 0x7274, 0xc2fc, 0xa206, 0x0110, 0x6800, 0x0c88, 0x6800, 0x200a, - 0x681b, 0x0005, 0x707f, 0x0000, 0x080c, 0x35b1, 0x6820, 0xd084, - 0x1110, 0x080c, 0x35ab, 0x080c, 0x35c5, 0x681f, 0x0000, 0x6823, - 0x0020, 0x080c, 0x1d3d, 0x0804, 0x248f, 0xa282, 0x0003, 0x1904, - 0x380d, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, - 0xc1bd, 0x6922, 0xd1c4, 0x0590, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, - 0x0510, 0xa682, 0x001c, 0x0218, 0x0110, 0x2031, 0x001c, 0x852b, - 0x852b, 0x2041, 0x0000, 0x080c, 0x38c6, 0x0118, 0x080c, 0x36f6, - 0x00a0, 0x080c, 0x3892, 0x080c, 0x36f3, 0x6920, 0xc1c5, 0x6922, + 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x257f, 0x374b, + 0x3748, 0x3768, 0x3754, 0x257f, 0x3746, 0x3746, 0x080c, 0x252b, + 0x0449, 0x0411, 0x0028, 0x0431, 0x7058, 0x2060, 0x6800, 0x6002, + 0x080c, 0x1d89, 0x0804, 0x257f, 0x7060, 0x7063, 0x0000, 0x707f, + 0x0000, 0x0002, 0x3764, 0x3764, 0x3762, 0x3762, 0x3762, 0x3764, + 0x3762, 0x3764, 0x0804, 0x2a62, 0x7063, 0x0000, 0x0804, 0x257f, + 0x681b, 0x0000, 0x0804, 0x3117, 0x6800, 0xa005, 0x1108, 0x6002, + 0x6006, 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4502, 0x2104, + 0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4504, 0x2404, + 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005, + 0x0110, 0x8001, 0x601a, 0x0005, 0x080c, 0x3c0c, 0x681b, 0x0018, + 0x0490, 0x080c, 0x3c0c, 0x681b, 0x0019, 0x0468, 0x080c, 0x3c0c, + 0x681b, 0x001a, 0x0440, 0x080c, 0x3c0c, 0x681b, 0x0003, 0x0418, + 0x7770, 0x080c, 0x3b35, 0x7174, 0xa18c, 0x00ff, 0x3210, 0xa294, + 0x0600, 0x0118, 0xa1e8, 0x8ac0, 0x0010, 0xa1e8, 0x8bd0, 0x2d04, + 0x2d08, 0x2068, 0xa005, 0x1118, 0x707a, 0x0804, 0x257f, 0x6814, + 0x7270, 0xa206, 0x0110, 0x6800, 0x0c98, 0x6800, 0x200a, 0x681b, + 0x0005, 0x707b, 0x0000, 0x080c, 0x3772, 0x6820, 0xd084, 0x1110, + 0x080c, 0x376c, 0x080c, 0x3786, 0x681f, 0x0000, 0x6823, 0x0020, + 0x080c, 0x1d89, 0x0804, 0x257f, 0xa282, 0x0003, 0x1904, 0x39d5, + 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd, + 0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0530, + 0xa682, 0x001c, 0x0218, 0x0110, 0x2031, 0x001c, 0xa686, 0x0010, + 0x1108, 0x8630, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3a8e, + 0x0118, 0x080c, 0x38bd, 0x00a0, 0x080c, 0x3a5a, 0x080c, 0x38ba, + 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, + 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x080c, 0x38ba, + 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, + 0x0005, 0x00c6, 0x7054, 0x2060, 0x6100, 0xd1e4, 0x0598, 0x6208, + 0x8217, 0xa294, 0x00ff, 0xa282, 0x001c, 0x0218, 0x0110, 0x2011, + 0x001c, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686, 0x0010, 0x1108, + 0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282, + 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210, + 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, 0x3a5e, + 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3a8e, 0x0118, 0x080c, + 0x38bd, 0x0020, 0x080c, 0x3a5a, 0x080c, 0x38ba, 0x7858, 0xc095, + 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, 0x6000, + 0xd0e4, 0x1178, 0x6010, 0xa084, 0x000f, 0x1130, 0x6104, 0xa18c, + 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032, 0x2019, 0x0000, + 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294, 0x00ff, 0x78ec, + 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011, 0x000a, 0x0028, + 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, + 0x00ff, 0xa382, 0x001c, 0x0218, 0x0110, 0x2019, 0x001c, 0x78ab, + 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, + 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3a18, 0x00ce, 0x0005, + 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, + 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, + 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, + 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6, 0x7154, 0x2160, + 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86, 0x6018, 0x789a, + 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c, 0x000f, 0xa105, + 0x2029, 0x4505, 0x252c, 0xd5cc, 0x0140, 0xd3a4, 0x0110, 0xa085, + 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6, 0x6016, 0x788a, + 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605, 0x600e, 0x6004, + 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282, 0x0002, 0x1904, + 0x39de, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0568, 0xc1cc, + 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04, 0x39d0, 0x080c, + 0x3963, 0x080c, 0x38ba, 0xa980, 0x0001, 0x200c, 0x080c, 0x3b31, + 0x080c, 0x385d, 0x88ff, 0x0178, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, - 0x781b, 0x0082, 0x0005, 0x080c, 0x36f3, 0x7e58, 0xd6d4, 0x1118, - 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x00c6, 0x7058, - 0x2060, 0x6100, 0xd1e4, 0x0578, 0x6208, 0x8217, 0xa294, 0x00ff, - 0xa282, 0x001c, 0x0218, 0x0110, 0x2011, 0x001c, 0x2600, 0xa202, - 0x1208, 0x2230, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, - 0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, - 0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, - 0x3896, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x38c6, 0x0118, - 0x080c, 0x36f6, 0x0020, 0x080c, 0x3892, 0x080c, 0x36f3, 0x7858, - 0xc095, 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, - 0x6000, 0xd0e4, 0x1178, 0x6010, 0xa084, 0x000f, 0x1130, 0x6104, - 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032, 0x2019, - 0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294, 0x00ff, - 0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011, 0x000a, - 0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308, 0x831f, - 0xa39c, 0x00ff, 0xa382, 0x001c, 0x0218, 0x0110, 0x2019, 0x001c, - 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, - 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3850, 0x00ce, - 0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, - 0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0003, - 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, - 0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6, 0x7158, - 0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86, 0x6018, - 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c, 0x000f, - 0xa105, 0x2029, 0x4305, 0x252c, 0xd5cc, 0x0140, 0xd3a4, 0x0110, - 0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6, 0x6016, - 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605, 0x600e, - 0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282, 0x0002, - 0x1904, 0x3816, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0568, - 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04, 0x3809, - 0x080c, 0x379c, 0x080c, 0x36f3, 0xa980, 0x0001, 0x200c, 0x080c, - 0x3969, 0x080c, 0x3696, 0x88ff, 0x0178, 0x789b, 0x0060, 0x2800, - 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, - 0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118, 0x781b, - 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002, 0x1218, - 0xa284, 0x0001, 0x0140, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, - 0x1110, 0x2011, 0x0000, 0x080c, 0x3883, 0x0471, 0x080c, 0x36f3, - 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6, 0x0026, - 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1150, 0x6014, 0xa084, - 0x0040, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088, 0x2011, 0x0000, - 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, - 0x0004, 0x080c, 0x3850, 0x6820, 0xa085, 0x0200, 0x6822, 0x002e, - 0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009, 0x0000, 0x7058, - 0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018, 0xa080, 0x0002, - 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108, - 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020, 0x78a6, 0x6016, - 0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce, 0x0005, 0x0006, - 0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010, 0x000e, 0x0488, - 0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558, 0x7bb8, 0x8307, - 0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff, 0xa09e, 0x0001, - 0x1904, 0x382d, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, - 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x4083, 0x781b, - 0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, - 0x0001, 0x080c, 0x3f50, 0x0005, 0x080c, 0x243b, 0x781b, 0x0080, - 0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, - 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x36f6, 0x080c, 0x379a, - 0x7e58, 0x04f9, 0x781b, 0x0082, 0x0005, 0x0cd9, 0x6820, 0xc0c4, - 0x6822, 0x00c6, 0x7058, 0x2060, 0x0804, 0x3720, 0x0c91, 0x6820, - 0xc0cc, 0x6822, 0x00c6, 0x7058, 0x2060, 0x0804, 0x37b9, 0x0c49, - 0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7058, 0x2060, 0x6004, + 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, + 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002, 0x1218, 0xa284, + 0x0001, 0x0140, 0x7154, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x1110, + 0x2011, 0x0000, 0x080c, 0x3a4b, 0x0471, 0x080c, 0x38ba, 0x7858, + 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6, 0x0026, 0x2960, + 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1150, 0x6014, 0xa084, 0x0040, + 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088, 0x2011, 0x0000, 0x78ab, + 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, + 0x080c, 0x3a18, 0x6820, 0xa085, 0x0200, 0x6822, 0x002e, 0x00ce, + 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009, 0x0000, 0x7054, 0x2060, + 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, + 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108, 0xc0ed, + 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020, 0x78a6, 0x6016, 0x788a, + 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce, 0x0005, 0x0006, 0x7000, + 0xa086, 0x0003, 0x0110, 0x000e, 0x0010, 0x000e, 0x0488, 0xd6ac, + 0x0578, 0x7888, 0xa084, 0x0040, 0x0558, 0x7bb8, 0x8307, 0xa084, + 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff, 0xa09e, 0x0001, 0x1904, + 0x39f5, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, 0x0000, + 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x425d, 0x781b, 0x0080, + 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001, + 0x080c, 0x4118, 0x0005, 0x080c, 0x252b, 0x781b, 0x0080, 0x0005, + 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, + 0x0000, 0xa006, 0x2010, 0x080c, 0x38bd, 0x080c, 0x3961, 0x7e58, + 0x080c, 0x3a11, 0x781b, 0x0082, 0x0005, 0x0cd1, 0x6820, 0xc0c4, + 0x6822, 0x00c6, 0x7054, 0x2060, 0x0804, 0x38e7, 0x0c89, 0x6820, + 0xc0cc, 0x6822, 0x00c6, 0x7054, 0x2060, 0x0804, 0x3980, 0x0c41, + 0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7054, 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006, 0x00ce, 0x0005, 0x0049, 0x781b, 0x0082, 0x0005, 0x6827, 0x0002, 0x0049, 0x781b, 0x0082, 0x0005, 0x2001, 0x0005, 0x0088, 0x2001, 0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028, 0x2001, 0x0009, 0x0010, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, - 0x70d4, 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, 0x70b8, 0xa065, + 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, - 0xb28c, 0x0600, 0x0118, 0xa0e0, 0x47c0, 0x0010, 0xa0e0, 0x4840, + 0xb28c, 0x0600, 0x0118, 0xa0e0, 0x49c0, 0x0010, 0xa0e0, 0x4a40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae, 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0038, 0x6006, 0x007e, 0x0005, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, - 0x0804, 0x3850, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080, + 0x0804, 0x3a18, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa, - 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3850, 0x0156, 0x8007, + 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3a18, 0x0156, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, - 0xa18c, 0xffe0, 0x2021, 0x3952, 0x2019, 0x0011, 0x20a9, 0x000e, + 0xa18c, 0xffe0, 0x2021, 0x3b1a, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, 0xa106, 0x0128, 0x8420, - 0x2300, 0xa210, 0x1f04, 0x38ba, 0x015e, 0x0005, 0x0156, 0x0804, - 0x3908, 0x2021, 0x3960, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582, + 0x2300, 0xa210, 0x1f04, 0x3a82, 0x015e, 0x0005, 0x0156, 0x0804, + 0x3ad0, 0x2021, 0x3b28, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582, 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033, 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200, - 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x38df, 0x015e, - 0x0088, 0x2021, 0x3952, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, + 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3aa7, 0x015e, + 0x0088, 0x2021, 0x3b1a, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04, - 0x38f1, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064, + 0x3ab9, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064, 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x0005, - 0xa886, 0x0002, 0x01e8, 0x2021, 0x393e, 0x20a9, 0x000d, 0x2011, + 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b06, 0x20a9, 0x000d, 0x2011, 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011, 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04, - 0x3919, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890, - 0x2021, 0x394d, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024, + 0x3ae1, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890, + 0x2021, 0x3b15, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024, 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420, - 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x38f1, 0x1021, 0x2202, + 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3ab9, 0x1021, 0x2202, 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812, 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204, 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404, @@ -1391,314 +1485,319 @@ 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc, - 0x0118, 0xa0e0, 0x68c0, 0x0010, 0xa0e0, 0x48c0, 0x0005, 0x00e6, - 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4380, 0x2071, - 0x4380, 0x0030, 0x2009, 0x4340, 0x2079, 0x0200, 0x2071, 0x4340, - 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x39c5, 0x39a0, - 0x39a0, 0x39a0, 0x39a0, 0x39a0, 0x399e, 0x399e, 0x080c, 0x243b, - 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b, 0x0008, - 0x7848, 0xa084, 0x0008, 0x1de0, 0x68b4, 0xc0f5, 0x68b6, 0x7858, - 0xc0f5, 0x785a, 0x7830, 0xd0bc, 0x1180, 0xb284, 0x0800, 0x0118, - 0x0104, 0x39c5, 0x0010, 0x0304, 0x39c5, 0x681c, 0xd0ac, 0x1118, - 0x080c, 0x3a4b, 0x0010, 0x781b, 0x00fb, 0x2091, 0x8001, 0x00fe, - 0x00ee, 0x0005, 0x00c6, 0x2001, 0x4301, 0x2004, 0xd0ac, 0x1904, - 0x3a3d, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xb28c, 0x0600, 0x0118, 0xa0e0, 0x47c0, 0x0010, 0xa0e0, 0x4840, - 0x6004, 0xa084, 0x000a, 0x1904, 0x3a3d, 0x6108, 0xa194, 0xff00, - 0x0904, 0x3a3d, 0xa18c, 0x00ff, 0x601c, 0xa084, 0xff00, 0x0180, - 0x2001, 0x0009, 0xa102, 0x16b8, 0x2001, 0x000a, 0xa102, 0x16b0, - 0x2001, 0x000c, 0xa102, 0x16a8, 0x601c, 0xa084, 0x00ff, 0x601e, - 0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, - 0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, 0x0190, - 0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, 0x0180, - 0x00d8, 0x2009, 0x000c, 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, - 0x0014, 0x00a0, 0x2009, 0x0019, 0x0088, 0x2009, 0x0020, 0x0070, - 0x2009, 0x003f, 0x0058, 0x2009, 0x000a, 0x0040, 0x2009, 0x000c, - 0x0028, 0x2009, 0x0019, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, - 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x00ce, 0x0005, 0x781b, - 0x0083, 0x0005, 0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005, - 0x781b, 0x006e, 0x0005, 0x2009, 0x4319, 0x210c, 0xa186, 0x0000, - 0x0150, 0xa186, 0x0001, 0x0150, 0x701f, 0x000b, 0x7067, 0x0001, - 0x781b, 0x0054, 0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a, - 0x0005, 0x2009, 0x4319, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186, - 0x0001, 0x0138, 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0054, - 0x0005, 0x701f, 0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b, - 0x00fb, 0x0005, 0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005, - 0x781b, 0x00cb, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, - 0x7067, 0x0001, 0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, - 0x1170, 0x7808, 0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, - 0x78ec, 0xa084, 0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, - 0x7808, 0xc08d, 0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, - 0xb284, 0x0800, 0x0118, 0x1104, 0x3ab2, 0x0010, 0x1304, 0x3ab2, - 0x78ac, 0x0005, 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, - 0xe000, 0xe000, 0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, - 0x0118, 0x1104, 0x3ac1, 0x0010, 0x1304, 0x3ac4, 0x78ac, 0x0006, - 0x7808, 0xa085, 0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, - 0x1904, 0x30a0, 0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, - 0x080c, 0x23e1, 0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, - 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x248f, 0x0804, - 0x3a3f, 0xa784, 0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, - 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x248f, 0x78e4, - 0xa084, 0x0007, 0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, - 0x2030, 0x7e5a, 0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, - 0x7884, 0xd0fc, 0x0128, 0x080c, 0x382d, 0x681b, 0x0022, 0x0005, - 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, - 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, - 0x2a7a, 0xb284, 0x0800, 0x0110, 0x0104, 0x248c, 0x0304, 0x248c, - 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, - 0x0118, 0xa080, 0x4840, 0x0010, 0xa080, 0x47c0, 0x2060, 0x2048, - 0x705a, 0x2a60, 0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, - 0x3b81, 0xd1ac, 0x05e0, 0x6108, 0x8117, 0xa18c, 0x00ff, 0x631c, - 0x832f, 0x68a0, 0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, - 0xd0e4, 0x0110, 0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, - 0x1290, 0x78ec, 0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, - 0x000b, 0x1248, 0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, - 0x0000, 0x2029, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, - 0x0004, 0x79aa, 0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, - 0x0008, 0x6820, 0xa085, 0x1000, 0x6822, 0x080c, 0x3850, 0xa085, - 0x0001, 0x00ce, 0x0005, 0xa282, 0x0006, 0x1904, 0x381f, 0x7da8, - 0x7eac, 0x8637, 0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, - 0xa7bc, 0x00ff, 0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, - 0x05c8, 0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x37fc, - 0xa6b4, 0x00ff, 0x0560, 0xa682, 0x0039, 0x1a04, 0x37fc, 0xa582, - 0x0009, 0x0a04, 0x37fc, 0xa882, 0x0003, 0x1a04, 0x37fc, 0xa886, - 0x0002, 0x0128, 0xa886, 0x0000, 0x0138, 0x0804, 0x37fc, 0xa786, - 0x0000, 0x0904, 0x37fc, 0x8634, 0x852b, 0x852b, 0x080c, 0x38c6, - 0x0904, 0x37fc, 0x080c, 0x36f6, 0x080c, 0x379a, 0x7e58, 0xd6d4, - 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x080c, - 0x36f3, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7158, 0xa188, - 0x0000, 0x210c, 0xd1ac, 0x0904, 0x37fc, 0xd1ec, 0x1120, 0x2039, - 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000, 0x2041, - 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff, 0xa706, - 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f, 0xa39c, - 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705, 0xa086, - 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000, 0x2041, - 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284, 0xff00, - 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128, 0x852b, - 0x852b, 0x080c, 0x38c6, 0x0d58, 0x080c, 0x36f6, 0x080c, 0x379a, - 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, - 0x78ab, 0x0000, 0x7daa, 0x7eaa, 0x7faa, 0x2800, 0x78aa, 0x789b, - 0x0060, 0x78ab, 0x0005, 0x080c, 0x3850, 0x7858, 0xc095, 0x785a, - 0x781b, 0x0082, 0x0005, 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, 0x0009, 0x0014, - 0x0014, 0x9855, 0x984d, 0x0014, 0x9911, 0x98ff, 0x0014, 0x0014, - 0x0090, 0x00e7, 0x0100, 0x0402, 0x2008, 0xf880, 0x0018, 0x0017, - 0x840f, 0xd8c1, 0x0014, 0x0016, 0xa20a, 0x0014, 0x300b, 0xa20c, - 0x0014, 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0118, 0xa0e0, 0x6ac0, 0x0010, 0xa0e0, 0x4ac0, 0x0005, 0x00e6, + 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4580, 0x2071, + 0x4580, 0x0030, 0x2009, 0x4540, 0x2079, 0x0200, 0x2071, 0x4540, + 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x3b68, 0x3b68, + 0x3b68, 0x3b68, 0x3b68, 0x3b68, 0x3b66, 0x3b66, 0x080c, 0x252b, + 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0580, 0x7858, + 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, 0x1814, + 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b, + 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830, 0xd0bc, 0x11b8, + 0xb284, 0x0800, 0x0118, 0x0104, 0x3b9f, 0x0010, 0x0304, 0x3b9f, + 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084, 0x0003, 0x0138, + 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b, 0x00fb, 0x00fe, + 0x00ee, 0x0005, 0x2001, 0x4501, 0x2004, 0xd0ac, 0x1118, 0x6814, + 0x080c, 0x2454, 0x0005, 0x781b, 0x0083, 0x0005, 0x781b, 0x0082, + 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e, 0x0005, 0x2009, + 0x4519, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186, 0x0001, 0x0150, + 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x781b, + 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009, 0x4519, 0x210c, + 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138, 0x701f, 0x000b, + 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f, 0x000a, 0x0005, + 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005, 0x781b, 0x00fa, + 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb, 0x0005, 0x6818, + 0xd0fc, 0x0110, 0x681b, 0x001d, 0x7063, 0x0001, 0x781b, 0x0054, + 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808, 0xc08c, 0x780a, + 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084, 0x0021, 0x0118, + 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d, 0x780a, 0x0005, + 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800, 0x0118, 0x1104, + 0x3c1e, 0x0010, 0x1304, 0x3c1e, 0x78ac, 0x0005, 0x7808, 0xa084, + 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084, + 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104, 0x3c2d, 0x0010, + 0x1304, 0x3c30, 0x78ac, 0x0006, 0x7808, 0xa085, 0x0002, 0x780a, + 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x31c5, 0xa784, 0x0070, + 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2446, 0x2d78, 0x2c68, + 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008, 0x78ec, 0xa084, + 0x0003, 0x0904, 0x31c5, 0x0804, 0x3bab, 0xa784, 0x0004, 0x01c8, + 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008, 0x78ec, 0xa084, + 0x0003, 0x0904, 0x31c5, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, + 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00fb, + 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc, 0x0128, 0x080c, + 0x39f5, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003, 0x7858, 0xa084, + 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, + 0x78ec, 0xa084, 0x0003, 0x0904, 0x2b6b, 0xb284, 0x0800, 0x0110, + 0x0104, 0x257c, 0x0304, 0x257c, 0x6b14, 0x8307, 0xa084, 0x000f, + 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080, 0x4a40, 0x0010, + 0xa080, 0x49c0, 0x2060, 0x2048, 0x7056, 0x2a60, 0x0005, 0x00c6, + 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3ced, 0xd1ac, 0x05e0, 0x6108, + 0x8117, 0xa18c, 0x00ff, 0x631c, 0x832f, 0x68a0, 0xd0cc, 0x11c8, + 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110, 0x8213, 0x00b8, + 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec, 0xd0e4, 0x1118, + 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248, 0x2009, 0x000a, + 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029, 0x0000, 0x78ab, + 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa, 0x78ab, 0x0000, + 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820, 0xa085, 0x1000, + 0x6822, 0x080c, 0x3a18, 0xa085, 0x0001, 0x00ce, 0x0005, 0xa282, + 0x0006, 0x1904, 0x39e7, 0x7da8, 0x7eac, 0x8637, 0xa5ac, 0x00ff, + 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff, 0xa8c4, 0x00ff, + 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3d59, 0xa18c, 0xecff, + 0x6922, 0xa782, 0x0002, 0x1a04, 0x39c3, 0xa6b4, 0x00ff, 0x0904, + 0x3d56, 0xa682, 0x0039, 0x1a04, 0x39c3, 0xa582, 0x0009, 0x0a04, + 0x39c3, 0xa882, 0x0003, 0x1a04, 0x39c3, 0xa886, 0x0002, 0x01d0, + 0xa886, 0x0000, 0x1904, 0x39c3, 0x2001, 0x000c, 0x79ec, 0xd1e4, + 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c, 0x39c3, 0x00c6, + 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000, 0xc0ac, 0x6002, + 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x39c3, 0x8634, 0xa686, + 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c, 0x3a8e, 0x0904, + 0x39c3, 0x080c, 0x38bd, 0x080c, 0x3961, 0x7e58, 0xd6d4, 0x1118, + 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x080c, 0x38ba, + 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154, 0xa188, 0x0000, + 0x210c, 0xd1ac, 0x0904, 0x39c3, 0xd1ec, 0x1120, 0x2039, 0x0000, + 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000, 0x2041, 0x0000, + 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff, 0xa706, 0x0110, + 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f, 0xa39c, 0x00ff, + 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705, 0xa086, 0x0201, + 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000, 0x2041, 0x0000, + 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284, 0xff00, 0x1108, + 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128, 0x852b, 0x852b, + 0x080c, 0x3a8e, 0x0d58, 0x080c, 0x38bd, 0x080c, 0x3961, 0x789b, + 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x78ab, + 0x0000, 0x7daa, 0x7eaa, 0x7faa, 0x2800, 0x78aa, 0x789b, 0x0060, + 0x78ab, 0x0005, 0x080c, 0x3a18, 0x7858, 0xc095, 0x785a, 0x781b, + 0x0082, 0x0005, 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, + 0x9855, 0x984d, 0x0014, 0x9911, 0x98ff, 0x0014, 0x0014, 0x0090, + 0x00e7, 0x0100, 0x0402, 0x2008, 0xf880, 0x0018, 0x0017, 0x840f, + 0xd8c1, 0x0014, 0x0016, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, + 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, - 0x0010, 0x0010, 0xa200, 0x3806, 0x8839, 0x20c4, 0x0864, 0xa84f, - 0x3008, 0x28c1, 0x9d18, 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, - 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, 0x9cce, 0xa8f3, - 0x0864, 0xa83d, 0x300c, 0xa801, 0x3008, 0x28e1, 0x9cce, 0x2021, - 0xa818, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, - 0x6c80, 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, - 0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa814, 0x883e, - 0xa812, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x1814, - 0x883b, 0x7027, 0x8576, 0x8677, 0xa806, 0x796d, 0xa8da, 0x796b, - 0xa8f1, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d18, 0x2044, 0x2103, - 0x20b4, 0x2095, 0xa8ca, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, + 0x0010, 0xa200, 0x3806, 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, + 0x28c1, 0x9d18, 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, + 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, 0x9cce, 0xa8f3, 0x0864, + 0xa83e, 0x300c, 0xa801, 0x3008, 0x28e1, 0x9cce, 0x28a1, 0x7162, + 0x2021, 0xa818, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, + 0x67a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, + 0x7027, 0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa812, + 0x883e, 0xa810, 0x2881, 0x7161, 0x280a, 0xa204, 0x64c0, 0x6de0, + 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, + 0x7861, 0x883e, 0x206c, 0x28c1, 0x9d18, 0x2044, 0x2103, 0x20a2, + 0x2081, 0xa8ca, 0x2902, 0xa20e, 0xa80b, 0xa207, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, - 0x856e, 0x866f, 0x7121, 0x0014, 0x0704, 0x3008, 0x9cce, 0x0014, - 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, - 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881, - 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, - 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, - 0x8000, 0x2849, 0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2081, - 0x2802, 0x1011, 0xa8fc, 0xa889, 0x3008, 0x20a1, 0x283c, 0x1011, - 0xa8fc, 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, - 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, - 0x26e0, 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, - 0x9d22, 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, - 0x0016, 0x6042, 0x8008, 0xa8fa, 0x8160, 0x842a, 0x8180, 0xf021, - 0x3008, 0x84a8, 0x11d7, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, - 0x0016, 0x0000, 0x0126, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, - 0x7204, 0x7008, 0xc09c, 0xa205, 0x1178, 0x720c, 0x82ff, 0x0128, - 0x8aff, 0x1150, 0x7200, 0xd284, 0x1138, 0x7007, 0x0004, 0x7003, - 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003, 0x7002, - 0xc69c, 0xd084, 0x05b8, 0x2001, 0x4301, 0x2004, 0xd0b4, 0x0904, - 0x3dcf, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184, 0x0003, - 0x0904, 0x3dcf, 0xa184, 0x01e0, 0x1904, 0x3dcf, 0xd1f4, 0x1d88, - 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60, 0x2011, 0x0180, 0x710c, - 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20, 0x700c, 0xa106, 0x0dc0, - 0x7007, 0x0012, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184, - 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4, 0x0548, 0x7007, 0x0002, - 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130, 0x080c, 0x3e9e, 0x8aff, - 0x0904, 0x3d58, 0x0cb8, 0x700c, 0xa08c, 0x07ff, 0x01e8, 0x7004, - 0xd084, 0x0178, 0x7014, 0xa005, 0x1148, 0x7010, 0x7310, 0xa306, - 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102, 0x1e20, 0x7007, 0x0010, - 0x0030, 0x8aff, 0x0148, 0x080c, 0x4046, 0x1de8, 0x09d8, 0x080c, - 0x3e58, 0x012e, 0x2000, 0x0005, 0x7204, 0x7108, 0xc19c, 0x8103, - 0x1218, 0x080c, 0x3e9e, 0x0cc0, 0xa205, 0x1d88, 0x7007, 0x0004, - 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x6428, 0x84ff, 0x0508, - 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, - 0x1148, 0x0210, 0x080c, 0x243b, 0x609c, 0xa075, 0x0190, 0x0c88, - 0x2039, 0x3e0e, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, - 0x8421, 0x0138, 0x8738, 0x2704, 0xa005, 0x1da8, 0x709c, 0xa075, - 0x1d00, 0x0005, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015, - 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, - 0x0000, 0x0000, 0x3e0e, 0x3e0b, 0x0000, 0x0000, 0x8000, 0x0000, - 0x3e0e, 0x0000, 0x3e16, 0x3e13, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3e16, 0x0000, 0x3e11, 0x3e11, 0x0000, 0x0000, 0x8000, 0x0000, - 0x3e11, 0x0000, 0x3e17, 0x3e17, 0x0000, 0x0000, 0x0000, 0x0000, - 0x3e17, 0x2079, 0x4300, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, - 0x0002, 0x7003, 0x0001, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, - 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2001, 0x01ff, 0x2004, - 0xd0fc, 0x1128, 0x8109, 0x0118, 0x2071, 0x0020, 0x0c80, 0x0005, - 0x7004, 0x8004, 0x1690, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, - 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110, 0x080c, 0x243b, - 0xa19c, 0x300c, 0xa386, 0x2004, 0x0130, 0xa386, 0x0008, 0x0160, - 0xa386, 0x200c, 0x1d60, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, - 0x07ff, 0x0110, 0x080c, 0x243b, 0x7007, 0x0012, 0x7000, 0xd084, - 0x1160, 0x7008, 0xa084, 0x01e0, 0x1140, 0x7310, 0x7014, 0xa305, - 0x0120, 0x710c, 0xa184, 0x07ff, 0x1958, 0x7007, 0x0012, 0x7007, - 0x0008, 0x7004, 0xd09c, 0x1de8, 0x7007, 0x0012, 0x7108, 0x8103, - 0x0ed8, 0x7003, 0x0008, 0x0005, 0x7108, 0x0000, 0xa184, 0x01e0, - 0x1550, 0x7108, 0xa184, 0x01e0, 0x1530, 0xa184, 0x0007, 0x0002, - 0x3eb2, 0x3ec0, 0x3eb0, 0x3ec0, 0x3eb0, 0x3f06, 0x3eb0, 0x3f05, - 0x080c, 0x243b, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, - 0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x4046, 0x1de8, 0x0005, - 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0118, 0x080c, - 0x4046, 0x1de8, 0x0005, 0x7007, 0x0012, 0x7108, 0x1d04, 0x3ece, - 0x2091, 0x6000, 0x1d04, 0x3ed2, 0x2091, 0x6000, 0x7007, 0x0012, + 0x856e, 0x7121, 0x0014, 0x0704, 0x3008, 0x9cce, 0x0014, 0xa202, + 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, + 0x08e6, 0xa8f5, 0xf861, 0xa8eb, 0xf801, 0x0014, 0xf881, 0x0016, + 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, + 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, + 0x2849, 0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2081, 0x2802, + 0x1011, 0xa8fc, 0xa889, 0x3008, 0x20a1, 0x283c, 0x1011, 0xa8fc, + 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, + 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, + 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d22, + 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, + 0x6042, 0x8008, 0xa8fa, 0x8160, 0x842a, 0x8180, 0xf021, 0x3008, + 0x84a8, 0x11d7, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, + 0x0000, 0x0126, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, + 0x7008, 0xc09c, 0xa205, 0x1178, 0x720c, 0x82ff, 0x0128, 0x8aff, + 0x1150, 0x7200, 0xd284, 0x1138, 0x7007, 0x0004, 0x7003, 0x0008, + 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, + 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184, + 0x0003, 0x0904, 0x3f50, 0xa184, 0x01e0, 0x1904, 0x3f50, 0xd1f4, + 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60, 0x2011, 0x0180, + 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20, 0x700c, 0xa106, + 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, + 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4, 0x0548, 0x7007, + 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130, 0x080c, 0x4053, + 0x8aff, 0x0904, 0x3edf, 0x0cb8, 0x700c, 0xa08c, 0x07ff, 0x01e8, + 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148, 0x7010, 0x7310, + 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102, 0x1e20, 0x7007, + 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x4212, 0x1de8, 0x09d8, + 0x080c, 0x3fd9, 0x012e, 0x2000, 0x0005, 0x7204, 0x7108, 0xc19c, + 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205, 0x1d88, 0x7007, + 0x0004, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x6428, 0x84ff, + 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3f9a, 0x273c, + 0x87fb, 0x1148, 0x0210, 0x080c, 0x252b, 0x609c, 0xa075, 0x0190, + 0x0c88, 0x2039, 0x3f8f, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, + 0xa529, 0x8421, 0x0138, 0x8738, 0x2704, 0xa005, 0x1da8, 0x709c, + 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, + 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, + 0x001b, 0x0000, 0x0000, 0x3f8f, 0x3f8c, 0x0000, 0x0000, 0x8000, + 0x0000, 0x3f8f, 0x0000, 0x3f97, 0x3f94, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3f97, 0x0000, 0x3f92, 0x3f92, 0x0000, 0x0000, 0x8000, + 0x0000, 0x3f92, 0x0000, 0x3f98, 0x3f98, 0x0000, 0x0000, 0x0000, + 0x0000, 0x3f98, 0x2079, 0x4500, 0x2071, 0x0010, 0x7007, 0x000a, + 0x7007, 0x0002, 0x7003, 0x0001, 0x2009, 0x0002, 0x2071, 0x0050, + 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2001, 0x01ff, + 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118, 0x2071, 0x0020, 0x0c80, + 0x0005, 0x7004, 0x8004, 0x1a04, 0x402f, 0x7108, 0x7008, 0xa106, + 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x408b, 0x0804, 0x404f, + 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106, 0x1de0, + 0xa184, 0x01e0, 0x0120, 0x080c, 0x408b, 0x0804, 0x404f, 0xa19c, + 0x300c, 0xa386, 0x2004, 0x0190, 0xa386, 0x0008, 0x01c0, 0x7004, + 0xd084, 0x1148, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, + 0x0110, 0x0804, 0x408b, 0xa386, 0x200c, 0x19f0, 0x7200, 0x8204, + 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110, 0x080c, 0x252b, 0x7108, + 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0118, 0x080c, 0x408b, + 0x0470, 0x7007, 0x0012, 0x7000, 0xd084, 0x1148, 0x7310, 0x7014, + 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff, 0x1904, 0x3fd9, 0x7108, + 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0118, 0x080c, 0x408b, + 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8, + 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0118, 0x080c, + 0x408b, 0x0028, 0x7007, 0x0012, 0x7108, 0x8103, 0x0e88, 0x7003, + 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0, 0x15a8, 0x7108, 0xa184, + 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002, 0x4067, 0x4075, 0x4065, + 0x4075, 0x4065, 0x40c5, 0x4065, 0x40c3, 0x080c, 0x252b, 0x7004, + 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x1118, 0x2049, 0x0000, + 0x0005, 0x080c, 0x4212, 0x1de8, 0x0005, 0x7004, 0xa084, 0x0010, + 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140, 0x7108, 0x7008, 0xa106, + 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030, 0x8aff, 0x0118, 0x080c, + 0x4212, 0x1de8, 0x0005, 0x7007, 0x0012, 0x7108, 0x1d04, 0x408e, + 0x2091, 0x6000, 0x1d04, 0x4092, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000, 0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108, 0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001, - 0x080c, 0x397f, 0x6818, 0xa084, 0x8000, 0x0110, 0x681b, 0x0002, - 0x0005, 0x080c, 0x243b, 0x080c, 0x243b, 0x04b9, 0x7210, 0x7114, - 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, - 0x0461, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, - 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238, 0x8412, 0x8210, - 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60, 0x8a07, 0x0006, - 0x6004, 0xa084, 0x0008, 0x0118, 0xa7ba, 0x3e13, 0x0010, 0xa7ba, - 0x3e0b, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, - 0x7007, 0x0012, 0x080c, 0x3e58, 0x0005, 0x8a50, 0x8739, 0x2704, + 0x080c, 0x3b47, 0x681b, 0x0002, 0x2051, 0x0000, 0x0005, 0x080c, + 0x252b, 0x080c, 0x252b, 0x080c, 0x4105, 0x7210, 0x7114, 0x700c, + 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x04a9, + 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, + 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238, 0x8412, 0x8210, 0x830a, + 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60, 0x8a07, 0x0006, 0x6004, + 0xa084, 0x0008, 0x0118, 0xa7ba, 0x3f94, 0x0010, 0xa7ba, 0x3f8c, + 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108, + 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110, 0x080c, 0x408b, + 0x7007, 0x0012, 0x080c, 0x3fd9, 0x0005, 0x8a50, 0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60, 0x6004, 0xa084, - 0x000f, 0xa080, 0x3e29, 0x203c, 0x87fb, 0x090c, 0x243b, 0x0005, - 0x0126, 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, + 0x000f, 0xa080, 0x3faa, 0x203c, 0x87fb, 0x090c, 0x252b, 0x0005, + 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008, 0x000e, 0x0118, - 0xa0b8, 0x3e13, 0x0010, 0xa0b8, 0x3e0b, 0xb284, 0x0200, 0x0110, + 0xa0b8, 0x3f94, 0x0010, 0xa0b8, 0x3f8c, 0xb284, 0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0520, 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203, - 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4067, 0x0010, - 0x080c, 0x4046, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6, - 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004, + 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x423a, 0x0010, + 0x080c, 0x4212, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6, + 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004, 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, - 0x0126, 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, + 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, 0x2d60, - 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, 0x1138, - 0x0210, 0x080c, 0x243b, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c, - 0x4046, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016, - 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284, + 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3f9a, 0x273c, 0x87fb, 0x1138, + 0x0210, 0x080c, 0x252b, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c, + 0x4212, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016, + 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, - 0x2049, 0x3fe5, 0x6828, 0xa055, 0x05f0, 0x2d70, 0x2e60, 0x7004, - 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, 0x1140, 0x0210, - 0x080c, 0x243b, 0x709c, 0xa075, 0x2060, 0x0568, 0x0c80, 0x2704, - 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268, 0x8a51, 0x1110, - 0x080c, 0x243b, 0x8738, 0x2704, 0xa005, 0x1d90, 0x709c, 0xa075, - 0x2060, 0x01c8, 0x08e0, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, - 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1210, 0x080c, - 0x243b, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050, 0x0010, 0x2071, - 0x0020, 0x0804, 0x3f79, 0x012e, 0x2000, 0x0005, 0x7008, 0xa084, - 0x0003, 0xa086, 0x0003, 0x1108, 0x0005, 0x2704, 0xac78, 0x7800, - 0x701a, 0x7804, 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, - 0xa084, 0x0008, 0x0120, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, - 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4300, 0x8a51, - 0x01b0, 0x8738, 0x2704, 0xa005, 0x1168, 0x609c, 0xa005, 0x0180, - 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x3e19, 0x203c, 0x87fb, - 0x090c, 0x243b, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x0005, - 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6, 0x70d4, 0xa084, - 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108, 0xa184, 0x0003, - 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3d6c, 0x7108, 0xd1fc, - 0x0118, 0x080c, 0x3e9e, 0x0c88, 0x7007, 0x0010, 0x7108, 0xd1fc, - 0x0de8, 0x080c, 0x3e9e, 0x7008, 0xa086, 0x0008, 0x1d30, 0x7000, - 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000, 0x012e, 0x2000, - 0x0005, 0x0126, 0x0146, 0x0136, 0x0156, 0x00c6, 0x00d6, 0x70d4, - 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x2049, 0x40b1, 0xad80, - 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118, 0x2099, 0x0032, 0x0010, - 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff, 0x682a, 0x7007, 0x0008, - 0x7007, 0x0002, 0x7003, 0x0001, 0x0118, 0x8000, 0x80ac, 0x53a5, - 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084, - 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000, 0x7003, 0x0000, 0x015e, - 0x013e, 0x014e, 0x012e, 0x2000, 0x0005, 0x2091, 0x8000, 0x2091, - 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974, 0x70d0, 0xa106, 0x1148, - 0x781c, 0xa005, 0x0130, 0x781f, 0x0000, 0x0e04, 0x4101, 0x2091, - 0x4080, 0x7830, 0x8001, 0x7832, 0x1904, 0x416b, 0x7834, 0x7832, - 0x2061, 0x68c0, 0x2069, 0x4380, 0xc7fd, 0x68d0, 0xa005, 0x0128, - 0x8001, 0x68d2, 0x1110, 0x080c, 0x42c4, 0x6800, 0xa084, 0x000f, - 0x0168, 0xa086, 0x0001, 0x0150, 0x6844, 0xa00d, 0x0138, 0x2104, - 0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x425f, 0x6814, 0xa005, - 0x01a8, 0x8001, 0x6816, 0x1190, 0x68a7, 0x0001, 0x00f6, 0xd7fc, - 0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3aa0, - 0x00fe, 0x6864, 0xa005, 0x0110, 0x080c, 0x2233, 0x6880, 0xa005, - 0x0140, 0x8001, 0x6882, 0x1128, 0x6867, 0x0000, 0x68d4, 0xc0c5, - 0x68d6, 0x68d4, 0xd0fc, 0x01b0, 0xc0fc, 0x68d6, 0x20a9, 0x0200, - 0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d4, 0xc0fd, 0x68d6, - 0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x2233, 0xace0, 0x0010, - 0x1f04, 0x4150, 0xd7fc, 0x0138, 0x2061, 0x48c0, 0x2069, 0x4340, - 0xc7fc, 0x0804, 0x410d, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0, - 0x783c, 0x783a, 0x2061, 0x48c0, 0x2069, 0x4340, 0xc7fc, 0x680c, - 0xa005, 0x0110, 0x080c, 0x41c9, 0xd7fc, 0x1130, 0x2061, 0x68c0, - 0x2069, 0x4380, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac, - 0x1120, 0xd0a4, 0x0148, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0e04, - 0x4193, 0x080c, 0x1ffe, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840, - 0x8001, 0x7842, 0x1568, 0x7844, 0x7842, 0x2091, 0x8000, 0x2061, - 0x48c0, 0x2069, 0x4340, 0xc7fc, 0x6810, 0xa005, 0x1110, 0x2001, - 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118, 0xa080, 0x89d0, 0x0010, - 0xa080, 0x88c0, 0x2040, 0x2004, 0xa065, 0x0150, 0x6024, 0xa005, - 0x0120, 0x8001, 0x6026, 0x0904, 0x4207, 0x6000, 0x2c40, 0x0ca0, - 0xd7fc, 0x1130, 0x2061, 0x68c0, 0x2069, 0x4380, 0xc7fd, 0x08e0, - 0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0540, - 0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0400, 0x6008, 0xc09c, - 0xd084, 0x1110, 0xd0ac, 0x01a8, 0x600a, 0x6004, 0xa06d, 0x01c0, - 0x00c6, 0x0016, 0x6010, 0x8001, 0x6012, 0x080c, 0x35ab, 0x2d00, - 0x2c68, 0x2060, 0x080c, 0x1b85, 0x080c, 0x1d30, 0x001e, 0x00ce, - 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d, 0x0100, - 0xace0, 0x0010, 0x1f04, 0x41cd, 0xa184, 0x0001, 0x0130, 0xa18c, - 0xfffe, 0x690e, 0x080c, 0x2233, 0x0008, 0x690e, 0x0005, 0x6800, - 0xa005, 0x0120, 0x684c, 0xac06, 0x0904, 0x425f, 0x6864, 0xa005, - 0x0120, 0x6027, 0x0001, 0x0804, 0x425c, 0x2c00, 0x687e, 0x6714, - 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, - 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, - 0x6022, 0x6000, 0x2042, 0x080c, 0x1b1d, 0x6818, 0xa005, 0x0110, - 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, - 0x790a, 0x8001, 0x1310, 0x080c, 0x243b, 0x6812, 0x1118, 0x7910, - 0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c, - 0x1d3d, 0xd7fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, 0x4380, - 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x697a, 0x2001, - 0x0004, 0x2708, 0x080c, 0x2228, 0x2091, 0x8001, 0x0005, 0x00d6, - 0x694c, 0x2160, 0xd7fc, 0x1118, 0x2069, 0x0200, 0x0010, 0x2069, - 0x0100, 0x080c, 0x23e1, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, - 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, - 0x0000, 0x6033, 0x0000, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004, - 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x4282, 0x684b, - 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x428b, - 0x20a9, 0x00fa, 0x1f04, 0x4292, 0x6808, 0xa084, 0xfffd, 0x680a, - 0x681b, 0x0054, 0x00de, 0x6867, 0x0007, 0x2091, 0x8001, 0x0005, - 0x2079, 0x4300, 0x00e1, 0x0089, 0x00a9, 0x2009, 0x0002, 0x2069, - 0x4380, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, 0x0000, 0x8109, - 0x0118, 0x2069, 0x4340, 0x0ca8, 0x0005, 0x2019, 0x00a3, 0x7b3a, - 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42, 0x7b46, 0x0005, 0x2019, - 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6950, 0xa185, 0x0000, 0x0178, - 0x00c6, 0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, - 0xc0b5, 0x600a, 0x8210, 0x8109, 0x1da8, 0x6952, 0x00ce, 0x0005, - 0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0180, 0x0088, 0xae8e, 0x0100, - 0x0130, 0x7814, 0xc0f5, 0x7816, 0xd0d4, 0x1170, 0x0050, 0x7814, - 0xc0fd, 0x7816, 0xd0d4, 0x1140, 0x0020, 0xd0e4, 0x0138, 0x70a0, - 0x70a2, 0x7804, 0xd08c, 0x0110, 0x681f, 0x000c, 0x0005, 0xaf67 + 0x2049, 0x41ad, 0x6828, 0xa055, 0x00d6, 0x0904, 0x420e, 0x2d70, + 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3f9a, 0x273c, 0x87fb, + 0x1140, 0x0210, 0x080c, 0x252b, 0x709c, 0xa075, 0x2060, 0x0570, + 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268, + 0x8a51, 0x1110, 0x080c, 0x252b, 0x8738, 0x2704, 0xa005, 0x1d90, + 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420, 0x831a, + 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, + 0x1210, 0x080c, 0x252b, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050, + 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x4141, 0x00de, 0x012e, + 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110, + 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108, 0x0005, + 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, 0x7012, + 0x780c, 0x7016, 0x6004, 0xa084, 0x0008, 0x0120, 0x7810, 0x7022, + 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, + 0x2079, 0x4500, 0x8a51, 0x01e8, 0x8738, 0x2704, 0xa005, 0x1168, + 0x609c, 0xa005, 0x01b8, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, + 0x3f9a, 0x203c, 0x87fb, 0x090c, 0x252b, 0x7008, 0x0006, 0xa084, + 0x01e0, 0x000e, 0x0110, 0xa006, 0x0028, 0xa084, 0x0003, 0xa086, + 0x0003, 0x0005, 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6, + 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108, + 0xa184, 0x0003, 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3ef3, + 0x7108, 0xd1fc, 0x0118, 0x080c, 0x4053, 0x0c88, 0x7007, 0x0010, + 0x7108, 0xd1fc, 0x0de8, 0x080c, 0x4053, 0x7008, 0xa086, 0x0008, + 0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000, + 0x012e, 0x2000, 0x0005, 0x0126, 0x0146, 0x0136, 0x0156, 0x00c6, + 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x2049, + 0x428b, 0xad80, 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118, 0x2099, + 0x0032, 0x0010, 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff, 0x682a, + 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0118, 0x8000, + 0x80ac, 0x53a5, 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007, 0x0004, + 0x7004, 0xa084, 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000, 0x7003, + 0x0000, 0x015e, 0x013e, 0x014e, 0x012e, 0x2000, 0x0005, 0x2091, + 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974, 0x70d0, + 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f, 0x0000, 0x0e04, + 0x42db, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x1904, 0x4345, + 0x7834, 0x7832, 0x2061, 0x6ac0, 0x2069, 0x4580, 0xc7fd, 0x68cc, + 0xa005, 0x0128, 0x8001, 0x68ce, 0x1110, 0x080c, 0x44ad, 0x6800, + 0xa084, 0x000f, 0x0168, 0xa086, 0x0001, 0x0150, 0x6840, 0xa00d, + 0x0138, 0x2104, 0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x444a, + 0x6814, 0xa005, 0x01a8, 0x8001, 0x6816, 0x1190, 0x68a3, 0x0001, + 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, + 0x080c, 0x3c0c, 0x00fe, 0x6860, 0xa005, 0x0110, 0x080c, 0x2296, + 0x687c, 0xa005, 0x0140, 0x8001, 0x687e, 0x1128, 0x6863, 0x0000, + 0x68d0, 0xc0c5, 0x68d2, 0x68d0, 0xd0fc, 0x01b0, 0xc0fc, 0x68d2, + 0x20a9, 0x0200, 0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d0, + 0xc0fd, 0x68d2, 0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x2296, + 0xace0, 0x0010, 0x1f04, 0x432a, 0xd7fc, 0x0138, 0x2061, 0x4ac0, + 0x2069, 0x4540, 0xc7fc, 0x0804, 0x42e7, 0x0459, 0x7838, 0x8001, + 0x783a, 0x11a0, 0x783c, 0x783a, 0x2061, 0x4ac0, 0x2069, 0x4540, + 0xc7fc, 0x680c, 0xa005, 0x0110, 0x080c, 0x43c1, 0xd7fc, 0x1130, + 0x2061, 0x6ac0, 0x2069, 0x4580, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, + 0x0168, 0xd0ac, 0x1120, 0xd0a4, 0x0148, 0xc0ad, 0x7812, 0x2091, + 0x8001, 0x0e04, 0x436d, 0x080c, 0x2061, 0x0005, 0x2091, 0x8001, + 0x0005, 0x7840, 0x8001, 0x7842, 0x1904, 0x43c0, 0x7844, 0x7842, + 0x2069, 0x4540, 0xc7fc, 0x2079, 0x0200, 0x68d4, 0xa005, 0x0138, + 0x7de0, 0xa504, 0x1120, 0x68d6, 0x68d0, 0xc0bc, 0x68d2, 0x2079, + 0x4500, 0x6810, 0xa005, 0x1110, 0x2001, 0x0101, 0x8001, 0x6812, + 0xd7fc, 0x0118, 0xa080, 0x8bd0, 0x0010, 0xa080, 0x8ac0, 0x2040, + 0x2004, 0xa065, 0x01e0, 0x6024, 0xa005, 0x01b0, 0x8001, 0x6026, + 0x1198, 0x6800, 0xa005, 0x0130, 0x6848, 0xac06, 0x1118, 0x080c, + 0x444a, 0x0068, 0x6860, 0xa005, 0x0118, 0x6027, 0x0001, 0x0020, + 0x080c, 0x4402, 0x2804, 0x0c28, 0x6000, 0x2c40, 0x0c10, 0xd7fc, + 0x1138, 0x2069, 0x4580, 0xc7fd, 0x2079, 0x0100, 0x0804, 0x437d, + 0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0558, + 0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0418, 0x6008, 0xc09c, + 0xd084, 0x1110, 0xd0ac, 0x01c0, 0x600a, 0x6004, 0xa005, 0x01d8, + 0x00d6, 0x00c6, 0x0016, 0x2068, 0x6010, 0x8001, 0x6012, 0x080c, + 0x376c, 0x2d00, 0x2c68, 0x2060, 0x080c, 0x1bc7, 0x080c, 0x1d7c, + 0x001e, 0x00ce, 0x00de, 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, + 0x0010, 0xa18d, 0x0100, 0xace0, 0x0010, 0x1f04, 0x43c5, 0xa184, + 0x0001, 0x0130, 0xa18c, 0xfffe, 0x690e, 0x080c, 0x2296, 0x0008, + 0x690e, 0x0005, 0x2c00, 0x687a, 0x6714, 0x6f72, 0x6017, 0x0000, + 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084, 0x5f00, 0x601e, + 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, + 0x080c, 0x1b5f, 0x6818, 0xa005, 0x0110, 0x8001, 0x681a, 0x6808, + 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x1310, + 0x080c, 0x252b, 0x6812, 0x1118, 0x7910, 0xc1a5, 0x7912, 0x602f, + 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c, 0x1d89, 0xd7fc, 0x1118, + 0x2069, 0x4540, 0x0010, 0x2069, 0x4580, 0x6910, 0xa184, 0x0100, + 0x2001, 0x0006, 0x1118, 0x6976, 0x2001, 0x0004, 0x2708, 0x080c, + 0x228b, 0x0005, 0x00d6, 0x6948, 0x2160, 0xd7fc, 0x1118, 0x2069, + 0x0200, 0x0010, 0x2069, 0x0100, 0x080c, 0x2446, 0x601b, 0x0006, + 0x6858, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, + 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6808, 0xa084, + 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004, 0x20a9, + 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x4471, 0x684b, 0x0009, + 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x447a, 0x20a9, + 0x00fa, 0x1f04, 0x4481, 0x681b, 0x0054, 0x00de, 0x6863, 0x0007, + 0x0005, 0x2079, 0x4500, 0x00e1, 0x0089, 0x00a9, 0x2009, 0x0002, + 0x2069, 0x4580, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, 0x0000, + 0x8109, 0x0118, 0x2069, 0x4540, 0x0ca8, 0x0005, 0x2019, 0x00a3, + 0x7b3a, 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42, 0x7b46, 0x0005, + 0x2019, 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x694c, 0xa185, 0x0000, + 0x0158, 0x00c6, 0x6abc, 0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, + 0x8109, 0x1dc8, 0x694e, 0x00ce, 0x0005, 0x70ec, 0xd0dc, 0x1118, + 0xd0d4, 0x0190, 0x0098, 0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5, + 0xc0c5, 0x7816, 0xd0d4, 0x11a8, 0x0088, 0x7814, 0xc0fd, 0xc0c5, + 0x7816, 0xd0d4, 0x1170, 0x0050, 0xd0e4, 0x0168, 0x70e4, 0xa084, + 0x01ff, 0xa086, 0x01ff, 0x0d38, 0x70a0, 0x70a2, 0x7804, 0xd08c, + 0x0110, 0x681f, 0x000c, 0x0005, 0x69ca }; #ifdef UNIQUE_FW_NAME -unsigned short fw12160i_length01 = 0x32f8; +unsigned short fw12160i_length01 = 0x34e5; #else -unsigned short risc_code_length01 = 0x32f8; +unsigned short risc_code_length01 = 0x34e5; #endif diff -urN linux-2.4.0-test12/drivers/scsi/ql1280_fw.h linux-2.4.0-test12-lia/drivers/scsi/ql1280_fw.h --- linux-2.4.0-test12/drivers/scsi/ql1280_fw.h Mon Feb 7 19:45:28 2000 +++ linux-2.4.0-test12-lia/drivers/scsi/ql1280_fw.h Mon Oct 30 22:17:11 2000 @@ -1,59 +1,117 @@ /************************************************************************ + * * + * --- ISP1240/1080/1280 Initiator Firmware --- * + * 32 LUN Support * + * * + ************************************************************************ - * Copyright (C) 1999,2000 Qlogic, Corporation. + + * * + + * Copyright (C) 1999,2000 Qlogic, Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that the following conditions are met: + * 1. Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products + + * 2. Redistribution in binary form must reproduce the above copyright + + * notice, this list of conditions and the following disclaimer in the + + * documentation and/or other materials provided with the distribution. + + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * * + ************************************************************************ + */ /* - * Firmware Version 8.09.00 (18:29 Apr 16, 1999) + * Firmware Version 8.13.08 (10:53 Jan 14, 2000) */ -unsigned short fw1280ei_version = 8*1024+9; +#ifdef UNIQUE_FW_NAME +unsigned short fw1280ei_version = 8*1024+13; +#else +unsigned short risc_code_version = 8*1024+13; +#endif + +#ifdef UNIQUE_FW_NAME +unsigned char fw1280ei_version_str[] = {8,13,8}; +#else +unsigned char firmware_version[] = {8,13,8}; +#endif -unsigned char fw1280ei_version_str[] = {8,9,0}; +#ifdef UNIQUE_FW_NAME +#define fw1280ei_VERSION_STRING "8.13.8" +#else +#define FW_VERSION_STRING "8.13.8" +#endif +#ifdef UNIQUE_FW_NAME unsigned short fw1280ei_addr01 = 0x1000 ; +#else +unsigned short risc_code_addr01 = 0x1000 ; +#endif +#ifdef UNIQUE_FW_NAME unsigned short fw1280ei_code01[] = { - 0x0078, 0x1041, 0x0000, 0x39e3, 0x0000, 0x2043, 0x4f50, 0x5952, +#else +unsigned short risc_code01[] = { +#endif + 0x0078, 0x1041, 0x0000, 0x3c71, 0x0000, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350, 0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056, - 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3039, 0x2020, 0x2043, + 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3133, 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020, - 0x2400, 0x20c9, 0x93ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080, + 0x2400, 0x20c9, 0x96ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, - 0x2089, 0x136a, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086, + 0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071, - 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13ea, 0x0078, - 0x106d, 0x20c1, 0x0020, 0x2089, 0x1312, 0x2071, 0x0010, 0x70c3, + 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f8, 0x0078, + 0x106d, 0x20c1, 0x0020, 0x2089, 0x131c, 0x2071, 0x0010, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, @@ -61,1838 +119,1924 @@ 0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0, 0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080, 0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128, - 0xa1a2, 0x4a00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, - 0xa192, 0x9400, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x2078, - 0x2218, 0x2079, 0x4a00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, - 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2001, 0x04fc, 0x2004, - 0xa086, 0x1080, 0x00c0, 0x10db, 0x2071, 0x0100, 0x0d7e, 0x2069, - 0x4a40, 0x1078, 0x49ae, 0x0d7f, 0x7810, 0xc0ed, 0x7812, 0x781b, - 0x0064, 0x0078, 0x1100, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280, - 0x00c0, 0x10fb, 0x7814, 0xc0ed, 0xc0d5, 0x7816, 0x781b, 0x0064, - 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4a40, 0x1078, 0x49ae, 0x2069, - 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, 0x7814, 0xc0d4, 0x7816, - 0x0d7f, 0x0078, 0x1100, 0x7814, 0xc0e5, 0x7816, 0x781b, 0x003c, - 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802, - 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002, - 0x2009, 0x0002, 0x2069, 0x4a40, 0x681b, 0x0003, 0x6823, 0x0007, - 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000, - 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0040, - 0x1154, 0x68d3, 0x000a, 0x68c3, 0x4ac0, 0x2079, 0x4a00, 0x7814, - 0xd0e4, 0x00c0, 0x113a, 0xd0ec, 0x00c0, 0x113e, 0x68d7, 0x7329, - 0x0078, 0x1140, 0x68d7, 0x730d, 0x0078, 0x1140, 0x68d7, 0x7329, - 0x68c7, 0x4fc0, 0x68cb, 0x4ec0, 0x68cf, 0x8fc0, 0x68ab, 0x9244, - 0x68af, 0x9249, 0x68b3, 0x9244, 0x68b7, 0x9244, 0x68a7, 0x0001, - 0x2069, 0x4a80, 0x0078, 0x1114, 0x68d3, 0x000a, 0x68c3, 0x4cc0, - 0x7814, 0xd0e4, 0x00c0, 0x1160, 0x68d7, 0x7439, 0x0078, 0x1162, - 0x68d7, 0x7419, 0x68c7, 0x6fc0, 0x68cb, 0x4f40, 0x68cf, 0x90d0, - 0x68ab, 0x9249, 0x68af, 0x924e, 0x68b3, 0x9249, 0x68b7, 0x9249, - 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11b8, 0x7814, 0xd0e4, - 0x00c0, 0x11aa, 0x0e7e, 0x2069, 0x4ec0, 0x2071, 0x0200, 0x70ec, - 0xd0e4, 0x00c0, 0x118b, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, - 0x2007, 0x0078, 0x1191, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, - 0x2007, 0x2069, 0x4f40, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0, - 0x11a1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0078, - 0x11a7, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, 0x0e7f, - 0x0078, 0x11d1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x2069, 0x4ec0, - 0x1078, 0x2007, 0x2069, 0x4f40, 0x1078, 0x2007, 0x0078, 0x11d1, - 0x2069, 0x4ec0, 0x0e7e, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0, - 0x11ca, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0e7f, - 0x0078, 0x11d1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, - 0x0e7f, 0x2011, 0x0002, 0x2069, 0x4fc0, 0x2009, 0x0002, 0x20a9, - 0x0100, 0x683f, 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff, - 0x00c0, 0x11e8, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x11ec, - 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x00f0, 0x11d9, - 0x8109, 0x00c0, 0x11d7, 0x8211, 0x0040, 0x11fa, 0x2069, 0x6fc0, - 0x0078, 0x11d5, 0x1078, 0x2611, 0x1078, 0x441d, 0x1078, 0x1df2, - 0x1078, 0x4957, 0x2091, 0x2100, 0x2079, 0x4a00, 0x7810, 0xd0ec, - 0x0040, 0x120e, 0x2071, 0x0020, 0x0078, 0x1210, 0x2071, 0x0050, - 0x2091, 0x2200, 0x2079, 0x4a00, 0x2071, 0x0020, 0x2091, 0x2300, - 0x2079, 0x4a00, 0x7810, 0xd0ec, 0x0040, 0x1222, 0x2079, 0x0100, - 0x0078, 0x1224, 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x2400, - 0x2079, 0x0100, 0x2071, 0x4a80, 0x2091, 0x2000, 0x2079, 0x4a00, - 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, 0x2071, 0x0010, - 0x70c3, 0x0000, 0x0090, 0x1243, 0x70c0, 0xa086, 0x0002, 0x00c0, - 0x1243, 0x1078, 0x159d, 0x2039, 0x0000, 0x7810, 0xd0ec, 0x00c0, - 0x12c5, 0x1078, 0x1472, 0x78ac, 0xa005, 0x00c0, 0x1261, 0x0068, - 0x1257, 0x786c, 0xa065, 0x0040, 0x1257, 0x1078, 0x2368, 0x1078, - 0x209f, 0x0068, 0x126e, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078, - 0x2368, 0x0068, 0x126e, 0x2009, 0x4a47, 0x2011, 0x4a87, 0x2104, - 0x220c, 0xa105, 0x0040, 0x126e, 0x1078, 0x1f1e, 0x2071, 0x4a40, - 0x70a4, 0xa005, 0x0040, 0x1293, 0x7450, 0xa485, 0x0000, 0x0040, - 0x1293, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, - 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0068, - 0x1293, 0x2079, 0x4a00, 0x786c, 0xa065, 0x0040, 0x1293, 0x2071, - 0x0010, 0x1078, 0x2368, 0x00e0, 0x129b, 0x2079, 0x4a00, 0x2071, - 0x0010, 0x1078, 0x4765, 0x2071, 0x4a80, 0x70a4, 0xa005, 0x0040, - 0x12b3, 0x7050, 0xa025, 0x0040, 0x12b3, 0x2079, 0x0100, 0x2091, - 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, - 0x8000, 0x2091, 0x303d, 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, - 0x12bf, 0x786c, 0xa065, 0x0040, 0x12bf, 0x1078, 0x2368, 0x00e0, - 0x1249, 0x1078, 0x4765, 0x0078, 0x1249, 0x1078, 0x1472, 0x78ac, - 0xa005, 0x00c0, 0x12dd, 0x0068, 0x12d3, 0x786c, 0xa065, 0x0040, - 0x12d3, 0x1078, 0x2368, 0x1078, 0x209f, 0x0068, 0x12e7, 0x786c, - 0xa065, 0x0040, 0x12dd, 0x1078, 0x2368, 0x0068, 0x12e7, 0x2009, - 0x4a47, 0x2104, 0xa005, 0x0040, 0x12e7, 0x1078, 0x1f1e, 0x2071, - 0x4a40, 0x70a4, 0xa005, 0x0040, 0x1302, 0x7450, 0xa485, 0x0000, - 0x0040, 0x1302, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, - 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, - 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, 0x130c, 0x786c, 0xa065, - 0x0040, 0x130c, 0x1078, 0x2368, 0x00e0, 0x12c5, 0x1078, 0x4765, - 0x0078, 0x12c5, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341, - 0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341, - 0x1341, 0x1341, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341, - 0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341, - 0x1341, 0x1341, 0x0078, 0x1332, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f, - 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b, - 0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, - 0x8001, 0x007c, 0x138a, 0x138a, 0x138c, 0x138c, 0x1399, 0x1399, - 0x1399, 0x1399, 0x13a4, 0x13a4, 0x138c, 0x138c, 0x1399, 0x1399, - 0x1399, 0x1399, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, - 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, - 0x13a5, 0x13a5, 0x0078, 0x138a, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c7, 0x127f, 0x107f, - 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e, 0x127e, 0x0d7e, - 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069, 0x4a40, 0x2079, - 0x4a00, 0x1078, 0x49ae, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, - 0x107f, 0x007c, 0x3c00, 0xa084, 0x0007, 0x0079, 0x13bf, 0x13d0, - 0x13d0, 0x13d2, 0x13d2, 0x13d7, 0x13d7, 0x13dc, 0x13dc, 0x3c00, - 0xa084, 0x0003, 0x0079, 0x13cc, 0x13d0, 0x13d0, 0x13e5, 0x13e5, - 0x1078, 0x28ec, 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, - 0x2100, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, 0x44b7, - 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, - 0x44b7, 0x007c, 0x140a, 0x140a, 0x140c, 0x140c, 0x1419, 0x1419, - 0x1419, 0x1419, 0x1424, 0x1424, 0x1431, 0x1431, 0x1419, 0x1419, - 0x1419, 0x1419, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, - 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, - 0x1442, 0x1442, 0x0078, 0x140a, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f, - 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, - 0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, - 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b, - 0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, - 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, - 0x2079, 0x4a00, 0x2071, 0x0200, 0x2069, 0x4a40, 0x3d00, 0xd08c, - 0x00c0, 0x1456, 0x2069, 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, - 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007f, 0x007c, 0x7008, - 0x800b, 0x00c8, 0x146d, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, - 0x146e, 0xd09c, 0x0040, 0x146d, 0x087a, 0x097a, 0x70c3, 0x4002, - 0x0078, 0x15a0, 0x0068, 0x14f7, 0x2061, 0x0000, 0x6018, 0xd084, - 0x00c0, 0x14f7, 0x7828, 0xa005, 0x00c0, 0x1482, 0x0010, 0x14f8, - 0x0078, 0x14f7, 0x7910, 0xd1f4, 0x0040, 0x148a, 0x2001, 0x4007, - 0x0078, 0x159f, 0x7914, 0xd1ec, 0x0040, 0x14a5, 0xd0fc, 0x0040, - 0x149b, 0x007e, 0x1078, 0x1d82, 0x007f, 0x0040, 0x14a5, 0x2001, - 0x4007, 0x0078, 0x159f, 0x007e, 0x1078, 0x1d72, 0x007f, 0x0040, - 0x14a5, 0x2001, 0x4007, 0x0078, 0x159f, 0x7910, 0xd0fc, 0x00c0, - 0x14af, 0x2061, 0x4a40, 0xc19c, 0xc7fc, 0x0078, 0x14b3, 0x2061, - 0x4a80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x14f7, 0x7912, - 0x6083, 0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14c4, - 0x0c7e, 0x1078, 0x1b13, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065, - 0x0040, 0x14dd, 0x0c7e, 0x609c, 0x1078, 0x1e5d, 0x0c7f, 0x609f, - 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, 0x0103, 0x1078, - 0x1d92, 0x00c0, 0x14f1, 0x1078, 0x1de4, 0x7810, 0xd09c, 0x00c0, - 0x14e5, 0x2061, 0x4a40, 0x0078, 0x14e9, 0x2061, 0x4a80, 0xc09c, - 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc, 0x0040, 0x14f5, 0xc0dc, - 0x60d6, 0x2001, 0x4005, 0x0078, 0x159f, 0x0078, 0x159d, 0x007c, - 0x7810, 0xd0f4, 0x0040, 0x1500, 0x2001, 0x4007, 0x0078, 0x159f, - 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa08a, - 0x0040, 0x00c8, 0x150d, 0x0079, 0x1514, 0x2100, 0xa08a, 0x0040, - 0x00c8, 0x15ab, 0x0079, 0x1554, 0x159d, 0x15f3, 0x15bc, 0x162b, - 0x1663, 0x1663, 0x15b3, 0x1c57, 0x166e, 0x15ab, 0x15c0, 0x15c2, - 0x15c4, 0x15c6, 0x1c5c, 0x15ab, 0x167c, 0x16d4, 0x1b35, 0x1c51, - 0x15c8, 0x19a7, 0x19e9, 0x1a1f, 0x1a6b, 0x1962, 0x196f, 0x1983, - 0x1996, 0x17a4, 0x1cdc, 0x1706, 0x1713, 0x171f, 0x172b, 0x1741, - 0x174d, 0x1750, 0x175c, 0x1768, 0x1770, 0x178c, 0x1798, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x17b1, 0x17c3, 0x17df, 0x1815, 0x183d, - 0x184d, 0x1850, 0x1881, 0x18b2, 0x18c4, 0x1931, 0x1941, 0x1d32, - 0x15ab, 0x15ab, 0x15ab, 0x1951, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x1c81, 0x1c87, 0x15ab, 0x15ab, 0x15ab, 0x1c8b, 0x1cd8, - 0x15ab, 0x15ab, 0x1ce8, 0x1cf7, 0x15ed, 0x165d, 0x1676, 0x16ce, - 0x1b2f, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x1d39, 0x1c73, 0x1c7d, - 0x15ab, 0x15ab, 0x1d02, 0x1d1b, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, - 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x72ca, 0x71c6, 0x2001, 0x4006, - 0x0078, 0x159f, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, - 0x0068, 0x15a0, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, - 0x2091, 0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x15a0, 0x70c3, - 0x4006, 0x0078, 0x15a0, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, - 0x0005, 0x53a3, 0x0078, 0x159d, 0x70c4, 0x70c3, 0x0004, 0x007a, - 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, - 0x2091, 0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, - 0x70cf, 0x2020, 0x70d3, 0x0008, 0x2001, 0x0009, 0x70d6, 0x2079, - 0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, - 0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, - 0x5000, 0x2091, 0x4080, 0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, - 0x74de, 0x0078, 0x15f6, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, - 0x73cc, 0x70c4, 0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, - 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, - 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x1610, 0x2120, 0xa006, - 0x2008, 0x8403, 0x7012, 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, - 0xd0fc, 0x0040, 0x1617, 0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, - 0x1625, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x24a8, 0x53a5, 0x0078, - 0x1607, 0x0078, 0x159d, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, - 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, - 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x7007, - 0x0006, 0x81ff, 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x164a, - 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, - 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1651, 0xa084, 0x01e0, 0x0040, - 0x163f, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x75d8, 0x74dc, 0x75da, - 0x74de, 0x0078, 0x162e, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, - 0x00c0, 0x166b, 0x200a, 0x72ca, 0x0078, 0x159c, 0x70c7, 0x0008, - 0x70cb, 0x0009, 0x70cf, 0x0000, 0x0078, 0x159d, 0x75d8, 0x76dc, - 0x75da, 0x76de, 0x0078, 0x167f, 0x2029, 0x0000, 0x2530, 0x70c4, - 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, - 0x0040, 0x16c9, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040, 0x1697, - 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7b7e, - 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040, 0x16af, - 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118, 0xa291, - 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16b9, 0x8407, - 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, - 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040, 0x16c3, - 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae, 0x0078, - 0x16cc, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x159d, 0x75d8, 0x76dc, - 0x75da, 0x76de, 0x0078, 0x16d7, 0x2029, 0x0000, 0x2530, 0x70c4, - 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, - 0x0040, 0x1701, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x16ef, - 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7a9a, - 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x16fa, 0x7a10, - 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, - 0x1704, 0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x159d, 0x2009, 0x0000, - 0x786c, 0xa065, 0x0040, 0x1710, 0x8108, 0x6000, 0x0078, 0x1709, - 0x7ac4, 0x0078, 0x159b, 0x2009, 0x4a48, 0x210c, 0x7810, 0xd0ec, - 0x00c0, 0x159c, 0x2011, 0x4a88, 0x2214, 0x0078, 0x159b, 0x2009, - 0x4a49, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a89, - 0x2214, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6128, 0x622c, 0x8214, - 0x8214, 0x8214, 0x7810, 0xd0ec, 0x00c0, 0x173f, 0x2061, 0x4a80, - 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, - 0x159b, 0x2009, 0x4a4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, - 0x2011, 0x4a8c, 0x2214, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c, - 0x2009, 0x4a4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, - 0x4a8d, 0x2214, 0x0078, 0x159b, 0x2009, 0x4a4e, 0x210c, 0x7810, - 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a8e, 0x2214, 0x0078, 0x159b, - 0x7920, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x7a24, 0x0078, 0x159b, - 0x71c4, 0xd1fc, 0x00c0, 0x1778, 0x2011, 0x4ec0, 0x0078, 0x177a, - 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xa268, 0x6a00, 0x6804, 0xd09c, 0x0040, 0x1789, 0x6b08, 0x0078, - 0x178a, 0x6b0c, 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, - 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x159a, - 0x2061, 0x4a40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, - 0x4a80, 0x6218, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, - 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, - 0x159a, 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, - 0x1595, 0x1078, 0x2729, 0xa384, 0x4000, 0x0040, 0x17c1, 0xa295, - 0x0020, 0x0078, 0x159a, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, - 0x00c8, 0x1595, 0xd1bc, 0x00c0, 0x17d2, 0x2011, 0x4a48, 0x2204, - 0x0078, 0x17d6, 0x2011, 0x4a88, 0x2204, 0xc0bd, 0x007e, 0x2100, - 0xc0bc, 0x2012, 0x1078, 0x2686, 0x017f, 0x0078, 0x159c, 0x71c4, - 0x2021, 0x4a49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x17ee, - 0x71c8, 0x2021, 0x4a89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x180d, - 0x20a9, 0x0008, 0x2204, 0xa106, 0x0040, 0x17fd, 0x8210, 0x00f0, - 0x17f2, 0x71c4, 0x72c8, 0x0078, 0x1594, 0xa292, 0x180d, 0x027e, - 0x2122, 0x017f, 0x1078, 0x26a7, 0x7810, 0xd0ec, 0x00c0, 0x180b, - 0xd3fc, 0x0040, 0x17e8, 0x0078, 0x159d, 0x03e8, 0x00fa, 0x01f4, - 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4a40, 0x6128, - 0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, - 0x8003, 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x183b, 0x027e, - 0x017e, 0x2061, 0x4a80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, - 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, - 0x72de, 0x017f, 0x027f, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6130, - 0x70c4, 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, 0x4a80, - 0x6230, 0x70c8, 0x6032, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c, - 0x71c4, 0xa184, 0xffcf, 0x0040, 0x185c, 0x7810, 0xd0ec, 0x00c0, - 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4d, 0x2204, 0x2112, - 0x007e, 0x2019, 0x0000, 0x1078, 0x270e, 0x7810, 0xd0ec, 0x0040, - 0x186c, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa184, 0xffcf, 0x0040, - 0x1875, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8d, 0x2204, - 0x2112, 0x007e, 0xc3fd, 0x1078, 0x270e, 0x027f, 0x017f, 0x0078, - 0x159b, 0x71c4, 0xa182, 0x0010, 0x0048, 0x188d, 0x7810, 0xd0ec, - 0x00c0, 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4e, 0x2204, - 0x007e, 0x2112, 0x2019, 0x0000, 0x1078, 0x26ec, 0x7810, 0xd0ec, - 0x0040, 0x189d, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa182, 0x0010, - 0x0048, 0x18a6, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8e, - 0x2204, 0x007e, 0x2112, 0xc3fd, 0x1078, 0x26ec, 0x027f, 0x017f, - 0x0078, 0x159b, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x1594, - 0xa284, 0xfffd, 0x00c0, 0x1594, 0x2100, 0x7920, 0x7822, 0x2200, - 0x7a24, 0x7826, 0x0078, 0x159b, 0x71c4, 0xd1fc, 0x00c0, 0x18cc, - 0x2011, 0x4ec0, 0x0078, 0x18ce, 0x2011, 0x4f40, 0x8107, 0xa084, - 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, - 0xa284, 0x0080, 0x0040, 0x18e2, 0x6c14, 0x84ff, 0x00c0, 0x18e2, - 0x6817, 0x0040, 0xa284, 0x0040, 0x0040, 0x18ec, 0x6c10, 0x84ff, - 0x00c0, 0x18ec, 0x6813, 0x0001, 0x6800, 0x007e, 0xa226, 0x0040, - 0x1909, 0x6a02, 0xd4ec, 0x0040, 0x18f6, 0xc3a5, 0xd4e4, 0x0040, - 0x18fa, 0xc39d, 0xd4f4, 0x0040, 0x1909, 0x810f, 0xd2f4, 0x0040, - 0x1905, 0x1078, 0x276b, 0x0078, 0x1909, 0x1078, 0x2749, 0x0078, - 0x1909, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1929, 0xa2a4, 0x00ff, - 0x7814, 0xd0e4, 0x00c0, 0x191c, 0xa482, 0x0028, 0x0048, 0x1926, - 0x0040, 0x1926, 0x0078, 0x1920, 0xa482, 0x0043, 0x0048, 0x1926, - 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x1596, 0x6a0a, 0xa39d, - 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, - 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a14, 0x6b1c, - 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, - 0x159a, 0x70c4, 0x2061, 0x4a40, 0x6118, 0x601a, 0x7810, 0xd0ec, - 0x00c0, 0x159c, 0x70c8, 0x2061, 0x4a80, 0x6218, 0x601a, 0x0078, - 0x159b, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x1595, - 0x1078, 0x278d, 0xa384, 0x4000, 0x0040, 0x1960, 0xa295, 0x0020, - 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, - 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, - 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, - 0x6804, 0xa005, 0x0040, 0x197e, 0x1078, 0x25de, 0x2091, 0x8001, - 0x2708, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, - 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1991, 0x1078, - 0x25de, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, 0x2041, - 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, - 0x1e1d, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x159b, 0x77c4, - 0x7814, 0xd0e4, 0x00c0, 0x19bb, 0xd7fc, 0x0040, 0x19b5, 0x1078, - 0x1d82, 0x0040, 0x19bb, 0x0078, 0x159f, 0x1078, 0x1d72, 0x0040, - 0x19bb, 0x0078, 0x159f, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, - 0x1078, 0x1e9a, 0x00c0, 0x19e5, 0x6818, 0xa005, 0x0040, 0x19df, - 0x2708, 0x077e, 0x1078, 0x27bd, 0x077f, 0x00c0, 0x19df, 0x2001, - 0x0015, 0xd7fc, 0x00c0, 0x19d8, 0x2061, 0x4a40, 0x0078, 0x19db, - 0xc0fd, 0x2061, 0x4a80, 0x782a, 0x2091, 0x8001, 0x007c, 0x2091, - 0x8001, 0x2001, 0x4005, 0x0078, 0x159f, 0x2091, 0x8001, 0x0078, - 0x159d, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fd, 0xd7fc, 0x0040, - 0x19f7, 0x1078, 0x1d82, 0x0040, 0x19fd, 0x0078, 0x159f, 0x1078, - 0x1d72, 0x0040, 0x19fd, 0x0078, 0x159f, 0x77c6, 0x2041, 0x0021, - 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x1e1d, - 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a11, 0x2061, 0x4a40, 0x0078, - 0x1a14, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0003, 0x6776, 0x6083, - 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, 0x007c, 0x77c8, - 0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a36, 0xd7fc, - 0x0040, 0x1a30, 0x1078, 0x1d82, 0x0040, 0x1a36, 0x0078, 0x159f, - 0x1078, 0x1d72, 0x0040, 0x1a36, 0x0078, 0x159f, 0xa7bc, 0xff00, - 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a43, 0x2061, - 0x4a40, 0x0078, 0x1a46, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0002, - 0x6776, 0x6083, 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, - 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, - 0x70c8, 0xa005, 0x0040, 0x1a5f, 0x60d4, 0xc0fd, 0x60d6, 0x1078, - 0x1e1d, 0x70c8, 0x683e, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a5f, - 0x2091, 0x8001, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x1a7f, 0x72c8, - 0xd284, 0x0040, 0x1a79, 0x1078, 0x1d82, 0x0040, 0x1a7f, 0x0078, - 0x159f, 0x1078, 0x1d72, 0x0040, 0x1a7f, 0x0078, 0x159f, 0x72c8, - 0x72ca, 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1aaa, 0x2039, 0x0000, - 0xd284, 0x0040, 0x1a8c, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, - 0x2051, 0x0008, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6808, 0xc0d4, - 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x1a92, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, - 0x00c0, 0x1a92, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1abc, - 0x7810, 0xd0ec, 0x0040, 0x1ab8, 0x2069, 0x0100, 0x0078, 0x1abe, - 0x2069, 0x0200, 0x0078, 0x1abe, 0x2069, 0x0100, 0x6830, 0xd0b4, - 0x0040, 0x1ada, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, - 0x0040, 0x1acc, 0x00f0, 0x1ac6, 0x684b, 0x0009, 0x20a9, 0x0014, - 0x6848, 0xd084, 0x0040, 0x1ad6, 0x00f0, 0x1ad0, 0x20a9, 0x00fa, - 0x00f0, 0x1ad8, 0x2079, 0x4a00, 0x2009, 0x0018, 0x72c8, 0xd284, - 0x00c0, 0x1ae6, 0x2061, 0x4a40, 0x0078, 0x1ae9, 0x2061, 0x4a80, - 0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, - 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, 0x0040, 0x1b03, 0xc0b4, - 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, - 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, - 0xc08d, 0x78ae, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0047, - 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b1a, 0x2069, 0x4a40, - 0x0078, 0x1b1c, 0x2069, 0x4a80, 0x78ac, 0xc08c, 0x78ae, 0xd084, - 0x00c0, 0x1b26, 0x0d7e, 0x1078, 0x1efa, 0x0d7f, 0x71c4, 0x71c6, - 0x6916, 0x81ff, 0x00c0, 0x1b2e, 0x68a7, 0x0001, 0x007c, 0x75d8, - 0x74dc, 0x75da, 0x74de, 0x0078, 0x1b38, 0x2029, 0x0000, 0x2520, - 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4a00, - 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1ddb, 0x0040, 0x1c3b, - 0x20a9, 0x0005, 0x20a1, 0x4a14, 0x2091, 0x8000, 0x41a1, 0x2091, - 0x8001, 0x2009, 0x0040, 0x1078, 0x1fcf, 0x0040, 0x1b5b, 0x1078, - 0x1de4, 0x0078, 0x1c3b, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, - 0x00c0, 0x1b66, 0x007e, 0x1078, 0x234b, 0x007f, 0xa084, 0xff00, - 0x8007, 0x8009, 0x0040, 0x1bda, 0x0c7e, 0x2c68, 0x1078, 0x1ddb, - 0x0040, 0x1bac, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1b6d, 0x609f, - 0x0000, 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, - 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, - 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1bd9, - 0x2009, 0x0040, 0x1078, 0x1fcf, 0x00c0, 0x1bc3, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x0002, 0x00c0, 0x1bac, 0x6004, 0xa084, 0x00ff, - 0xa086, 0x000a, 0x00c0, 0x1ba8, 0x017e, 0x1078, 0x2347, 0x017f, - 0x2d00, 0x6002, 0x0078, 0x1b7b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, - 0x1e5d, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, - 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086, 0x1078, 0x1d92, 0x1078, - 0x1de4, 0x0078, 0x1c3b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e5d, - 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, - 0x0103, 0x601b, 0x0003, 0x1078, 0x1d92, 0x1078, 0x1de4, 0x0078, - 0x1c3b, 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1bff, 0x6114, 0xd1fc, - 0x0040, 0x1be8, 0x1078, 0x1d82, 0x0040, 0x1bff, 0x0078, 0x1bec, - 0x1078, 0x1d72, 0x0040, 0x1bff, 0x2029, 0x0000, 0x2520, 0x2009, - 0x0018, 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, - 0x1d92, 0x1078, 0x1de4, 0x2001, 0x4007, 0x0078, 0x159f, 0x74c4, - 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, - 0xd0fc, 0x00c0, 0x1c0f, 0x2071, 0x4a40, 0x0078, 0x1c12, 0x2071, - 0x4a80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xa18c, 0xf77f, - 0x71d6, 0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, - 0x707e, 0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1c2a, - 0x1078, 0x43c1, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, - 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x1078, 0x25de, - 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x15a0, 0x20a9, - 0x0005, 0x2099, 0x4a14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, - 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, - 0x007c, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0078, 0x159d, 0x71c4, - 0x71c6, 0x2168, 0x0078, 0x1c5e, 0x2069, 0x1000, 0x690c, 0xa016, - 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1c60, 0xa285, 0x0000, - 0x00c0, 0x1c6e, 0x70c3, 0x4000, 0x0078, 0x1c70, 0x70c3, 0x4003, - 0x70ca, 0x0078, 0x15a0, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, - 0x00c8, 0x1595, 0x7966, 0x0078, 0x159d, 0x7964, 0x71c6, 0x0078, - 0x159d, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0078, 0x159d, 0x7900, - 0x71c6, 0x0078, 0x159d, 0x70c4, 0xd08c, 0x0040, 0x1c94, 0x7a10, - 0xd2ec, 0x00c0, 0x1c94, 0xc08c, 0x2011, 0x0000, 0xa08c, 0x000d, - 0x0040, 0x1ca8, 0x810c, 0x0048, 0x1ca4, 0x8210, 0x810c, 0x810c, - 0x0048, 0x1ca4, 0x8210, 0x810c, 0x81ff, 0x00c0, 0x1596, 0x8210, - 0x7a0e, 0xd28c, 0x0040, 0x1cd4, 0x7910, 0xc1cd, 0x7912, 0x2009, - 0x0021, 0x2019, 0x0003, 0xd284, 0x0040, 0x1cce, 0x8108, 0x2019, - 0x0041, 0x2011, 0x924e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, - 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, - 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9253, - 0x2112, 0x2011, 0x9273, 0x2312, 0x7904, 0x7806, 0x0078, 0x159c, - 0x7804, 0x70c6, 0x0078, 0x159d, 0x2091, 0x8000, 0x2019, 0x0000, - 0x2011, 0x0000, 0x2009, 0x0000, 0x2091, 0x8001, 0x0078, 0x159a, - 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6830, 0xa084, 0xff00, - 0x8007, 0x2010, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, - 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a34, 0x2091, 0x8001, 0x2708, - 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, 0x0008, - 0x72c8, 0x8217, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c30, 0x6a32, - 0x2091, 0x8001, 0x8738, 0x00f0, 0x1d0a, 0x077f, 0x2708, 0x8427, - 0x2410, 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, - 0x0008, 0x72c8, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c34, 0x6a36, - 0x2091, 0x8001, 0x8738, 0x00f0, 0x1d22, 0x077f, 0x2708, 0x2410, - 0x0078, 0x159b, 0x2011, 0x4a3c, 0x220c, 0x70c4, 0x2012, 0x0078, - 0x159c, 0x71c4, 0xd1fc, 0x00c0, 0x1d41, 0x2011, 0x4ec0, 0x0078, - 0x1d43, 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d52, 0x2011, 0x0001, - 0x0078, 0x1d54, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x159a, 0x017e, - 0x7814, 0xd0f4, 0x0040, 0x1d64, 0x2001, 0x4007, 0x70db, 0x0000, - 0xa18d, 0x0001, 0x0078, 0x1d70, 0xd0fc, 0x0040, 0x1d6f, 0x2001, - 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d70, 0xa006, - 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d7f, 0x2001, - 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d80, 0xa006, - 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040, 0x1d8f, 0x2001, - 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d90, 0xa006, - 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0040, - 0x1d9b, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c, 0x81a9, - 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2, 0x53a6, - 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1db8, 0x810f, - 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x1dbb, - 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, - 0x7d10, 0xd5c4, 0x0040, 0x1dc8, 0x7b84, 0xa319, 0x7c80, 0xa421, - 0x7008, 0xd0fc, 0x0040, 0x1dc8, 0x7003, 0x0001, 0x7007, 0x0006, - 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dd8, 0x7322, 0x7426, - 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1de3, 0x2c04, - 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4a00, 0x7848, - 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1def, 0x1078, 0x28ec, 0x784a, - 0x0f7f, 0x007c, 0x2011, 0x9400, 0x7a4a, 0x7bc4, 0x8319, 0x0040, - 0x1dff, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1df6, 0x2013, - 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e0b, 0x2011, - 0x4fc0, 0x0078, 0x1e0d, 0x2011, 0x6fc0, 0xa784, 0x0f00, 0x800b, - 0xa784, 0x001f, 0x0040, 0x1e18, 0x8003, 0x8003, 0x8003, 0x8003, - 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e02, 0x2900, - 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, - 0xd7fc, 0x00c0, 0x1e2f, 0x2009, 0x4a53, 0x0078, 0x1e31, 0x2009, - 0x4a93, 0x210c, 0x6804, 0xa005, 0x0040, 0x1e41, 0xa116, 0x00c0, - 0x1e41, 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, - 0x1e44, 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e59, - 0x6000, 0x6806, 0x1078, 0x1e6f, 0x1078, 0x201b, 0x6810, 0x7908, - 0x8109, 0x790a, 0x8001, 0x6812, 0x00c0, 0x1e44, 0x7910, 0xc1a5, - 0x7912, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1e6e, - 0x2008, 0x609c, 0xa005, 0x0040, 0x1e6b, 0x2062, 0x609f, 0x0000, - 0xa065, 0x0078, 0x1e61, 0x7848, 0x794a, 0x2062, 0x007c, 0x6007, - 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, - 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c, - 0x0e7e, 0xd7fc, 0x00c0, 0x1e8a, 0x2071, 0x4a40, 0x2031, 0x4ac0, - 0x0078, 0x1e8e, 0x2071, 0x4a80, 0x2031, 0x4cc0, 0x7050, 0xa08c, - 0x0200, 0x00c0, 0x1e98, 0xa608, 0x2d0a, 0x8000, 0x7052, 0xa006, - 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0, 0x1ea2, 0x2079, 0x4a40, - 0x0078, 0x1ea4, 0x2079, 0x4a80, 0x1078, 0x1e02, 0x2091, 0x8000, - 0x6804, 0x780a, 0xa065, 0x0040, 0x1ef8, 0x0078, 0x1eb6, 0x2c00, - 0x780a, 0x2060, 0x6000, 0xa065, 0x0040, 0x1ef8, 0x6010, 0xa306, - 0x00c0, 0x1eaf, 0x600c, 0xa206, 0x00c0, 0x1eaf, 0x2c28, 0x784c, - 0xac06, 0x00c0, 0x1ec5, 0x0078, 0x1ef5, 0x6804, 0xac06, 0x00c0, - 0x1ed3, 0x6000, 0x2060, 0x6806, 0xa005, 0x00c0, 0x1ed3, 0x6803, - 0x0000, 0x0078, 0x1edd, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486, - 0x0000, 0x00c0, 0x1edd, 0x2c00, 0x6802, 0x2560, 0x0f7f, 0x1078, - 0x1e6f, 0x0f7e, 0x601b, 0x0005, 0x6023, 0x0020, 0x0f7f, 0x1078, - 0x201b, 0x0f7e, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812, - 0x00c0, 0x1ef5, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, - 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0040, - 0x1f02, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, - 0x2091, 0x8000, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x1f0a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, - 0x00c0, 0x1f0a, 0x2091, 0x8001, 0x077f, 0x007c, 0x2061, 0x0000, - 0x6018, 0xd084, 0x00c0, 0x1f3e, 0x7810, 0xd08c, 0x0040, 0x1f2f, - 0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4a40, 0x0078, 0x1f34, 0xc08d, - 0x7812, 0x2069, 0x4a80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, - 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x1f3f, 0x007c, 0xa08c, - 0xfff0, 0x0040, 0x1f45, 0x1078, 0x28ec, 0x0079, 0x1f47, 0x1f57, - 0x1f5a, 0x1f60, 0x1f64, 0x1f58, 0x1f68, 0x1f58, 0x1f58, 0x1f58, - 0x1f6e, 0x1f9f, 0x1fa3, 0x1fa9, 0x1f58, 0x1f58, 0x1f58, 0x007c, - 0x1078, 0x28ec, 0x1078, 0x1efa, 0x2001, 0x8001, 0x0078, 0x1fbe, - 0x2001, 0x8003, 0x0078, 0x1fbe, 0x2001, 0x8004, 0x0078, 0x1fbe, - 0x1078, 0x1efa, 0x2001, 0x8006, 0x0078, 0x1fbe, 0x2091, 0x8000, - 0x077e, 0xd7fc, 0x00c0, 0x1f7a, 0x2069, 0x4a40, 0x2039, 0x0009, - 0x0078, 0x1f7e, 0x2069, 0x4a80, 0x2039, 0x0009, 0x6800, 0xa086, - 0x0000, 0x0040, 0x1f88, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, - 0x6874, 0x077f, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, - 0x2051, 0x0010, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x1f92, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1fbe, 0x2001, - 0x800c, 0x0078, 0x1fbe, 0x1078, 0x1efa, 0x2001, 0x800d, 0x0078, - 0x1fbe, 0x7814, 0xd0e4, 0x00c0, 0x1fbc, 0xd0ec, 0x0040, 0x1fb6, - 0xd7fc, 0x0040, 0x1fb6, 0x78ec, 0x0078, 0x1fb7, 0x78e4, 0x70c6, - 0x2001, 0x800e, 0x0078, 0x1fbe, 0x0078, 0x1f58, 0x70c2, 0xd7fc, - 0x00c0, 0x1fc6, 0x70db, 0x0000, 0x0078, 0x1fc8, 0x70db, 0x0001, - 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0xac80, - 0x0001, 0x81ff, 0x0040, 0x1ffa, 0x2099, 0x0030, 0x20a0, 0x700c, - 0xa084, 0x03ff, 0x0040, 0x1fdc, 0x7018, 0x007e, 0x701c, 0x007e, - 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a, 0x731e, - 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, - 0x00c8, 0x1fee, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1ffa, - 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f, 0x7026, - 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c, 0x2011, - 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00, 0x6807, - 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, - 0x00c0, 0x200b, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, - 0x7868, 0xa005, 0x796a, 0x0040, 0x2028, 0x2c02, 0x0078, 0x2029, - 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08, - 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x203a, 0x2d02, - 0x0078, 0x203b, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x2c04, - 0x786e, 0xa005, 0x00c0, 0x2045, 0x786a, 0x2091, 0x8001, 0x609c, - 0xa005, 0x0040, 0x205e, 0x0c7e, 0x2060, 0x2008, 0x609c, 0xa005, - 0x0040, 0x205a, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005, - 0x00c0, 0x2052, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848, 0x2062, - 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x2068, 0x1078, 0x28ec, - 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, - 0x00c8, 0x2073, 0xa200, 0x00f0, 0x206e, 0x8086, 0x818e, 0x007c, - 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x2099, 0xa11a, 0x00c8, - 0x2099, 0x8213, 0x818d, 0x0048, 0x208c, 0xa11a, 0x00c8, 0x208d, - 0x00f0, 0x2081, 0x0078, 0x2091, 0xa11a, 0x2308, 0x8210, 0x00f0, - 0x2081, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, - 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x2095, 0x7d74, - 0x70d0, 0xa506, 0x0040, 0x2185, 0x7810, 0x2050, 0x7800, 0xd08c, - 0x0040, 0x20c1, 0xdaec, 0x0040, 0x20c1, 0x0e7e, 0x2091, 0x8000, - 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20be, 0x7008, 0x0e7f, - 0xa086, 0x0008, 0x0040, 0x20c1, 0x0078, 0x2185, 0x0e7f, 0x0078, - 0x2185, 0x1078, 0x1ddb, 0x0040, 0x2185, 0xa046, 0x7970, 0x2500, - 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d0, 0x0078, 0x20d7, - 0x72d0, 0xa206, 0x0040, 0x20d7, 0x8840, 0x2009, 0x0080, 0x0c7e, - 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, 0xac80, - 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x20e9, 0x1078, - 0x1ddb, 0x7008, 0xd0fc, 0x0040, 0x20e9, 0x7007, 0x0002, 0x2091, - 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2120, 0x53a5, 0x8cff, 0x00c0, - 0x20fe, 0x88ff, 0x0040, 0x216f, 0x0078, 0x2108, 0x2c00, 0x788e, - 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078, 0x216f, - 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2110, 0x7420, 0x7524, - 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, - 0x721a, 0x731e, 0xdac4, 0x0040, 0x2120, 0x7422, 0x7526, 0xa006, - 0x7007, 0x0004, 0x0040, 0x216f, 0x8cff, 0x0040, 0x2129, 0x1078, - 0x1de4, 0x0c7f, 0x1078, 0x1de4, 0xa046, 0x7888, 0x8000, 0x788a, - 0xa086, 0x0002, 0x0040, 0x214f, 0x7a7c, 0x7b78, 0xdac4, 0x0040, - 0x213b, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, - 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, - 0xdac4, 0x0040, 0x2185, 0x7422, 0x7526, 0x0078, 0x2185, 0x6014, - 0xd0fc, 0x00c0, 0x2157, 0x2069, 0x4a40, 0x0078, 0x2159, 0x2069, - 0x4a80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040, 0x2165, - 0xa046, 0x788c, 0x2060, 0x0078, 0x214f, 0x788b, 0x0000, 0x78ac, - 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x2185, 0x0c7f, - 0x788b, 0x0000, 0x1078, 0x2319, 0x6004, 0xa084, 0x000f, 0x1078, - 0x2186, 0x88ff, 0x0040, 0x2183, 0x788c, 0x2060, 0x6004, 0xa084, - 0x000f, 0x1078, 0x2186, 0x0078, 0x209f, 0x007c, 0x0079, 0x2188, - 0x2198, 0x21b6, 0x21d4, 0x2198, 0x21e5, 0x21a9, 0x2198, 0x2198, - 0x2198, 0x21b4, 0x21d2, 0x2198, 0x2198, 0x2198, 0x2198, 0x2198, - 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, - 0x1078, 0x2228, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2303, - 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21af, 0x0078, 0x2198, 0x601c, - 0xc0bd, 0x601e, 0x0078, 0x21bc, 0x1078, 0x234b, 0x78bc, 0xd0c4, - 0x0040, 0x21bc, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6004, 0x8007, - 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21cf, 0x1078, 0x2228, - 0x0040, 0x21cf, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x21d1, 0x0078, - 0x2247, 0x007c, 0x1078, 0x2347, 0x78bc, 0xa08c, 0x0e00, 0x00c0, - 0x21dc, 0xd0c4, 0x00c0, 0x21de, 0x0078, 0x2198, 0x1078, 0x2228, - 0x00c0, 0x21e4, 0x0078, 0x2247, 0x007c, 0x78bc, 0xd0c4, 0x0040, - 0x21eb, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, - 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x220b, 0xa7bc, - 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x220b, 0xa7bc, - 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, - 0x220b, 0x0078, 0x2225, 0x1078, 0x1e02, 0x2d00, 0x2091, 0x8000, - 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, - 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x220e, 0x8211, 0x0040, - 0x2225, 0x20a9, 0x0100, 0x0078, 0x220e, 0x1078, 0x1de4, 0x007c, - 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0, 0x2233, - 0x78ba, 0x0078, 0x223b, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, - 0x00c0, 0x223b, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0, 0x2246, - 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c, 0x0e7e, - 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, - 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040, 0x225a, - 0x1078, 0x43c1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, - 0x4a80, 0xd7fc, 0x00c0, 0x2266, 0x2071, 0x4a40, 0xa784, 0x0f00, - 0x800b, 0xa784, 0x001f, 0x0040, 0x2271, 0x8003, 0x8003, 0x8003, - 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084, 0x000f, - 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091, 0x8000, - 0x7810, 0xd0f4, 0x00c0, 0x228b, 0x6e08, 0xd684, 0x0040, 0x22a1, - 0xd9fc, 0x00c0, 0x22a1, 0x2091, 0x8001, 0x1078, 0x1e6f, 0x2091, - 0x8000, 0x1078, 0x201b, 0x2091, 0x8001, 0x7814, 0xd0e4, 0x00c0, - 0x2301, 0x7810, 0xd0f4, 0x0040, 0x2301, 0x601b, 0x0021, 0x0078, - 0x2301, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22a8, 0x8000, 0x6026, - 0x6a10, 0x6814, 0xa202, 0x0048, 0x22bb, 0x0040, 0x22bb, 0x2091, - 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, - 0x2303, 0x0078, 0x2301, 0x2c08, 0xd9fc, 0x0040, 0x22de, 0x6800, - 0xa065, 0x0040, 0x22de, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, - 0x22d9, 0x704c, 0xa206, 0x00c0, 0x22d9, 0x6b04, 0x2160, 0x2304, - 0x6002, 0xa005, 0x00c0, 0x22d5, 0x6902, 0x2260, 0x6102, 0x0078, - 0x22ea, 0x2160, 0x6202, 0x6906, 0x0078, 0x22ea, 0x6800, 0x6902, - 0xa065, 0x0040, 0x22e6, 0x6102, 0x0078, 0x22e7, 0x6906, 0x2160, - 0x6003, 0x0000, 0x2160, 0xd9fc, 0x0040, 0x22f1, 0xa6b4, 0xfffc, - 0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, - 0x8001, 0xd6b4, 0x0040, 0x2301, 0xa6b6, 0x0040, 0x6e0a, 0x1078, - 0x1e80, 0x0e7f, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, - 0x1078, 0x201b, 0x2091, 0x8001, 0x78b8, 0xa065, 0x0040, 0x2316, - 0x609c, 0x78ba, 0x609f, 0x0000, 0x0078, 0x2303, 0x78b6, 0x78ba, - 0x007c, 0x7970, 0x7874, 0x2818, 0xd384, 0x0040, 0x2323, 0x8000, - 0xa112, 0x0048, 0x2328, 0x8000, 0xa112, 0x00c8, 0x2338, 0xc384, - 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0040, 0x2333, 0x7a84, - 0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0040, 0x2338, 0x8000, - 0x7876, 0x70d2, 0x781c, 0xa005, 0x0040, 0x2346, 0x8001, 0x781e, - 0x00c0, 0x2346, 0x0068, 0x2346, 0x2091, 0x4080, 0x007c, 0x2039, - 0x235f, 0x0078, 0x234d, 0x2039, 0x2365, 0x2704, 0xa005, 0x0040, - 0x235e, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, - 0x6814, 0x6916, 0x680e, 0x8738, 0x0078, 0x234d, 0x007c, 0x0003, - 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, - 0x2041, 0x0000, 0x780c, 0x0079, 0x236d, 0x2535, 0x2508, 0x2371, - 0x23e5, 0x2039, 0x9274, 0x2734, 0x7d10, 0x0078, 0x238c, 0x6084, - 0xa086, 0x0103, 0x00c0, 0x23ce, 0x6114, 0x6018, 0xa105, 0x00c0, - 0x23ce, 0x8603, 0xa080, 0x9255, 0x620c, 0x2202, 0x8000, 0x6210, - 0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x000f, 0x0040, 0x2454, - 0x786c, 0xa065, 0x00c0, 0x2377, 0x7808, 0xa602, 0x00c8, 0x239d, - 0xd5ac, 0x00c0, 0x239d, 0x263a, 0x007c, 0xa682, 0x0003, 0x00c8, - 0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, - 0x23c9, 0x2011, 0x9255, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, - 0xd684, 0x00c0, 0x23b9, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, - 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, - 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, - 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, - 0x253f, 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x2377, 0x2091, - 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x23e0, 0xc0ad, - 0x7812, 0x2091, 0x8001, 0x0078, 0x254e, 0x2039, 0x9274, 0x2734, - 0x7d10, 0x0078, 0x23fc, 0x6084, 0xa086, 0x0103, 0x00c0, 0x243d, - 0x6114, 0x6018, 0xa105, 0x00c0, 0x243d, 0xa680, 0x9255, 0x620c, - 0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x001e, 0x0040, 0x2454, - 0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8, 0x240d, - 0xd5ac, 0x00c0, 0x240d, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, - 0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, - 0x2438, 0x2011, 0x9255, 0x2009, 0x924e, 0x26a8, 0x211c, 0x2204, - 0x201a, 0x8108, 0x8210, 0x00f0, 0x241e, 0xa685, 0x8030, 0x70c2, + 0xa1a2, 0x4d00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, + 0xa192, 0x9700, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x2061, + 0x2218, 0x2079, 0x4d00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, + 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400, + 0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001, + 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100, + 0x0d7e, 0x2069, 0x4d40, 0x1078, 0x4c38, 0x0d7f, 0x7810, 0xc0ed, + 0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004, + 0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816, + 0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4d40, 0x1078, + 0x4c38, 0x2069, 0x4d80, 0x2071, 0x0100, 0x1078, 0x4c38, 0x7814, + 0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816, + 0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, + 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, + 0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4d40, 0x681b, 0x0003, + 0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, + 0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, + 0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4dc0, 0x2079, + 0x4d00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148, + 0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a, + 0x68d7, 0x732d, 0x68c7, 0x52c0, 0x68cb, 0x51c0, 0x68cf, 0x92c0, + 0x68ab, 0x9544, 0x68af, 0x9549, 0x68b3, 0x9544, 0x68b7, 0x9544, + 0x68a7, 0x0001, 0x2069, 0x4d80, 0x0078, 0x111e, 0x68d3, 0x000a, + 0x68c3, 0x4fc0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439, + 0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x72c0, 0x68cb, 0x5240, + 0x68cf, 0x93d0, 0x68ab, 0x9549, 0x68af, 0x954e, 0x68b3, 0x9549, + 0x68b7, 0x9549, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2, + 0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x51c0, 0x2071, + 0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021, + 0x000c, 0x1078, 0x1ff0, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021, + 0x000a, 0x1078, 0x1ff0, 0x2069, 0x5240, 0x2071, 0x0100, 0x70ec, + 0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, + 0x1ff0, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, + 0x1ff0, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c, + 0x2069, 0x51c0, 0x1078, 0x1ff0, 0x2069, 0x5240, 0x1078, 0x1ff0, + 0x0078, 0x11db, 0x2069, 0x51c0, 0x0e7e, 0x2071, 0x0100, 0x70ec, + 0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, + 0x1ff0, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a, + 0x1078, 0x1ff0, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x52c0, 0x2009, + 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8, + 0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064, + 0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, + 0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204, + 0x2069, 0x72c0, 0x0078, 0x11df, 0x1078, 0x261d, 0x1078, 0x4603, + 0x1078, 0x1dbb, 0x1078, 0x4be1, 0x2091, 0x2100, 0x2079, 0x4d00, + 0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a, + 0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4d00, 0x2071, 0x0020, + 0x2091, 0x2300, 0x2079, 0x4d00, 0x7810, 0xd0ec, 0x0040, 0x122c, + 0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4d40, + 0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4d80, 0x2091, 0x2000, + 0x2079, 0x4d00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, + 0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086, + 0x0002, 0x00c0, 0x124d, 0x1078, 0x15ba, 0x2039, 0x0000, 0x7810, + 0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0, + 0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078, + 0x2356, 0x1078, 0x2088, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040, + 0x126b, 0x1078, 0x2356, 0x0068, 0x1278, 0x2009, 0x4d47, 0x2011, + 0x4d87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1ef1, + 0x2071, 0x4d40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485, + 0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, + 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b0b, 0x2091, 0x8000, 0x2091, + 0x303d, 0x0068, 0x129d, 0x2079, 0x4d00, 0x786c, 0xa065, 0x0040, + 0x129d, 0x2071, 0x0010, 0x1078, 0x2356, 0x00e0, 0x12a5, 0x2079, + 0x4d00, 0x2071, 0x0010, 0x1078, 0x49ba, 0x2071, 0x4d80, 0x70a4, + 0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079, + 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, + 0x2b0b, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4d00, 0x2071, + 0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078, + 0x2356, 0x00e0, 0x1253, 0x1078, 0x49ba, 0x0078, 0x1253, 0x1078, + 0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c, + 0xa065, 0x0040, 0x12dd, 0x1078, 0x2356, 0x1078, 0x2088, 0x0068, + 0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x2356, 0x0068, + 0x12f1, 0x2009, 0x4d47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078, + 0x1ef1, 0x2071, 0x4d40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450, + 0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000, + 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b0b, 0x2091, 0x8000, + 0x2091, 0x303d, 0x2079, 0x4d00, 0x2071, 0x0010, 0x0068, 0x1316, + 0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x2356, 0x00e0, 0x12cf, + 0x1078, 0x49ba, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e, + 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363, + 0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e, + 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363, + 0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e, + 0x127e, 0x2091, 0x2400, 0x1078, 0x292b, 0x127f, 0x107f, 0x007f, + 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8, + 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, + 0x127e, 0x2091, 0x2300, 0x1078, 0x292b, 0x127f, 0x107f, 0x007f, + 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, + 0x1078, 0x292b, 0x2091, 0x2400, 0x1078, 0x292b, 0x127f, 0x107f, + 0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396, + 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396, + 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af, + 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, + 0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e, + 0x127e, 0x2091, 0x2300, 0x1078, 0x292b, 0x127f, 0x107f, 0x007f, + 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5, + 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e, + 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069, + 0x4d40, 0x2079, 0x4d00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, + 0x4c38, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c, + 0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0, + 0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003, + 0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x290c, + 0x2091, 0x2200, 0x1078, 0x46dd, 0x007c, 0x2091, 0x2100, 0x1078, + 0x46dd, 0x007c, 0x2091, 0x2100, 0x1078, 0x46dd, 0x2091, 0x2200, + 0x1078, 0x46dd, 0x007c, 0x2091, 0x2100, 0x1078, 0x46dd, 0x007c, + 0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427, + 0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427, + 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, + 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, + 0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078, + 0x292b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, + 0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091, + 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, + 0x292b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, + 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x292b, 0x2091, 0x2400, + 0x1078, 0x292b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, + 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4d00, + 0x2071, 0x0200, 0x2069, 0x4d40, 0x3d00, 0xd08c, 0x0040, 0x1466, + 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4c38, 0x3d00, 0xd084, + 0x0040, 0x1474, 0x2069, 0x4d80, 0x2071, 0x0100, 0x70ec, 0xa084, + 0x1c00, 0x78e6, 0x1078, 0x4c38, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, + 0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007, + 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489, + 0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15bd, 0x0068, 0x1513, + 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x1513, 0x7828, 0xa005, + 0x00c0, 0x149e, 0x0010, 0x1514, 0x0078, 0x1513, 0x7910, 0xd1f4, + 0x0040, 0x14a6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x7914, 0xd1ec, + 0x0040, 0x14c1, 0xd0fc, 0x0040, 0x14b7, 0x007e, 0x1078, 0x1d4b, + 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, 0x15bc, 0x007e, + 0x1078, 0x1d3b, 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, + 0x15bc, 0x7910, 0xd0fc, 0x00c0, 0x14cb, 0x2061, 0x4d40, 0xc19c, + 0xc7fc, 0x0078, 0x14cf, 0x2061, 0x4d80, 0xc19d, 0xc7fd, 0x6064, + 0xa005, 0x00c0, 0x1513, 0x7912, 0x6083, 0x0000, 0x7828, 0xc0fc, + 0xa086, 0x0018, 0x00c0, 0x14e0, 0x0c7e, 0x1078, 0x1b44, 0x0c7f, + 0x782b, 0x0000, 0x607c, 0xa065, 0x0040, 0x14f9, 0x0c7e, 0x609c, + 0x1078, 0x1e30, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c6d, 0x2009, + 0x0018, 0x6087, 0x0103, 0x1078, 0x1d5b, 0x00c0, 0x150d, 0x1078, + 0x1dad, 0x7810, 0xd09c, 0x00c0, 0x1501, 0x2061, 0x4d40, 0x0078, + 0x1505, 0x2061, 0x4d80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, + 0xd0dc, 0x0040, 0x1511, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078, + 0x15bc, 0x0078, 0x15ba, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x151c, + 0x2001, 0x4007, 0x0078, 0x15bc, 0xa006, 0x70c2, 0x70c6, 0x70ca, + 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x152a, + 0x0079, 0x1531, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15c8, 0x0079, + 0x1571, 0x15ba, 0x1610, 0x15d9, 0x1648, 0x1680, 0x1680, 0x15d0, + 0x1c85, 0x168b, 0x15c8, 0x15dd, 0x15df, 0x15e1, 0x15e3, 0x1c8a, + 0x15c8, 0x1699, 0x16f6, 0x1b64, 0x1c7f, 0x15e5, 0x19d4, 0x1a16, + 0x1a4e, 0x1a9c, 0x198f, 0x199c, 0x19b0, 0x19c3, 0x17cb, 0x15c8, + 0x172d, 0x173a, 0x1746, 0x1752, 0x1768, 0x1774, 0x1777, 0x1783, + 0x178f, 0x1797, 0x17b3, 0x17bf, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x17d8, 0x17ea, 0x1806, 0x183c, 0x1864, 0x1874, 0x1877, 0x18a8, + 0x18d9, 0x18eb, 0x195e, 0x196e, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x197e, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x1caf, 0x1cb5, + 0x15c8, 0x15c8, 0x15c8, 0x1cb9, 0x1cfe, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x160a, 0x167a, 0x1693, 0x16f0, 0x1b5e, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x1d02, 0x1ca1, 0x1cab, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, + 0x15c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15bc, 0x73ce, + 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15bd, 0x2061, + 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, + 0x70c3, 0x4001, 0x0078, 0x15bd, 0x70c3, 0x4006, 0x0078, 0x15bd, + 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078, + 0x15ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15ba, 0x0078, + 0x15ba, 0x0078, 0x15ba, 0x0078, 0x15ba, 0x2091, 0x8000, 0x70c3, + 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, + 0x0008, 0x2001, 0x000d, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, + 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445, + 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080, + 0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1613, + 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, + 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e, + 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15ba, 0xa182, + 0x0040, 0x00c8, 0x162d, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, + 0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1634, + 0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, 0x1642, 0x70c3, 0x4002, + 0x0078, 0x15bd, 0x24a8, 0x53a5, 0x0078, 0x1624, 0x0078, 0x15ba, + 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, + 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, + 0x7422, 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040, + 0x15ba, 0xa182, 0x0040, 0x00c8, 0x1667, 0x2120, 0xa006, 0x2008, + 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc, + 0x0040, 0x166e, 0xa084, 0x01e0, 0x0040, 0x165c, 0x70c3, 0x4002, + 0x0078, 0x15bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x164b, + 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1688, 0x200a, + 0x72ca, 0x0078, 0x15b9, 0x70c7, 0x0008, 0x70cb, 0x000d, 0x70cf, + 0x0008, 0x0078, 0x15ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, + 0x169c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, + 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16eb, 0xa40a, + 0x0040, 0x16ac, 0x00c8, 0x15bc, 0x8001, 0x7872, 0xa084, 0xfc00, + 0x0040, 0x16b9, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, + 0x15bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, + 0x0040, 0x16d1, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, + 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, + 0x16db, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, + 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, + 0x0040, 0x16e5, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, + 0x78ae, 0x0078, 0x16ee, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15ba, + 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16f9, 0x2029, 0x0000, + 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, + 0x74d6, 0xa005, 0x0040, 0x1728, 0xa40a, 0x0040, 0x1709, 0x00c8, + 0x15bc, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x1716, 0x78ac, + 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15bc, 0x7a9a, 0x7b9e, + 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1721, 0x7a10, 0xc2c5, + 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x172b, + 0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x15ba, 0x2009, 0x0000, 0x786c, + 0xa065, 0x0040, 0x1737, 0x8108, 0x6000, 0x0078, 0x1730, 0x7ac4, + 0x0078, 0x15b8, 0x2009, 0x4d48, 0x210c, 0x7810, 0xd0ec, 0x00c0, + 0x15b9, 0x2011, 0x4d88, 0x2214, 0x0078, 0x15b8, 0x2009, 0x4d49, + 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4d89, 0x2214, + 0x0078, 0x15b8, 0x2061, 0x4d40, 0x6128, 0x622c, 0x8214, 0x8214, + 0x8214, 0x7810, 0xd0ec, 0x00c0, 0x1766, 0x2061, 0x4d80, 0x6328, + 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15b8, + 0x2009, 0x4d4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, + 0x4d8c, 0x2214, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x2009, + 0x4d4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4d8d, + 0x2214, 0x0078, 0x15b8, 0x2009, 0x4d4e, 0x210c, 0x7810, 0xd0ec, + 0x00c0, 0x15b9, 0x2011, 0x4d8e, 0x2214, 0x0078, 0x15b8, 0x7920, + 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x7a24, 0x0078, 0x15b8, 0x71c4, + 0xd1fc, 0x00c0, 0x179f, 0x2011, 0x51c0, 0x0078, 0x17a1, 0x2011, + 0x5240, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, + 0x6a00, 0x6804, 0xd09c, 0x0040, 0x17b0, 0x6b08, 0x0078, 0x17b1, + 0x6b0c, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1dcb, 0x2091, 0x8000, + 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b7, 0x2061, + 0x4d40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4d80, + 0x6218, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1dcb, 0x2091, 0x8000, + 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15b7, + 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b2, + 0x1078, 0x2735, 0xa384, 0x4000, 0x0040, 0x17e8, 0xa295, 0x0020, + 0x0078, 0x15b7, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8, + 0x15b2, 0xd1bc, 0x00c0, 0x17f9, 0x2011, 0x4d48, 0x2204, 0x0078, + 0x17fd, 0x2011, 0x4d88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc, + 0x2012, 0x1078, 0x2692, 0x017f, 0x0078, 0x15b9, 0x71c4, 0x2021, + 0x4d49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1815, 0x71c8, + 0x2021, 0x4d89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1834, 0x20a9, + 0x0008, 0x2204, 0xa106, 0x0040, 0x1824, 0x8210, 0x00f0, 0x1819, + 0x71c4, 0x72c8, 0x0078, 0x15b1, 0xa292, 0x1834, 0x027e, 0x2122, + 0x017f, 0x1078, 0x26b3, 0x7810, 0xd0ec, 0x00c0, 0x1832, 0xd3fc, + 0x0040, 0x180f, 0x0078, 0x15ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee, + 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4d40, 0x6128, 0x622c, + 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, + 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1862, 0x027e, 0x017e, + 0x2061, 0x4d80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8, + 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de, + 0x017f, 0x027f, 0x0078, 0x15b8, 0x2061, 0x4d40, 0x6130, 0x70c4, + 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4d80, 0x6230, + 0x70c8, 0x6032, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x71c4, + 0xa184, 0xffcf, 0x0040, 0x1883, 0x7810, 0xd0ec, 0x00c0, 0x15b2, + 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4d4d, 0x2204, 0x2112, 0x007e, + 0x2019, 0x0000, 0x1078, 0x271a, 0x7810, 0xd0ec, 0x0040, 0x1893, + 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x189c, + 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4d8d, 0x2204, 0x2112, + 0x007e, 0xc3fd, 0x1078, 0x271a, 0x027f, 0x017f, 0x0078, 0x15b8, + 0x71c4, 0xa182, 0x0010, 0x0048, 0x18b4, 0x7810, 0xd0ec, 0x00c0, + 0x15b2, 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4d4e, 0x2204, 0x007e, + 0x2112, 0x2019, 0x0000, 0x1078, 0x26f8, 0x7810, 0xd0ec, 0x0040, + 0x18c4, 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa182, 0x0010, 0x0048, + 0x18cd, 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4d8e, 0x2204, + 0x007e, 0x2112, 0xc3fd, 0x1078, 0x26f8, 0x027f, 0x017f, 0x0078, + 0x15b8, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b1, 0xa284, + 0xfffd, 0x00c0, 0x15b1, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, + 0x7826, 0x0078, 0x15b8, 0x71c4, 0xd1fc, 0x00c0, 0x18f3, 0x2011, + 0x51c0, 0x0078, 0x18f5, 0x2011, 0x5240, 0x8107, 0xa084, 0x000f, + 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0x2091, + 0x8000, 0xa284, 0x0080, 0x0040, 0x190b, 0x6c14, 0x84ff, 0x00c0, + 0x190b, 0x6817, 0x0040, 0xa284, 0x0040, 0x0040, 0x1915, 0x6c10, + 0x84ff, 0x00c0, 0x1915, 0x6813, 0x0001, 0x6800, 0x007e, 0xa226, + 0x0040, 0x1932, 0x6a02, 0xd4ec, 0x0040, 0x191f, 0xc3a5, 0xd4e4, + 0x0040, 0x1923, 0xc39d, 0xd4f4, 0x0040, 0x1932, 0x810f, 0xd2f4, + 0x0040, 0x192e, 0x1078, 0x2777, 0x0078, 0x1932, 0x1078, 0x2755, + 0x0078, 0x1932, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1954, 0xa2a4, + 0x00ff, 0x7814, 0xd0e4, 0x00c0, 0x1945, 0xa482, 0x0028, 0x0048, + 0x1951, 0x0040, 0x1951, 0x0078, 0x1949, 0xa482, 0x0043, 0x0048, + 0x1951, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x2091, 0x8001, 0x0078, + 0x15b3, 0x6a0a, 0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, + 0x6b0c, 0x71c4, 0x2091, 0x8001, 0x0078, 0x15b7, 0x77c4, 0x1078, + 0x1dcb, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, + 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, 0x15b7, 0x70c4, 0x2061, + 0x4d40, 0x6118, 0x601a, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x70c8, + 0x2061, 0x4d80, 0x6218, 0x601a, 0x0078, 0x15b8, 0x71c4, 0x72c8, + 0x73cc, 0xa182, 0x0010, 0x00c8, 0x15b2, 0x1078, 0x2799, 0xa384, + 0x4000, 0x0040, 0x198d, 0xa295, 0x0020, 0x0078, 0x15b7, 0x77c4, + 0x1078, 0x1dcb, 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, + 0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1dcb, 0x2091, + 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, + 0x19ab, 0x1078, 0x25ea, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8, + 0x77c4, 0x1078, 0x1dcb, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, + 0x6804, 0xa005, 0x0040, 0x19be, 0x1078, 0x25ea, 0x2091, 0x8001, + 0x2708, 0x0078, 0x15b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, + 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x1de6, 0x2091, 0x8001, + 0x2708, 0x6a08, 0x0078, 0x15b8, 0x77c4, 0x7814, 0xd0e4, 0x00c0, + 0x19e8, 0xd7fc, 0x0040, 0x19e2, 0x1078, 0x1d4b, 0x0040, 0x19e8, + 0x0078, 0x15bc, 0x1078, 0x1d3b, 0x0040, 0x19e8, 0x0078, 0x15bc, + 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x1078, 0x1e6d, 0x00c0, + 0x1a12, 0x6818, 0xa005, 0x0040, 0x1a0c, 0x2708, 0x077e, 0x1078, + 0x27c9, 0x077f, 0x00c0, 0x1a0c, 0x2001, 0x0015, 0xd7fc, 0x00c0, + 0x1a05, 0x2061, 0x4d40, 0x0078, 0x1a08, 0xc0fd, 0x2061, 0x4d80, + 0x782a, 0x2091, 0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, + 0x0078, 0x15bc, 0x2091, 0x8001, 0x0078, 0x15ba, 0x77c4, 0x7814, + 0xd0e4, 0x00c0, 0x1a2a, 0xd7fc, 0x0040, 0x1a24, 0x1078, 0x1d4b, + 0x0040, 0x1a2a, 0x0078, 0x15bc, 0x1078, 0x1d3b, 0x0040, 0x1a2a, + 0x0078, 0x15bc, 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, + 0x0020, 0x2091, 0x8000, 0x1078, 0x1de6, 0x2009, 0x0016, 0xd7fc, + 0x00c0, 0x1a3e, 0x2061, 0x4d40, 0x0078, 0x1a41, 0x2061, 0x4d80, + 0xc1fd, 0x6067, 0x0003, 0x607f, 0x0000, 0x6776, 0x6083, 0x000f, + 0x792a, 0x1078, 0x25ea, 0x2091, 0x8001, 0x007c, 0x77c8, 0x77ca, + 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a65, 0xd7fc, 0x0040, + 0x1a5f, 0x1078, 0x1d4b, 0x0040, 0x1a65, 0x0078, 0x15bc, 0x1078, + 0x1d3b, 0x0040, 0x1a65, 0x0078, 0x15bc, 0xa7bc, 0xff00, 0x2091, + 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a72, 0x2061, 0x4d40, + 0x0078, 0x1a75, 0x2061, 0x4d80, 0xc1fd, 0x607f, 0x0000, 0x6067, + 0x0002, 0x6776, 0x6083, 0x000f, 0x792a, 0x1078, 0x25ea, 0x2091, + 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010, 0x2091, + 0x8000, 0x70c8, 0xa005, 0x0040, 0x1a90, 0x60d4, 0xc0fd, 0x60d6, + 0x1078, 0x1de6, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, + 0x1a90, 0x2091, 0x8001, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x1ab0, + 0x72c8, 0xd284, 0x0040, 0x1aaa, 0x1078, 0x1d4b, 0x0040, 0x1ab0, + 0x0078, 0x15bc, 0x1078, 0x1d3b, 0x0040, 0x1ab0, 0x0078, 0x15bc, + 0x72c8, 0x72ca, 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1adb, 0x2039, + 0x0000, 0xd284, 0x0040, 0x1abd, 0xc7fd, 0x2041, 0x0021, 0x2049, + 0x0004, 0x2051, 0x0008, 0x1078, 0x1dcb, 0x2091, 0x8000, 0x6808, + 0xc0d4, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, + 0x00c0, 0x1ac3, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, + 0x0f00, 0x00c0, 0x1ac3, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, + 0x1aed, 0x7810, 0xd0ec, 0x0040, 0x1ae9, 0x2069, 0x0100, 0x0078, + 0x1aef, 0x2069, 0x0200, 0x0078, 0x1aef, 0x2069, 0x0100, 0x6808, + 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x0040, 0x1b0f, 0x684b, + 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0040, 0x1b01, 0x00f0, + 0x1afb, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, + 0x1b0b, 0x00f0, 0x1b05, 0x20a9, 0x00fa, 0x00f0, 0x1b0d, 0x2079, + 0x4d00, 0x2009, 0x0018, 0x72c8, 0xd284, 0x00c0, 0x1b1b, 0x2061, + 0x4d40, 0x0078, 0x1b1e, 0x2061, 0x4d80, 0xc1fd, 0x792a, 0x6067, + 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, + 0x60d4, 0xd0b4, 0x0040, 0x1b38, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8, + 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, + 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x681b, + 0x0047, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b4b, 0x2069, + 0x4d40, 0x0078, 0x1b4d, 0x2069, 0x4d80, 0x71c4, 0x71c6, 0x6916, + 0x81ff, 0x00c0, 0x1b55, 0x68a7, 0x0001, 0x78ac, 0xc08c, 0x78ae, + 0xd084, 0x00c0, 0x1b5d, 0x1078, 0x1ecd, 0x007c, 0x75d8, 0x74dc, + 0x75da, 0x74de, 0x0078, 0x1b67, 0x2029, 0x0000, 0x2520, 0x71c4, + 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4d00, 0x7dde, + 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1da4, 0x0040, 0x1c69, 0x20a9, + 0x0005, 0x20a1, 0x4d14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, + 0x2009, 0x0040, 0x1078, 0x1fb8, 0x0040, 0x1b8a, 0x1078, 0x1dad, + 0x0078, 0x1c69, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0, + 0x1b95, 0x007e, 0x1078, 0x2339, 0x007f, 0xa084, 0xff00, 0x8007, + 0x8009, 0x0040, 0x1c09, 0x0c7e, 0x2c68, 0x1078, 0x1da4, 0x0040, + 0x1bdb, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1b9c, 0x609f, 0x0000, + 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, + 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, + 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c08, 0x2009, + 0x0040, 0x1078, 0x1fb8, 0x00c0, 0x1bf2, 0x6004, 0xa084, 0x00ff, + 0xa086, 0x0002, 0x00c0, 0x1bdb, 0x6004, 0xa084, 0x00ff, 0xa086, + 0x000a, 0x00c0, 0x1bd7, 0x017e, 0x1078, 0x2335, 0x017f, 0x2d00, + 0x6002, 0x0078, 0x1baa, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e30, + 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c6d, 0x2009, 0x0018, 0x6008, + 0xc0cd, 0x600a, 0x6004, 0x6086, 0x1078, 0x1d5b, 0x1078, 0x1dad, + 0x0078, 0x1c69, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e30, 0x0c7f, + 0x609f, 0x0000, 0x1078, 0x1c6d, 0x2009, 0x0018, 0x6087, 0x0103, + 0x601b, 0x0003, 0x1078, 0x1d5b, 0x1078, 0x1dad, 0x0078, 0x1c69, + 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1c2e, 0x6114, 0xd1fc, 0x0040, + 0x1c17, 0x1078, 0x1d4b, 0x0040, 0x1c2e, 0x0078, 0x1c1b, 0x1078, + 0x1d3b, 0x0040, 0x1c2e, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, + 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, 0x1d5b, + 0x1078, 0x1dad, 0x2001, 0x4007, 0x0078, 0x15bc, 0x74c4, 0x73c8, + 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, 0xd0fc, + 0x00c0, 0x1c3e, 0x2071, 0x4d40, 0x0078, 0x1c41, 0x2071, 0x4d80, + 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6, 0x736a, + 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, + 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1c58, 0x1078, 0x45a7, + 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, + 0x0000, 0x6714, 0x6023, 0x0000, 0x1078, 0x25ea, 0x2091, 0x8001, + 0x007c, 0x70c3, 0x4005, 0x0078, 0x15bd, 0x20a9, 0x0005, 0x2099, + 0x4d14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, + 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, + 0x70c7, 0x0000, 0x791e, 0x0078, 0x15ba, 0x71c4, 0x71c6, 0x2168, + 0x0078, 0x1c8c, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, + 0x8d68, 0x8109, 0x00c0, 0x1c8e, 0xa285, 0x0000, 0x00c0, 0x1c9c, + 0x70c3, 0x4000, 0x0078, 0x1c9e, 0x70c3, 0x4003, 0x70ca, 0x0078, + 0x15bd, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b2, + 0x7966, 0x0078, 0x15ba, 0x7964, 0x71c6, 0x0078, 0x15ba, 0x7900, + 0x71c6, 0x71c4, 0x7902, 0x0078, 0x15ba, 0x7900, 0x71c6, 0x0078, + 0x15ba, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1cce, + 0x810c, 0x0048, 0x1cca, 0x8210, 0x810c, 0x810c, 0x0048, 0x1cca, + 0x8210, 0x810c, 0x81ff, 0x00c0, 0x15b3, 0x8210, 0x7a0e, 0xd28c, + 0x0040, 0x1cfa, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, + 0x0003, 0xd284, 0x0040, 0x1cf4, 0x8108, 0x2019, 0x0041, 0x2011, + 0x954e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, + 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, + 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9553, 0x2112, 0x2011, + 0x9573, 0x2312, 0x7904, 0x7806, 0x0078, 0x15b9, 0x7804, 0x70c6, + 0x0078, 0x15ba, 0x71c4, 0xd1fc, 0x00c0, 0x1d0a, 0x2011, 0x51c0, + 0x0078, 0x1d0c, 0x2011, 0x5240, 0x8107, 0xa084, 0x000f, 0x8003, + 0x8003, 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d1b, 0x2011, + 0x0001, 0x0078, 0x1d1d, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x15b7, + 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d2d, 0x2001, 0x4007, 0x70db, + 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d39, 0xd0fc, 0x0040, 0x1d38, + 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d39, + 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d48, + 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d49, + 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040, 0x1d58, + 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d59, + 0xa006, 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4, + 0x0040, 0x1d64, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c, + 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2, + 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1d81, + 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, + 0x1d84, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, + 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1d91, 0x7b84, 0xa319, 0x7c80, + 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1d91, 0x7003, 0x0001, 0x7007, + 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1da1, 0x7322, + 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1dac, + 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4d00, + 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1db8, 0x1078, 0x290c, + 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9700, 0x7a4a, 0x7bc4, 0x8319, + 0x0040, 0x1dc8, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1dbf, + 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1dd4, + 0x2011, 0x52c0, 0x0078, 0x1dd6, 0x2011, 0x72c0, 0xa784, 0x0f00, + 0x800b, 0xa784, 0x001f, 0x0040, 0x1de1, 0x8003, 0x8003, 0x8003, + 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1dcb, + 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, + 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1dfb, 0x2009, 0x4d53, 0x2071, + 0x4d40, 0x0078, 0x1dff, 0x2009, 0x4d93, 0x2071, 0x4d80, 0x210c, + 0x6804, 0xa005, 0x0040, 0x1e0f, 0xa116, 0x00c0, 0x1e0f, 0x2060, + 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e12, 0x2009, + 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e27, 0x6000, 0x6806, + 0x1078, 0x1e42, 0x1078, 0x2004, 0x6810, 0x7908, 0x8109, 0x790a, + 0x8001, 0x6812, 0x00c0, 0x1e12, 0x7910, 0xc1a5, 0x7912, 0x017f, + 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2a6d, 0x0e7f, 0x007c, + 0xa065, 0x0040, 0x1e41, 0x2008, 0x609c, 0xa005, 0x0040, 0x1e3e, + 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e34, 0x7848, 0x794a, + 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, + 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, + 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1e5d, 0x2071, + 0x4d40, 0x2031, 0x4dc0, 0x0078, 0x1e61, 0x2071, 0x4d80, 0x2031, + 0x4fc0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1e6b, 0xa608, 0x2d0a, + 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0, + 0x1e75, 0x2079, 0x4d40, 0x0078, 0x1e77, 0x2079, 0x4d80, 0x1078, + 0x1dcb, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040, 0x1ecb, + 0x0078, 0x1e89, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065, 0x0040, + 0x1ecb, 0x6010, 0xa306, 0x00c0, 0x1e82, 0x600c, 0xa206, 0x00c0, + 0x1e82, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1e98, 0x0078, 0x1ec8, + 0x6804, 0xac06, 0x00c0, 0x1ea6, 0x6000, 0x2060, 0x6806, 0xa005, + 0x00c0, 0x1ea6, 0x6803, 0x0000, 0x0078, 0x1eb0, 0x6400, 0x7808, + 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1eb0, 0x2c00, 0x6802, + 0x2560, 0x0f7f, 0x1078, 0x1e42, 0x0f7e, 0x601b, 0x0005, 0x6023, + 0x0020, 0x0f7f, 0x1078, 0x2004, 0x0f7e, 0x7908, 0x8109, 0x790a, + 0x6810, 0x8001, 0x6812, 0x00c0, 0x1ec8, 0x7810, 0xc0a5, 0x7812, + 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039, + 0x0000, 0xd0fc, 0x0040, 0x1ed5, 0xc7fd, 0x2041, 0x0021, 0x2049, + 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1de6, 0x8738, + 0xa784, 0x001f, 0x00c0, 0x1edd, 0xa7bc, 0xff00, 0x873f, 0x8738, + 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1edd, 0x2091, 0x8001, 0x077f, + 0x007c, 0x786c, 0x2009, 0x9574, 0x210c, 0xa10d, 0x0040, 0x1efb, + 0xa065, 0x0078, 0x2356, 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, + 0x1f1b, 0x7810, 0xd08c, 0x0040, 0x1f0c, 0xc08c, 0x7812, 0xc7fc, + 0x2069, 0x4d40, 0x0078, 0x1f11, 0xc08d, 0x7812, 0x2069, 0x4d80, + 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, + 0xa005, 0x00c0, 0x1f1c, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1f22, + 0x1078, 0x290c, 0x0079, 0x1f24, 0x1f34, 0x1f37, 0x1f3d, 0x1f41, + 0x1f35, 0x1f45, 0x1f35, 0x1f35, 0x1f35, 0x1f4b, 0x1f7c, 0x1f80, + 0x1f86, 0x1f9b, 0x1f35, 0x1f35, 0x007c, 0x1078, 0x290c, 0x1078, + 0x1ecd, 0x2001, 0x8001, 0x0078, 0x1fa7, 0x2001, 0x8003, 0x0078, + 0x1fa7, 0x2001, 0x8004, 0x0078, 0x1fa7, 0x1078, 0x1ecd, 0x2001, + 0x8006, 0x0078, 0x1fa7, 0x2091, 0x8000, 0x077e, 0xd7fc, 0x00c0, + 0x1f57, 0x2069, 0x4d40, 0x2039, 0x0009, 0x0078, 0x1f5b, 0x2069, + 0x4d80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040, 0x1f65, + 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f, 0xa0bc, + 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078, + 0x1de6, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1f6f, 0x2091, 0x8001, + 0x2001, 0x800a, 0x0078, 0x1fa7, 0x2001, 0x800c, 0x0078, 0x1fa7, + 0x1078, 0x1ecd, 0x2001, 0x800d, 0x0078, 0x1fa7, 0x7814, 0xd0e4, + 0x00c0, 0x1f99, 0xd0ec, 0x0040, 0x1f93, 0xd7fc, 0x0040, 0x1f93, + 0x78e4, 0x0078, 0x1f94, 0x78e0, 0x70c6, 0x2001, 0x800e, 0x0078, + 0x1fa7, 0x0078, 0x1f35, 0xd7fc, 0x0040, 0x1fa1, 0x78ec, 0x0078, + 0x1fa2, 0x78e8, 0x70c6, 0x2001, 0x000d, 0x0078, 0x1fa7, 0x70c2, + 0xd7fc, 0x00c0, 0x1faf, 0x70db, 0x0000, 0x0078, 0x1fb1, 0x70db, + 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, + 0xac80, 0x0001, 0x81ff, 0x0040, 0x1fe3, 0x2099, 0x0030, 0x20a0, + 0x700c, 0xa084, 0x03ff, 0x0040, 0x1fc5, 0x7018, 0x007e, 0x701c, + 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a, + 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, + 0x800b, 0x00c8, 0x1fd7, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, + 0x1fe3, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f, + 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c, + 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00, + 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, + 0x8109, 0x00c0, 0x1ff4, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063, + 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x2011, 0x2c02, 0x0078, + 0x2012, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4d00, 0x6887, 0x0103, + 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x2023, + 0x2d02, 0x0078, 0x2024, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000, + 0x2c04, 0x786e, 0xa005, 0x00c0, 0x202e, 0x786a, 0x2091, 0x8001, + 0x609c, 0xa005, 0x0040, 0x2047, 0x0c7e, 0x2060, 0x2008, 0x609c, + 0xa005, 0x0040, 0x2043, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, + 0xa005, 0x00c0, 0x203b, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848, + 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x2051, 0x1078, + 0x290c, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, + 0x818e, 0x00c8, 0x205c, 0xa200, 0x00f0, 0x2057, 0x8086, 0x818e, + 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x2082, 0xa11a, + 0x00c8, 0x2082, 0x8213, 0x818d, 0x0048, 0x2075, 0xa11a, 0x00c8, + 0x2076, 0x00f0, 0x206a, 0x0078, 0x207a, 0xa11a, 0x2308, 0x8210, + 0x00f0, 0x206a, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, + 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x207e, + 0x7d74, 0x70d0, 0xa506, 0x0040, 0x216e, 0x7810, 0x2050, 0x7800, + 0xd08c, 0x0040, 0x20aa, 0xdaec, 0x0040, 0x20aa, 0x0e7e, 0x2091, + 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20a7, 0x7008, + 0x0e7f, 0xa086, 0x0008, 0x0040, 0x20aa, 0x0078, 0x216e, 0x0e7f, + 0x0078, 0x216e, 0x1078, 0x1da4, 0x0040, 0x216e, 0xa046, 0x7970, + 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20b9, 0x0078, + 0x20c0, 0x72d0, 0xa206, 0x0040, 0x20c0, 0x8840, 0x2009, 0x0080, + 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, + 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x20d2, + 0x1078, 0x1da4, 0x7008, 0xd0fc, 0x0040, 0x20d2, 0x7007, 0x0002, + 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2109, 0x53a5, 0x8cff, + 0x00c0, 0x20e7, 0x88ff, 0x0040, 0x2158, 0x0078, 0x20f1, 0x2c00, + 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078, + 0x2158, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x20f9, 0x7420, + 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, + 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2109, 0x7422, 0x7526, + 0xa006, 0x7007, 0x0004, 0x0040, 0x2158, 0x8cff, 0x0040, 0x2112, + 0x1078, 0x1dad, 0x0c7f, 0x1078, 0x1dad, 0xa046, 0x7888, 0x8000, + 0x788a, 0xa086, 0x0002, 0x0040, 0x2138, 0x7a7c, 0x7b78, 0xdac4, + 0x0040, 0x2124, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, + 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, + 0x731e, 0xdac4, 0x0040, 0x216e, 0x7422, 0x7526, 0x0078, 0x216e, + 0x6014, 0xd0fc, 0x00c0, 0x2140, 0x2069, 0x4d40, 0x0078, 0x2142, + 0x2069, 0x4d80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040, + 0x214e, 0xa046, 0x788c, 0x2060, 0x0078, 0x2138, 0x788b, 0x0000, + 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x216e, + 0x0c7f, 0x788b, 0x0000, 0x1078, 0x2307, 0x6004, 0xa084, 0x000f, + 0x1078, 0x216f, 0x88ff, 0x0040, 0x216c, 0x788c, 0x2060, 0x6004, + 0xa084, 0x000f, 0x1078, 0x216f, 0x0078, 0x2088, 0x007c, 0x0079, + 0x2171, 0x2181, 0x219f, 0x21bd, 0x2181, 0x21ce, 0x2192, 0x2181, + 0x2181, 0x2181, 0x219d, 0x21bb, 0x2181, 0x2181, 0x2181, 0x2181, + 0x2181, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, + 0x600a, 0x1078, 0x2211, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, + 0x22f1, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x2198, 0x0078, 0x2181, + 0x601c, 0xc0bd, 0x601e, 0x0078, 0x21a5, 0x1078, 0x2339, 0x78bc, + 0xd0c4, 0x0040, 0x21a5, 0x0078, 0x2181, 0x78bf, 0x0000, 0x6004, + 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21b8, 0x1078, + 0x2211, 0x0040, 0x21b8, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x21ba, + 0x0078, 0x2230, 0x007c, 0x1078, 0x2335, 0x78bc, 0xa08c, 0x0e00, + 0x00c0, 0x21c5, 0xd0c4, 0x00c0, 0x21c7, 0x0078, 0x2181, 0x1078, + 0x2211, 0x00c0, 0x21cd, 0x0078, 0x2230, 0x007c, 0x78bc, 0xd0c4, + 0x0040, 0x21d4, 0x0078, 0x2181, 0x78bf, 0x0000, 0x6714, 0x2011, + 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x21f4, + 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x21f4, + 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, + 0x0040, 0x21f4, 0x0078, 0x220e, 0x1078, 0x1dcb, 0x2d00, 0x2091, + 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, + 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x21f7, 0x8211, + 0x0040, 0x220e, 0x20a9, 0x0100, 0x0078, 0x21f7, 0x1078, 0x1dad, + 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0, + 0x221c, 0x78ba, 0x0078, 0x2224, 0x689e, 0x2d00, 0x6002, 0x78b8, + 0xad06, 0x00c0, 0x2224, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0, + 0x222f, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c, + 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, + 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040, + 0x2243, 0x1078, 0x45a7, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, + 0x2071, 0x4d80, 0xd7fc, 0x00c0, 0x224f, 0x2071, 0x4d40, 0xa784, + 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x225a, 0x8003, 0x8003, + 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084, + 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091, + 0x8000, 0x7810, 0xd0f4, 0x00c0, 0x2274, 0x6e08, 0xd684, 0x0040, + 0x228a, 0xd9fc, 0x00c0, 0x228a, 0x2091, 0x8001, 0x1078, 0x1e42, + 0x2091, 0x8000, 0x1078, 0x2004, 0x2091, 0x8001, 0x7814, 0xd0e4, + 0x00c0, 0x22ef, 0x7810, 0xd0f4, 0x0040, 0x22ef, 0x601b, 0x0021, + 0x0078, 0x22ef, 0x6024, 0xa096, 0x0001, 0x00c0, 0x2291, 0x8000, + 0x6026, 0x6a10, 0x6814, 0xa202, 0x0048, 0x22a4, 0x0040, 0x22a4, + 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, + 0x1078, 0x22f1, 0x0078, 0x22ef, 0x2c08, 0xd9fc, 0x0040, 0x22cc, + 0x6800, 0xa065, 0x0040, 0x22cc, 0x6a04, 0x7000, 0xa084, 0x0002, + 0x0040, 0x22c2, 0x704c, 0xa206, 0x00c0, 0x22c2, 0x6b04, 0x2160, + 0x2304, 0x6002, 0xa005, 0x00c0, 0x22be, 0x6902, 0x2260, 0x6102, + 0x0078, 0x22d8, 0x2d00, 0x2060, 0x1078, 0x2a6d, 0x6e08, 0x2160, + 0x6202, 0x6906, 0x0078, 0x22d8, 0x6800, 0x6902, 0xa065, 0x0040, + 0x22d4, 0x6102, 0x0078, 0x22d5, 0x6906, 0x2160, 0x6003, 0x0000, + 0x2160, 0xd9fc, 0x0040, 0x22df, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, + 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, + 0x0040, 0x22ef, 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1e53, 0x0e7f, + 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x2004, + 0x2091, 0x8001, 0x78b8, 0xa065, 0x0040, 0x2304, 0x609c, 0x78ba, + 0x609f, 0x0000, 0x0078, 0x22f1, 0x78b6, 0x78ba, 0x007c, 0x7970, + 0x7874, 0x2818, 0xd384, 0x0040, 0x2311, 0x8000, 0xa112, 0x0048, + 0x2316, 0x8000, 0xa112, 0x00c8, 0x2326, 0xc384, 0x7a7c, 0x721a, + 0x7a78, 0x721e, 0xdac4, 0x0040, 0x2321, 0x7a84, 0x7222, 0x7a80, + 0x7226, 0xa006, 0xd384, 0x0040, 0x2326, 0x8000, 0x7876, 0x70d2, + 0x781c, 0xa005, 0x0040, 0x2334, 0x8001, 0x781e, 0x00c0, 0x2334, + 0x0068, 0x2334, 0x2091, 0x4080, 0x007c, 0x2039, 0x234d, 0x0078, + 0x233b, 0x2039, 0x2353, 0x2704, 0xa005, 0x0040, 0x234c, 0xac00, + 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, + 0x680e, 0x8738, 0x0078, 0x233b, 0x007c, 0x0003, 0x0009, 0x000f, + 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, + 0x780c, 0x0079, 0x235b, 0x252d, 0x2500, 0x235f, 0x23d8, 0x2039, + 0x9574, 0x2734, 0x7d10, 0x0078, 0x237f, 0x6084, 0xa086, 0x0103, + 0x00c0, 0x23c1, 0x6114, 0x6018, 0xa105, 0x0040, 0x2374, 0x86ff, + 0x00c0, 0x2390, 0x0078, 0x23c1, 0x8603, 0xa080, 0x9555, 0x620c, + 0x2202, 0x8000, 0x6210, 0x2202, 0x1078, 0x2026, 0x8630, 0xa68e, + 0x000f, 0x0040, 0x244c, 0x786c, 0xa065, 0x00c0, 0x2365, 0x7808, + 0xa602, 0x00c8, 0x2390, 0xd5ac, 0x00c0, 0x2390, 0x263a, 0x007c, + 0xa682, 0x0003, 0x00c8, 0x244c, 0x2091, 0x8000, 0x2069, 0x0000, + 0x6818, 0xd084, 0x00c0, 0x23bc, 0x2011, 0x9555, 0x2204, 0x70c6, + 0x8210, 0x2204, 0x70ca, 0xd684, 0x00c0, 0x23ac, 0x8210, 0x2204, + 0x70da, 0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, + 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, + 0x8001, 0x203b, 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, + 0x244c, 0x263a, 0x1078, 0x2537, 0x00c0, 0x255a, 0x786c, 0xa065, + 0x00c0, 0x2365, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, + 0x0040, 0x23d3, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x255a, + 0x2039, 0x9574, 0x2734, 0x7d10, 0x0078, 0x23f4, 0x6084, 0xa086, + 0x0103, 0x00c0, 0x2435, 0x6114, 0x6018, 0xa105, 0x0040, 0x23ed, + 0x86ff, 0x00c0, 0x2405, 0x0078, 0x2435, 0xa680, 0x9555, 0x620c, + 0x2202, 0x1078, 0x2026, 0x8630, 0xa68e, 0x001e, 0x0040, 0x244c, + 0x786c, 0xa065, 0x00c0, 0x23de, 0x7808, 0xa602, 0x00c8, 0x2405, + 0xd5ac, 0x00c0, 0x2405, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, + 0x244c, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, + 0x2430, 0x2011, 0x9555, 0x2009, 0x954e, 0x26a8, 0x211c, 0x2204, + 0x201a, 0x8108, 0x8210, 0x00f0, 0x2416, 0xa685, 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, - 0x2091, 0x8001, 0xa006, 0x2009, 0x9275, 0x200a, 0x203a, 0x007c, - 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, 0x253f, - 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x2091, 0x8000, - 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x244f, 0xc0ad, 0x7812, - 0x2091, 0x8001, 0x0078, 0x254e, 0x2091, 0x8000, 0x7007, 0x0004, - 0x7994, 0x70d4, 0xa102, 0x0048, 0x2465, 0x0040, 0x246f, 0x7b90, - 0xa302, 0x00c0, 0x246f, 0x0078, 0x2468, 0x8002, 0x00c0, 0x246f, + 0x2091, 0x8001, 0xa006, 0x2009, 0x9575, 0x200a, 0x203a, 0x007c, + 0x7810, 0xc0ad, 0x7812, 0x0078, 0x244c, 0x263a, 0x1078, 0x2537, + 0x00c0, 0x255a, 0x786c, 0xa065, 0x00c0, 0x23de, 0x2091, 0x8000, + 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x2447, 0xc0ad, 0x7812, + 0x2091, 0x8001, 0x0078, 0x255a, 0x2091, 0x8000, 0x7007, 0x0004, + 0x7994, 0x70d4, 0xa102, 0x0048, 0x245d, 0x0040, 0x2467, 0x7b90, + 0xa302, 0x00c0, 0x2467, 0x0078, 0x2460, 0x8002, 0x00c0, 0x2467, 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, - 0xff00, 0x0040, 0x247c, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, - 0x8007, 0xa100, 0x0078, 0x247f, 0x8107, 0x8004, 0x8004, 0x7a9c, + 0xff00, 0x0040, 0x2474, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, + 0x8007, 0xa100, 0x0078, 0x2477, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, - 0x248f, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, - 0x0030, 0x7003, 0x0000, 0x2009, 0x9254, 0x260a, 0x8109, 0x2198, - 0x2104, 0xd084, 0x0040, 0x249d, 0x8633, 0xa6b0, 0x0002, 0x26a8, + 0x2487, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, + 0x0030, 0x7003, 0x0000, 0x2009, 0x9554, 0x260a, 0x8109, 0x2198, + 0x2104, 0xd084, 0x0040, 0x2495, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, - 0xa10a, 0x00c8, 0x24ac, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, - 0x0040, 0x24bb, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, - 0xa100, 0x0078, 0x24be, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, - 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0040, 0x24ca, 0x7b84, 0xa319, - 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x24ca, 0xa084, 0x01e0, - 0x0040, 0x24ef, 0x7d10, 0x2031, 0x9254, 0x2634, 0x78a8, 0x8000, - 0x78aa, 0xd08c, 0x00c0, 0x24e4, 0x7007, 0x0006, 0x7004, 0xd094, - 0x00c0, 0x24de, 0x0078, 0x2456, 0x2069, 0x4a47, 0x206b, 0x0003, - 0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x24f8, 0x2030, + 0xa10a, 0x00c8, 0x24a4, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, + 0x0040, 0x24b3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, + 0xa100, 0x0078, 0x24b6, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, + 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0040, 0x24c2, 0x7b84, 0xa319, + 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x24c2, 0xa084, 0x01e0, + 0x0040, 0x24e7, 0x7d10, 0x2031, 0x9554, 0x2634, 0x78a8, 0x8000, + 0x78aa, 0xd08c, 0x00c0, 0x24dc, 0x7007, 0x0006, 0x7004, 0xd094, + 0x00c0, 0x24d6, 0x0078, 0x244e, 0x2069, 0x4d47, 0x206b, 0x0003, + 0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x24f0, 0x2030, 0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, - 0x711a, 0x721e, 0xd5c4, 0x0040, 0x2507, 0x7322, 0x7426, 0x007c, - 0x6084, 0xa086, 0x0103, 0x00c0, 0x252b, 0x6114, 0x6018, 0xa105, - 0x00c0, 0x252b, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x252b, + 0x711a, 0x721e, 0xd5c4, 0x0040, 0x24ff, 0x7322, 0x7426, 0x007c, + 0x6084, 0xa086, 0x0103, 0x00c0, 0x2523, 0x6114, 0x6018, 0xa105, + 0x00c0, 0x2523, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x2523, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, - 0x2091, 0x4080, 0x1078, 0x203d, 0x0068, 0x252a, 0x786c, 0xa065, - 0x00c0, 0x2508, 0x007c, 0x1078, 0x253f, 0x00c0, 0x254e, 0x786c, - 0xa065, 0x00c0, 0x2508, 0x0078, 0x254e, 0x1078, 0x253f, 0x00c0, - 0x254e, 0x786c, 0xa065, 0x00c0, 0x2535, 0x0078, 0x254e, 0x1078, - 0x2554, 0x00c0, 0x2546, 0xa085, 0x0001, 0x007c, 0x1078, 0x2563, - 0x00c0, 0x254c, 0x2041, 0x0001, 0x7d10, 0x007c, 0x88ff, 0x0040, - 0x2553, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994, 0x70d4, 0xa102, - 0x00c0, 0x255d, 0xa385, 0x0000, 0x007c, 0x0048, 0x2561, 0xa302, - 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x257b, 0x0e7e, - 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2578, - 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x257b, 0x0078, 0x25cc, - 0x0e7f, 0x0078, 0x25cc, 0xa184, 0xff00, 0x0040, 0x2588, 0x810f, - 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x258b, - 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, - 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005, - 0x0040, 0x259c, 0x2009, 0x0040, 0x1078, 0x1d92, 0x0040, 0x25be, - 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x25cc, 0x6014, 0xd0fc, - 0x00c0, 0x25ae, 0x2069, 0x4a40, 0x0078, 0x25b0, 0x2069, 0x4a80, - 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, - 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x25cc, 0x78ab, 0x0000, - 0x1078, 0x203d, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x25c9, - 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, - 0x007c, 0x2138, 0xd7fc, 0x00c0, 0x25d9, 0x2009, 0x4a59, 0x0078, - 0x25db, 0x2009, 0x4a99, 0x2091, 0x8000, 0x200a, 0x0f7e, 0xd7fc, - 0x00c0, 0x25f2, 0x2009, 0x4a40, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x0040, 0x25ee, 0x2079, 0x0100, 0x0078, 0x25f6, 0x2079, 0x0200, - 0x0078, 0x25f6, 0x2009, 0x4a80, 0x2079, 0x0100, 0x2104, 0xa086, - 0x0000, 0x00c0, 0x260f, 0xd7fc, 0x00c0, 0x2602, 0x2009, 0x4a45, - 0x0078, 0x2604, 0x2009, 0x4a85, 0x2104, 0xa005, 0x00c0, 0x260f, - 0x7830, 0xa084, 0x00c0, 0x00c0, 0x260f, 0x781b, 0x0045, 0x0f7f, - 0x007c, 0x2009, 0x0002, 0x2069, 0x4a00, 0x6810, 0xd0ec, 0x00c0, - 0x2672, 0x2071, 0x4a80, 0x2079, 0x0100, 0x2021, 0x4cbf, 0x784b, - 0x000f, 0x2019, 0x4205, 0xd184, 0x0040, 0x2632, 0x6810, 0xd0ec, - 0x0040, 0x262e, 0x20a1, 0x012b, 0x0078, 0x2634, 0x20a1, 0x022b, - 0x0078, 0x2634, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x2641, - 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078, - 0x2634, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, - 0x8020, 0x00f0, 0x2645, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, - 0x0000, 0x0040, 0x2654, 0xc1bd, 0x1078, 0x283d, 0x017f, 0x7020, - 0xa084, 0x000f, 0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2664, - 0xa085, 0x6340, 0x0078, 0x2666, 0xa085, 0x62c0, 0x7806, 0x780f, - 0x9200, 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, - 0x7053, 0x0000, 0x8109, 0x0040, 0x2685, 0x2071, 0x4a40, 0x6810, - 0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2681, 0x2079, - 0x0200, 0x2021, 0x4abf, 0x0078, 0x261f, 0x007c, 0x017e, 0xd1bc, - 0x00c0, 0x269a, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, - 0x0040, 0x2696, 0x2011, 0x0101, 0x0078, 0x269c, 0x2011, 0x0201, - 0x0078, 0x269c, 0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, - 0xfff0, 0xa105, 0x2012, 0x017f, 0x1078, 0x283d, 0x007c, 0xd3fc, - 0x00c0, 0x26ba, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, - 0x0040, 0x26b6, 0x2011, 0x0101, 0x0078, 0x26bc, 0x2011, 0x0201, - 0x0078, 0x26bc, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, - 0x26be, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, - 0x007c, 0x2019, 0x0002, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, - 0x26d6, 0x8319, 0x2009, 0x0101, 0x0078, 0x26d8, 0x2009, 0x0101, - 0x20a9, 0x0005, 0x8213, 0x00f0, 0x26da, 0xa294, 0x00e0, 0x2104, - 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0040, 0x26eb, 0x2009, - 0x0201, 0x0078, 0x26d8, 0x007c, 0xd3fc, 0x00c0, 0x26ff, 0x007e, - 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26fb, 0x2011, - 0x0101, 0x0078, 0x2701, 0x2011, 0x0201, 0x0078, 0x2701, 0x2011, - 0x0101, 0x20a9, 0x000c, 0x810b, 0x00f0, 0x2703, 0xa18c, 0xf000, - 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, - 0x2721, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, - 0x271d, 0x2011, 0x0102, 0x0078, 0x2723, 0x2011, 0x0202, 0x0078, - 0x2723, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, - 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x273d, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2739, 0x2061, 0x0100, 0x0078, - 0x273f, 0x2061, 0x0200, 0x0078, 0x273f, 0x2061, 0x0100, 0xc1bc, - 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, - 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x275d, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2759, 0x2061, 0x0100, 0x0078, - 0x275f, 0x2061, 0x0200, 0x0078, 0x275f, 0x2061, 0x0100, 0xc1bc, - 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, - 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x277f, 0x007e, - 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x277b, 0x2061, - 0x0100, 0x0078, 0x2781, 0x2061, 0x0200, 0x0078, 0x2781, 0x2061, - 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, - 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, - 0x27a1, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, - 0x279d, 0x2061, 0x0100, 0x0078, 0x27a3, 0x2061, 0x0200, 0x0078, - 0x27a3, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, - 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0040, 0x27b1, 0xc2ac, 0xa39d, - 0x4000, 0xc3fc, 0xd3b4, 0x00c0, 0x27b6, 0xc3fd, 0x62ae, 0x2010, - 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, - 0x0e7e, 0x6818, 0xa005, 0x0040, 0x281b, 0xd1fc, 0x0040, 0x27cc, - 0x2061, 0x91d0, 0x0078, 0x27ce, 0x2061, 0x90c0, 0x1078, 0x2823, - 0x0040, 0x2801, 0x20a9, 0x0101, 0xd1fc, 0x0040, 0x27db, 0x2061, - 0x90d0, 0x0078, 0x27dd, 0x2061, 0x8fc0, 0x0c7e, 0x1078, 0x2823, - 0x0040, 0x27e8, 0x0c7f, 0x8c60, 0x00f0, 0x27dd, 0x0078, 0x281b, - 0x007f, 0xd1fc, 0x0040, 0x27f2, 0xa082, 0x90d0, 0x2071, 0x4a80, - 0x0078, 0x27f6, 0xa082, 0x8fc0, 0x2071, 0x4a40, 0x707a, 0x7176, - 0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x0078, - 0x2817, 0xd1fc, 0x00c0, 0x2808, 0x2071, 0x4a40, 0x0078, 0x280a, - 0x2071, 0x4a80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e, - 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x2001, - 0x0000, 0x0078, 0x281d, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, - 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x283a, 0x2060, - 0x6010, 0xa306, 0x00c0, 0x2837, 0x600c, 0xa206, 0x00c0, 0x2837, - 0x6014, 0xa106, 0x00c0, 0x2837, 0xa006, 0x0078, 0x283c, 0x6000, - 0x0078, 0x2824, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, - 0xd1bc, 0x00c0, 0x2855, 0x2079, 0x4a40, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2851, 0x2071, 0x0100, 0x0078, - 0x2859, 0x2071, 0x0200, 0x0078, 0x2859, 0x2079, 0x4a80, 0x2071, - 0x0100, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2863, - 0x017f, 0x0078, 0x287e, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, - 0xd0bc, 0x00c0, 0x287b, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x007f, 0x0040, 0x2877, 0xa18d, 0x0f00, 0x0078, 0x287d, 0xa18d, - 0x0f00, 0x0078, 0x287d, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, - 0x007c, 0x0e7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, 0x28ea, - 0x68e4, 0xd0ac, 0x0040, 0x28ea, 0xa084, 0x0006, 0x00c0, 0x28ea, - 0x6014, 0xd0fc, 0x00c0, 0x2898, 0x2071, 0x4ec0, 0x0078, 0x289a, - 0x2071, 0x4f40, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xae70, 0x7004, 0xa084, 0x000a, 0x00c0, 0x28ea, 0x7108, 0xa194, - 0xff00, 0x0040, 0x28ea, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, - 0x0040, 0x28cd, 0x2001, 0x000c, 0xa106, 0x0040, 0x28d1, 0x2001, - 0x0012, 0xa106, 0x0040, 0x28d5, 0x2001, 0x0014, 0xa106, 0x0040, - 0x28d9, 0x2001, 0x0019, 0xa106, 0x0040, 0x28dd, 0x2001, 0x0032, - 0xa106, 0x0040, 0x28e1, 0x0078, 0x28e5, 0x2009, 0x000c, 0x0078, - 0x28e7, 0x2009, 0x0012, 0x0078, 0x28e7, 0x2009, 0x0014, 0x0078, - 0x28e7, 0x2009, 0x0019, 0x0078, 0x28e7, 0x2009, 0x0020, 0x0078, - 0x28e7, 0x2009, 0x003f, 0x0078, 0x28e7, 0x2011, 0x0000, 0x2100, - 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x28ec, 0x2091, 0x8000, - 0x2071, 0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x28f3, 0x007f, + 0x2091, 0x4080, 0x1078, 0x2026, 0x0068, 0x2522, 0x786c, 0xa065, + 0x00c0, 0x2500, 0x007c, 0x1078, 0x2537, 0x00c0, 0x255a, 0x786c, + 0xa065, 0x00c0, 0x2500, 0x0078, 0x255a, 0x1078, 0x2537, 0x00c0, + 0x255a, 0x786c, 0xa065, 0x00c0, 0x252d, 0x0078, 0x255a, 0x6084, + 0xa086, 0x0103, 0x00c0, 0x254b, 0x6018, 0xc0fc, 0x601a, 0xa086, + 0x0004, 0x00c0, 0x254b, 0x7804, 0xd0a4, 0x0040, 0x254b, 0x1078, + 0x2026, 0xa006, 0x007c, 0x1078, 0x2560, 0x00c0, 0x2552, 0xa085, + 0x0001, 0x007c, 0x1078, 0x256f, 0x00c0, 0x2558, 0x2041, 0x0001, + 0x7d10, 0x007c, 0x88ff, 0x0040, 0x255f, 0x2091, 0x4080, 0x007c, + 0x7b90, 0x7994, 0x70d4, 0xa102, 0x00c0, 0x2569, 0xa385, 0x0000, + 0x007c, 0x0048, 0x256d, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, + 0xd0ec, 0x0040, 0x2587, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, + 0x7004, 0xa005, 0x00c0, 0x2584, 0x7008, 0x0e7f, 0xa086, 0x0008, + 0x0040, 0x2587, 0x0078, 0x25d8, 0x0e7f, 0x0078, 0x25d8, 0xa184, + 0xff00, 0x0040, 0x2594, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, + 0x8007, 0xa100, 0x0078, 0x2597, 0x8107, 0x8004, 0x8004, 0x7a9c, + 0x7b98, 0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, + 0x2009, 0x0018, 0x6028, 0xa005, 0x0040, 0x25a8, 0x2009, 0x0040, + 0x1078, 0x1d5b, 0x0040, 0x25ca, 0x78a8, 0x8000, 0x78aa, 0xd08c, + 0x00c0, 0x25d8, 0x6014, 0xd0fc, 0x00c0, 0x25ba, 0x2069, 0x4d40, + 0x0078, 0x25bc, 0x2069, 0x4d80, 0x2091, 0x8000, 0x681f, 0x0003, + 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, + 0x0078, 0x25d8, 0x78ab, 0x0000, 0x1078, 0x2026, 0x7990, 0x7894, + 0x8000, 0xa10a, 0x00c8, 0x25d5, 0xa006, 0x7896, 0x70d6, 0xa006, + 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x2138, 0xd7fc, 0x00c0, + 0x25e5, 0x2009, 0x4d59, 0x0078, 0x25e7, 0x2009, 0x4d99, 0x2091, + 0x8000, 0x200a, 0x0f7e, 0xd7fc, 0x00c0, 0x25fe, 0x2009, 0x4d40, + 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x0040, 0x25fa, 0x2079, 0x0100, + 0x0078, 0x2602, 0x2079, 0x0200, 0x0078, 0x2602, 0x2009, 0x4d80, + 0x2079, 0x0100, 0x2104, 0xa086, 0x0000, 0x00c0, 0x261b, 0xd7fc, + 0x00c0, 0x260e, 0x2009, 0x4d45, 0x0078, 0x2610, 0x2009, 0x4d85, + 0x2104, 0xa005, 0x00c0, 0x261b, 0x7830, 0xa084, 0x00c0, 0x00c0, + 0x261b, 0x781b, 0x0045, 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, + 0x4d00, 0x6810, 0xd0ec, 0x00c0, 0x267e, 0x2071, 0x4d80, 0x2079, + 0x0100, 0x2021, 0x4fbf, 0x784b, 0x000f, 0x2019, 0x43d2, 0xd184, + 0x0040, 0x263e, 0x6810, 0xd0ec, 0x0040, 0x263a, 0x20a1, 0x012b, + 0x0078, 0x2640, 0x20a1, 0x022b, 0x0078, 0x2640, 0x20a1, 0x012b, + 0x2304, 0xa005, 0x0040, 0x264d, 0x789a, 0x8318, 0x23ac, 0x8318, + 0x2398, 0x53a6, 0x3318, 0x0078, 0x2640, 0x789b, 0x0020, 0x20a9, + 0x0010, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0, 0x2651, 0x7003, + 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040, 0x2660, 0xc1bd, + 0x1078, 0x2849, 0x017f, 0x7020, 0xa084, 0x000f, 0x007e, 0x6814, + 0xd0e4, 0x007f, 0x00c0, 0x2670, 0xa085, 0x6340, 0x0078, 0x2672, + 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843, 0x00d8, 0x7853, + 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000, 0x8109, 0x0040, + 0x2691, 0x2071, 0x4d40, 0x6810, 0xd0ec, 0x0040, 0x268b, 0x2079, + 0x0100, 0x0078, 0x268d, 0x2079, 0x0200, 0x2021, 0x4dbf, 0x0078, + 0x262b, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x26a6, 0x007e, 0x2001, + 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26a2, 0x2011, 0x0101, + 0x0078, 0x26a8, 0x2011, 0x0201, 0x0078, 0x26a8, 0x2011, 0x0101, + 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x017f, + 0x1078, 0x2849, 0x007c, 0xd3fc, 0x00c0, 0x26c6, 0x007e, 0x2001, + 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26c2, 0x2011, 0x0101, + 0x0078, 0x26c8, 0x2011, 0x0201, 0x0078, 0x26c8, 0x2011, 0x0101, + 0x20a9, 0x0009, 0x810b, 0x00f0, 0x26ca, 0xa18c, 0x0e00, 0x2204, + 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019, 0x0002, 0x2001, + 0x4d04, 0x2004, 0xd0ec, 0x0040, 0x26e2, 0x8319, 0x2009, 0x0101, + 0x0078, 0x26e4, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x00f0, + 0x26e6, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, + 0x8319, 0x0040, 0x26f7, 0x2009, 0x0201, 0x0078, 0x26e4, 0x007c, + 0xd3fc, 0x00c0, 0x270b, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x2707, 0x2011, 0x0101, 0x0078, 0x270d, 0x2011, + 0x0201, 0x0078, 0x270d, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, + 0x00f0, 0x270f, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, + 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x272d, 0x007e, 0x2001, 0x4d04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2729, 0x2011, 0x0102, 0x0078, + 0x272f, 0x2011, 0x0202, 0x0078, 0x272f, 0x2011, 0x0102, 0x2204, + 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, + 0x2749, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, + 0x2745, 0x2061, 0x0100, 0x0078, 0x274b, 0x2061, 0x0200, 0x0078, + 0x274b, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, + 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, + 0x2769, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, + 0x2765, 0x2061, 0x0100, 0x0078, 0x276b, 0x2061, 0x0200, 0x0078, + 0x276b, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, + 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x0c7e, + 0xd1bc, 0x00c0, 0x278b, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x2787, 0x2061, 0x0100, 0x0078, 0x278d, 0x2061, + 0x0200, 0x0078, 0x278d, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, + 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, + 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27ad, 0x007e, 0x2001, 0x4d04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27a9, 0x2061, 0x0100, 0x0078, + 0x27af, 0x2061, 0x0200, 0x0078, 0x27af, 0x2061, 0x0100, 0xc1bc, + 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020, + 0x0040, 0x27bd, 0xc2ac, 0xa39d, 0x4000, 0xc3fc, 0xd3b4, 0x00c0, + 0x27c2, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, + 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, + 0x2827, 0xd1fc, 0x0040, 0x27d8, 0x2061, 0x94d0, 0x0078, 0x27da, + 0x2061, 0x93c0, 0x1078, 0x282f, 0x0040, 0x280d, 0x20a9, 0x0101, + 0xd1fc, 0x0040, 0x27e7, 0x2061, 0x93d0, 0x0078, 0x27e9, 0x2061, + 0x92c0, 0x0c7e, 0x1078, 0x282f, 0x0040, 0x27f4, 0x0c7f, 0x8c60, + 0x00f0, 0x27e9, 0x0078, 0x2827, 0x007f, 0xd1fc, 0x0040, 0x27fe, + 0xa082, 0x93d0, 0x2071, 0x4d80, 0x0078, 0x2802, 0xa082, 0x92c0, + 0x2071, 0x4d40, 0x707a, 0x7176, 0x2001, 0x0004, 0x7066, 0x7083, + 0x000f, 0x1078, 0x25dd, 0x0078, 0x2823, 0xd1fc, 0x00c0, 0x2814, + 0x2071, 0x4d40, 0x0078, 0x2816, 0x2071, 0x4d80, 0x6020, 0xc0dd, + 0x6022, 0x7176, 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, + 0x000f, 0x1078, 0x25dd, 0x2001, 0x0000, 0x0078, 0x2829, 0x2001, + 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, + 0xa005, 0x0040, 0x2846, 0x2060, 0x6010, 0xa306, 0x00c0, 0x2843, + 0x600c, 0xa206, 0x00c0, 0x2843, 0x6014, 0xa106, 0x00c0, 0x2843, + 0xa006, 0x0078, 0x2848, 0x6000, 0x0078, 0x2830, 0xa085, 0x0001, + 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0, 0x2861, 0x2079, + 0x4d40, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, + 0x285d, 0x2071, 0x0100, 0x0078, 0x2865, 0x2071, 0x0200, 0x0078, + 0x2865, 0x2079, 0x4d80, 0x2071, 0x0100, 0x7920, 0xa18c, 0x000f, + 0x70ec, 0xd0c4, 0x00c0, 0x286f, 0x017f, 0x0078, 0x288a, 0x810b, + 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0, 0x2887, 0x007e, + 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2883, 0xa18d, + 0x0f00, 0x0078, 0x2889, 0xa18d, 0x0f00, 0x0078, 0x2889, 0xa18d, + 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e, 0x2001, 0x4d01, + 0x2004, 0xd0ac, 0x00c0, 0x290a, 0x68e4, 0xd0ac, 0x0040, 0x290a, + 0xa084, 0x0006, 0x00c0, 0x290a, 0x6014, 0xd0fc, 0x00c0, 0x28a4, + 0x2071, 0x51c0, 0x0078, 0x28a6, 0x2071, 0x5240, 0x8007, 0xa084, + 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a, + 0x00c0, 0x290a, 0x7108, 0xa194, 0xff00, 0x0040, 0x290a, 0xa18c, + 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x28d9, 0x2001, 0x000c, + 0xa106, 0x0040, 0x28dd, 0x2001, 0x0012, 0xa106, 0x0040, 0x28e1, + 0x2001, 0x0014, 0xa106, 0x0040, 0x28e5, 0x2001, 0x0019, 0xa106, + 0x0040, 0x28e9, 0x2001, 0x0032, 0xa106, 0x0040, 0x28ed, 0x0078, + 0x28f1, 0x2009, 0x000c, 0x0078, 0x28f3, 0x2009, 0x0012, 0x0078, + 0x28f3, 0x2009, 0x0014, 0x0078, 0x28f3, 0x2009, 0x0019, 0x0078, + 0x28f3, 0x2009, 0x0020, 0x0078, 0x28f3, 0x2009, 0x003f, 0x0078, + 0x28f3, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x2071, 0x4d00, + 0x7004, 0xd0bc, 0x0040, 0x290a, 0x6014, 0xd0fc, 0x00c0, 0x2905, + 0x70ea, 0x2071, 0x4d40, 0x0078, 0x2908, 0x70ee, 0x2071, 0x4d80, + 0x701f, 0x800f, 0x0e7f, 0x007c, 0x0068, 0x290c, 0x2091, 0x8000, + 0x2071, 0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x2913, 0x007f, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, - 0x0809, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, - 0x4080, 0x0078, 0x2909, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, + 0x080d, 0x70df, 0x0008, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, + 0x4080, 0x0078, 0x2929, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, - 0x0040, 0x2920, 0xa784, 0x007d, 0x00c0, 0x417b, 0x1078, 0x28ec, - 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x292b, 0xa3a6, 0x0007, - 0x00c0, 0x28ec, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x2930, - 0x2f45, 0x3035, 0x3060, 0x32c1, 0x363b, 0x36a1, 0x3741, 0x37bd, - 0x38a1, 0x398a, 0x2943, 0x2940, 0x2d2a, 0x2e43, 0x360e, 0x2940, - 0x1078, 0x28ec, 0x007c, 0xa006, 0x0078, 0x294d, 0x7808, 0xc08d, + 0x0040, 0x2940, 0xa784, 0x007d, 0x00c0, 0x4348, 0x1078, 0x290c, + 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x294b, 0xa3a6, 0x0007, + 0x00c0, 0x290c, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x2950, + 0x2fc6, 0x30b5, 0x30e0, 0x3341, 0x372a, 0x379f, 0x3853, 0x38cf, + 0x39bd, 0x3aac, 0x2963, 0x2960, 0x2d99, 0x2eba, 0x36fb, 0x2960, + 0x1078, 0x290c, 0x007c, 0xa006, 0x0078, 0x296d, 0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, - 0x00c0, 0x2a64, 0x7064, 0xa084, 0x0007, 0x0079, 0x2957, 0x295f, - 0x29cf, 0x29d8, 0x29e3, 0x29ee, 0x2a4a, 0x29f9, 0x29cf, 0x7830, - 0xd0bc, 0x00c0, 0x2942, 0x71d4, 0xd1b4, 0x00c0, 0x29ac, 0x70a4, - 0xa086, 0x0001, 0x0040, 0x2942, 0x70b4, 0xa06d, 0x6800, 0xa065, - 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, - 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2982, 0x69bc, - 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0078, - 0x2bbd, 0x7060, 0xa005, 0x00c0, 0x2942, 0x0c7e, 0x0d7e, 0x70b4, + 0x00c0, 0x2ad3, 0x7064, 0xa084, 0x0007, 0x0079, 0x2977, 0x297f, + 0x29f2, 0x29fb, 0x2a06, 0x2a11, 0x2ab9, 0x2a1c, 0x29f2, 0x7830, + 0xd0bc, 0x00c0, 0x2962, 0x71d4, 0xd1bc, 0x00c0, 0x2962, 0xd1b4, + 0x00c0, 0x29cf, 0x70a4, 0xa086, 0x0001, 0x0040, 0x2962, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x29a5, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, - 0x2001, 0x0020, 0x0078, 0x2bbd, 0x1078, 0x411c, 0x00c0, 0x2942, - 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, - 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x7003, - 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x1078, - 0x411c, 0x00c0, 0x29d7, 0x781b, 0x0047, 0x7003, 0x0004, 0x007c, - 0x1078, 0x411c, 0x00c0, 0x29e2, 0x2011, 0x000c, 0x1078, 0x2a09, - 0x7003, 0x0004, 0x007c, 0x1078, 0x411c, 0x00c0, 0x29ed, 0x2011, - 0x0006, 0x1078, 0x2a09, 0x7003, 0x0004, 0x007c, 0x1078, 0x411c, - 0x00c0, 0x29f8, 0x2011, 0x000d, 0x1078, 0x2a09, 0x7003, 0x0004, - 0x007c, 0x1078, 0x411c, 0x00c0, 0x2a08, 0x2011, 0x0006, 0x1078, - 0x2a09, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003, 0x0001, - 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010, 0xa286, - 0x000c, 0x00c0, 0x2a18, 0x7aaa, 0x2001, 0x0001, 0x0078, 0x2a2d, - 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0040, - 0x2a26, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2a2d, 0x78ab, 0x0020, - 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, - 0x785b, 0x0004, 0x781b, 0x0108, 0x1078, 0x4131, 0x7083, 0x000f, - 0x70d4, 0xd0b4, 0x0040, 0x2a49, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x007c, 0x1078, 0x411c, 0x00c0, 0x2942, 0x707c, 0x2068, - 0x7774, 0x1078, 0x3fe1, 0x2c50, 0x1078, 0x41f0, 0x789b, 0x0010, - 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, - 0x2001, 0x0004, 0x0078, 0x2bc3, 0x1078, 0x411c, 0x00c0, 0x2942, - 0x789b, 0x0010, 0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, - 0x2a7e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, - 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x3fe1, - 0x2c50, 0x1078, 0x41f0, 0x6824, 0xa005, 0x0040, 0x2a8f, 0xa082, - 0x0006, 0x0048, 0x2a8d, 0x0078, 0x2a8f, 0x6827, 0x0005, 0x6814, - 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, - 0x2001, 0x0003, 0x0078, 0x2bc3, 0xc28d, 0x72d6, 0x72c0, 0xa200, - 0xa015, 0x7154, 0x8108, 0xa12a, 0x0048, 0x2aa7, 0x71c0, 0x2164, - 0x6504, 0x85ff, 0x00c0, 0x2abe, 0x7156, 0x8421, 0x00c0, 0x2aa2, - 0x70d4, 0xd08c, 0x0040, 0x2aba, 0x70d0, 0xa005, 0x00c0, 0x2aba, - 0x70d3, 0x000a, 0x007c, 0x2200, 0x0078, 0x2aac, 0x70d4, 0xc08c, - 0x70d6, 0x70d3, 0x0000, 0x603c, 0xa005, 0x00c0, 0x2abb, 0x6708, - 0xa784, 0x073f, 0x0040, 0x2aed, 0xd7d4, 0x00c0, 0x2abb, 0xa784, - 0x0021, 0x00c0, 0x2abb, 0xa784, 0x0002, 0x0040, 0x2ade, 0xa784, - 0x0004, 0x0040, 0x2abb, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, - 0x00c0, 0x2abb, 0xa784, 0x0100, 0x0040, 0x2aed, 0x6018, 0xa005, - 0x00c0, 0x2abb, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, - 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0040, 0x2afe, 0x601c, 0xa302, - 0x0048, 0x2b01, 0x0040, 0x2b01, 0x0078, 0x2abb, 0x83ff, 0x00c0, - 0x2abb, 0x2d58, 0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2b09, 0x7028, - 0x6022, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, - 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, - 0x0040, 0x2b1d, 0xd684, 0x0040, 0x2b1f, 0xa39c, 0xffbf, 0xd6a4, - 0x0040, 0x2b24, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2b6f, - 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, - 0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002, - 0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010, - 0x7baa, 0x0078, 0x2bbb, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, - 0x0005, 0x70ac, 0xa606, 0x00c0, 0x2b4e, 0x76a8, 0x76b2, 0x2c3a, - 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, - 0x7830, 0xd0bc, 0x0040, 0x2b66, 0x2091, 0x8000, 0x2091, 0x303d, - 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, - 0x0040, 0x2b6e, 0x8421, 0x2200, 0x00c0, 0x2aa1, 0x007c, 0xd1dc, - 0x0040, 0x3be5, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2b7c, 0x8528, - 0xd68c, 0x00c0, 0x2b7c, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, - 0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2b9b, - 0x6014, 0xa706, 0x00c0, 0x2b84, 0x60b8, 0x8001, 0x60ba, 0x00c0, - 0x2b7f, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, - 0x00c0, 0x2aa1, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, - 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, - 0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002, - 0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010, - 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, - 0x601a, 0x0078, 0x2bc4, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, - 0x0018, 0x0040, 0x2be0, 0xa184, 0x0010, 0x0040, 0x2bd3, 0x1078, - 0x3df6, 0x00c0, 0x2c05, 0xa184, 0x0008, 0x0040, 0x2be0, 0x69a0, - 0xa184, 0x0600, 0x00c0, 0x2be0, 0x1078, 0x3cda, 0x0078, 0x2c05, - 0x69a0, 0xa184, 0x1e00, 0x0040, 0x2c10, 0xa184, 0x0800, 0x0040, - 0x2bf9, 0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, - 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x1078, 0x3df6, 0x00c0, 0x2c05, - 0x69a0, 0xa184, 0x0200, 0x0040, 0x2c01, 0x1078, 0x3d3a, 0x0078, - 0x2c05, 0xa184, 0x0400, 0x00c0, 0x2bdc, 0x69a0, 0xa184, 0x1000, - 0x0040, 0x2c10, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x2749, - 0x027f, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2c1d, 0xa086, - 0x0060, 0x00c0, 0x2c1d, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, - 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, - 0x0040, 0x2c38, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, - 0x2c36, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, - 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, - 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, - 0x2898, 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2c70, 0x70d4, 0xc0b5, - 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, - 0x7882, 0xa286, 0x0002, 0x0040, 0x2ca6, 0x70a4, 0x8000, 0x70a6, - 0x74b4, 0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2c68, 0x73a8, - 0x73b6, 0xa286, 0x0010, 0x0040, 0x2942, 0x0d7f, 0x0c7f, 0x007c, - 0x7000, 0xa005, 0x00c0, 0x2c4e, 0xa286, 0x0002, 0x00c0, 0x2cc0, - 0x1078, 0x411c, 0x00c0, 0x2c4e, 0x6814, 0xc0fc, 0x8007, 0x7882, - 0x2091, 0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, - 0x780a, 0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, - 0x0c7f, 0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, - 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, - 0x0040, 0x2cb2, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, - 0x8000, 0x2090, 0x70a4, 0xa005, 0x00c0, 0x2cb7, 0x007c, 0x8421, - 0x0040, 0x2cb6, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2aa1, - 0xa286, 0x0010, 0x00c0, 0x2cf1, 0x1078, 0x411c, 0x00c0, 0x2c4e, - 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, - 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, - 0x780a, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, - 0xa206, 0x00c0, 0x2ce4, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, - 0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, - 0x007c, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, - 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, - 0x005b, 0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, - 0xa605, 0x0040, 0x2d1c, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, - 0x00c0, 0x2d16, 0x2009, 0x0000, 0x0078, 0x2d18, 0x2009, 0x0001, - 0xa284, 0x000f, 0x1079, 0x2d20, 0xad80, 0x0009, 0x7046, 0x007c, - 0x2d28, 0x45f7, 0x45f7, 0x45e4, 0x45f7, 0x2d28, 0x2d28, 0x2d28, - 0x1078, 0x28ec, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079, - 0x4a00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2d4e, 0x7064, 0xa086, - 0x0001, 0x00c0, 0x2d3e, 0x7066, 0x0078, 0x2e27, 0x7064, 0xa086, - 0x0005, 0x00c0, 0x2d4c, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, - 0x0000, 0x6820, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000, - 0x70a8, 0x70b2, 0x70b6, 0x70d4, 0xd0b4, 0x0040, 0x2d64, 0xc0b4, + 0x2001, 0x0010, 0x0078, 0x2c2c, 0x7060, 0xa005, 0x00c0, 0x2962, + 0x0c7e, 0x0d7e, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, + 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, + 0xa05d, 0xa886, 0x0001, 0x0040, 0x29c8, 0x69bc, 0x7daa, 0x79aa, + 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2c2c, 0x1078, + 0x42e9, 0x00c0, 0x2962, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, + 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, + 0xc08d, 0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, + 0x68c0, 0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, + 0x7046, 0x007c, 0x1078, 0x42e9, 0x00c0, 0x29fa, 0x781b, 0x0047, + 0x7003, 0x0004, 0x007c, 0x1078, 0x42e9, 0x00c0, 0x2a05, 0x2011, + 0x000c, 0x1078, 0x2a2c, 0x7003, 0x0004, 0x007c, 0x1078, 0x42e9, + 0x00c0, 0x2a10, 0x2011, 0x0006, 0x1078, 0x2a2c, 0x7003, 0x0004, + 0x007c, 0x1078, 0x42e9, 0x00c0, 0x2a1b, 0x2011, 0x000d, 0x1078, + 0x2a2c, 0x7003, 0x0004, 0x007c, 0x1078, 0x42e9, 0x00c0, 0x2a2b, + 0x2011, 0x0006, 0x1078, 0x2a2c, 0x707c, 0x707f, 0x0000, 0x2068, + 0x704e, 0x7003, 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, + 0x789b, 0x0010, 0xa286, 0x000c, 0x00c0, 0x2a3b, 0x7aaa, 0x2001, + 0x0001, 0x0078, 0x2a50, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, + 0xa286, 0x000d, 0x0040, 0x2a49, 0x7aaa, 0x2001, 0x0002, 0x0078, + 0x2a50, 0x78ab, 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, + 0x789b, 0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0110, 0x1078, + 0x42fe, 0x7083, 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2a6c, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x6018, 0x8001, 0x601a, 0x0c7f, 0x157e, 0x2011, 0x0004, 0x7164, - 0xa186, 0x0001, 0x0040, 0x2d7d, 0xa186, 0x0007, 0x00c0, 0x2d74, - 0x701f, 0x0005, 0x0078, 0x2d7d, 0x701f, 0x0001, 0x7067, 0x0000, - 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x2d7f, 0x7067, 0x0000, 0x2001, - 0x4a0a, 0x2004, 0xa084, 0x00ff, 0xa086, 0x0018, 0x0040, 0x2d8f, - 0x7018, 0x7016, 0xa005, 0x00c0, 0x2d8f, 0x70a7, 0x0001, 0x1078, - 0x4326, 0x20a9, 0x0010, 0x2039, 0x0000, 0x1078, 0x3edb, 0xa7b8, - 0x0100, 0x00f0, 0x2d95, 0x7000, 0x0079, 0x2d9e, 0x2dcd, 0x2db3, - 0x2db3, 0x2da8, 0x2dcd, 0x2dcd, 0x2dcd, 0x2da6, 0x1078, 0x28ec, - 0x7060, 0xa005, 0x0040, 0x2dcd, 0xad06, 0x00c0, 0x2db3, 0x6800, - 0x7062, 0x0078, 0x2dc5, 0x6820, 0xd084, 0x00c0, 0x2dc1, 0x6f14, - 0x1078, 0x3fe1, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bb5, 0x0078, - 0x2dc5, 0x705c, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, - 0x6820, 0xc09d, 0x6822, 0x1078, 0x202a, 0xb284, 0x0400, 0x0040, - 0x2dd5, 0x2021, 0x91d0, 0x0078, 0x2dd7, 0x2021, 0x90c0, 0x1078, - 0x2e2c, 0xb284, 0x0400, 0x0040, 0x2de1, 0x2021, 0x4a98, 0x0078, - 0x2de3, 0x2021, 0x4a58, 0x1078, 0x2e2c, 0x20a9, 0x0101, 0xb284, - 0x0400, 0x0040, 0x2def, 0x2021, 0x90d0, 0x0078, 0x2df1, 0x2021, - 0x8fc0, 0x1078, 0x2e2c, 0x8420, 0x00f0, 0x2df1, 0xb284, 0x0300, - 0x0040, 0x2dfe, 0x2061, 0x4fc0, 0x0078, 0x2e00, 0x2061, 0x6fc0, - 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040, 0x2e1d, - 0x6018, 0x017e, 0x007e, 0x2011, 0x4a02, 0x220c, 0xa102, 0x2012, - 0x007f, 0x017f, 0xa102, 0x0050, 0x2e1d, 0x6012, 0x00c0, 0x2e1d, - 0x2011, 0x4a04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000, 0xace0, - 0x0010, 0x00f0, 0x2e04, 0x8421, 0x00c0, 0x2e02, 0x157f, 0x7003, - 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005, 0x0040, - 0x2e3f, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820, - 0xc09d, 0x6822, 0x1078, 0x202a, 0x007f, 0x0078, 0x2e2e, 0x047f, - 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2e49, 0x1078, - 0x28ec, 0x2300, 0x0079, 0x2e4c, 0x2e4f, 0x2eda, 0x2ef7, 0xa282, - 0x0002, 0x0040, 0x2e55, 0x1078, 0x28ec, 0x7064, 0x7067, 0x0000, - 0x7083, 0x0000, 0x0079, 0x2e5c, 0x2e64, 0x2e64, 0x2e66, 0x2ea6, - 0x3bf1, 0x2e64, 0x2ea6, 0x2e64, 0x1078, 0x28ec, 0x7774, 0x1078, - 0x3edb, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x3fe1, 0x6018, 0xa005, - 0x0040, 0x2e9d, 0xd7fc, 0x00c0, 0x2e79, 0x2021, 0x90c0, 0x0078, - 0x2e7b, 0x2021, 0x91d0, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, - 0x2f12, 0x0040, 0x2e9d, 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, - 0x2e8d, 0x2021, 0x8fc0, 0x0078, 0x2e8f, 0x2021, 0x90d0, 0x047e, - 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2f12, 0x047f, 0x0040, - 0x2e9c, 0x8420, 0x00f0, 0x2e8f, 0x157f, 0x8738, 0xa784, 0x001f, - 0x00c0, 0x2e6c, 0x0078, 0x2946, 0x0078, 0x2946, 0x7774, 0x1078, - 0x3fe1, 0x6018, 0xa005, 0x0040, 0x2ed8, 0xd7fc, 0x00c0, 0x2eb4, - 0x2021, 0x90c0, 0x0078, 0x2eb6, 0x2021, 0x91d0, 0x2009, 0x0005, - 0x2011, 0x0020, 0x1078, 0x2f12, 0x0040, 0x2ed8, 0x157e, 0x20a9, - 0x0101, 0xd7fc, 0x00c0, 0x2ec8, 0x2021, 0x8fc0, 0x0078, 0x2eca, - 0x2021, 0x90d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, - 0x2f12, 0x047f, 0x0040, 0x2ed7, 0x8420, 0x00f0, 0x2eca, 0x157f, - 0x0078, 0x2946, 0x2200, 0x0079, 0x2edd, 0x2ee0, 0x2ee2, 0x2ee2, - 0x1078, 0x28ec, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0040, - 0x2eeb, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2ef0, 0x691a, - 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x40c9, 0x2200, - 0x0079, 0x2efa, 0x2eff, 0x2ee2, 0x2efd, 0x1078, 0x28ec, 0x1078, - 0x4326, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b7a, 0x1078, 0x3bd2, - 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, 0x3b7a, - 0x0078, 0x2946, 0x2404, 0xa005, 0x0040, 0x2f41, 0x2068, 0x2d04, - 0x007e, 0x6814, 0xa706, 0x0040, 0x2f21, 0x2d20, 0x007f, 0x0078, - 0x2f13, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, - 0x6822, 0x1078, 0x202a, 0x2021, 0x4a02, 0x241c, 0x8319, 0x2322, - 0x6010, 0x8001, 0x6012, 0x00c0, 0x2f3a, 0x2021, 0x4a04, 0x2404, - 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078, 0x3bd2, - 0x007c, 0xa085, 0x0001, 0x0078, 0x2f40, 0x2300, 0x0079, 0x2f48, - 0x2f4d, 0x2f4b, 0x2fce, 0x1078, 0x28ec, 0x78e4, 0xa005, 0x00d0, - 0x2f84, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, - 0x0040, 0x2f5e, 0xa18c, 0x0300, 0x0078, 0x2f60, 0xa18c, 0x0400, - 0x0040, 0x2f66, 0x0018, 0x2942, 0x0078, 0x2f68, 0x0028, 0x2942, - 0x2008, 0xa084, 0x0030, 0x00c0, 0x2f70, 0x781b, 0x005b, 0x007c, - 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f6d, 0x2100, 0xa084, 0x0007, - 0x0079, 0x2f7a, 0x2fae, 0x2fb8, 0x2fa3, 0x2f82, 0x4111, 0x4111, - 0x2f82, 0x2fc3, 0x1078, 0x28ec, 0x7000, 0xa086, 0x0004, 0x00c0, - 0x2f9e, 0x7064, 0xa086, 0x0002, 0x00c0, 0x2f94, 0x2011, 0x0002, - 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, 0xa086, 0x0006, 0x0040, - 0x2f8e, 0x7064, 0xa086, 0x0004, 0x0040, 0x2f8e, 0x79e4, 0x2001, - 0x0003, 0x0078, 0x3304, 0x6818, 0xd0fc, 0x0040, 0x2fa9, 0x681b, - 0x001d, 0x1078, 0x3eae, 0x781b, 0x0061, 0x007c, 0x6818, 0xd0fc, - 0x0040, 0x2fb4, 0x681b, 0x001d, 0x1078, 0x3eae, 0x0078, 0x40ed, - 0x6818, 0xd0fc, 0x0040, 0x2fbe, 0x681b, 0x001d, 0x1078, 0x3eae, - 0x781b, 0x00ef, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x2fc9, 0x681b, - 0x001d, 0x1078, 0x3eae, 0x781b, 0x00bf, 0x007c, 0xa584, 0x000f, - 0x00c0, 0x2feb, 0x7000, 0x0079, 0x2fd5, 0x2946, 0x2fdd, 0x2fdf, - 0x3b7a, 0x3b7a, 0x3b7a, 0x2fdd, 0x2fdd, 0x1078, 0x28ec, 0x1078, - 0x3bd2, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, - 0x3b7a, 0x0078, 0x2946, 0x78e4, 0xa005, 0x00d0, 0x2f84, 0x3208, - 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2ffc, - 0xa18c, 0x0300, 0x0078, 0x2ffe, 0xa18c, 0x0400, 0x0040, 0x3004, - 0x0018, 0x2f84, 0x0078, 0x3006, 0x0028, 0x2f84, 0x2008, 0xa084, - 0x0030, 0x00c0, 0x300e, 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, - 0x0003, 0x0040, 0x300b, 0x2100, 0xa184, 0x0007, 0x0079, 0x3018, - 0x3027, 0x302b, 0x3022, 0x3020, 0x4111, 0x4111, 0x3020, 0x410b, - 0x1078, 0x28ec, 0x1078, 0x3eb6, 0x781b, 0x0061, 0x007c, 0x1078, - 0x3eb6, 0x0078, 0x40ed, 0x1078, 0x3eb6, 0x781b, 0x00ef, 0x007c, - 0x1078, 0x3eb6, 0x781b, 0x00bf, 0x007c, 0x2300, 0x0079, 0x3038, - 0x303d, 0x303b, 0x303f, 0x1078, 0x28ec, 0x0078, 0x37bd, 0x681b, - 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x37bd, - 0x78ec, 0xa084, 0x0003, 0x0040, 0x37bd, 0xa184, 0x0100, 0x0040, - 0x3043, 0xa184, 0x0007, 0x0079, 0x3055, 0x305d, 0x302b, 0x2fa3, - 0x40c9, 0x4111, 0x4111, 0x40c9, 0x410b, 0x1078, 0x40d5, 0x007c, - 0xa282, 0x0005, 0x0050, 0x3066, 0x1078, 0x28ec, 0x2300, 0x0079, - 0x3069, 0x306c, 0x328b, 0x3296, 0x2200, 0x0079, 0x306f, 0x3089, - 0x3076, 0x3089, 0x3074, 0x326e, 0x1078, 0x28ec, 0x789b, 0x0018, - 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x3e9d, 0xa08a, - 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3085, 0x3e9d, 0x3e9d, 0x3e9d, - 0x3e47, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x309a, - 0x0078, 0x3e9d, 0x7000, 0xa005, 0x00c0, 0x3090, 0x2011, 0x0004, - 0x0078, 0x3998, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x3e9d, - 0x0079, 0x30a2, 0x30b4, 0x30b2, 0x30c9, 0x30cd, 0x318f, 0x3e9d, - 0x3e9d, 0x3191, 0x3e9d, 0x3e9d, 0x326a, 0x326a, 0x3e9d, 0x3e9d, - 0x3e9d, 0x326c, 0x1078, 0x28ec, 0xd6e4, 0x0040, 0x30bf, 0x2001, - 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00ba, 0x007c, 0x6818, - 0xd0fc, 0x0040, 0x30c7, 0x681b, 0x001d, 0x0078, 0x30b7, 0x0078, - 0x40c9, 0x681b, 0x001d, 0x0078, 0x3ea7, 0x6920, 0x6922, 0xa684, - 0x1800, 0x00c0, 0x3121, 0x6820, 0xd084, 0x00c0, 0x3127, 0x6818, - 0xa086, 0x0008, 0x00c0, 0x30de, 0x681b, 0x0000, 0xd6d4, 0x0040, - 0x318c, 0xd6bc, 0x0040, 0x311e, 0x7087, 0x0000, 0x6818, 0xa084, - 0x003f, 0xa08a, 0x000d, 0x0050, 0x311e, 0xa08a, 0x000c, 0x7186, + 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, + 0x2a7b, 0x70d4, 0xd0b4, 0x0040, 0x2a7c, 0x70b8, 0xac06, 0x00c0, + 0x2a7c, 0x1078, 0x2a5b, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, + 0x0040, 0x2aae, 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, + 0x70b4, 0x2068, 0x6800, 0xac06, 0x0040, 0x2a95, 0x8211, 0x0040, + 0x2aac, 0x1078, 0x2ab0, 0x0078, 0x2a8a, 0x0c7e, 0x2100, 0x2011, + 0x0001, 0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x8211, 0x0040, 0x2aa9, 0x1078, 0x2ab0, 0x0078, + 0x2a9c, 0x70a7, 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, + 0xade8, 0x0005, 0x70ac, 0xad06, 0x00c0, 0x2ab8, 0x70a8, 0x2068, + 0x007c, 0x1078, 0x42e9, 0x00c0, 0x2962, 0x707c, 0x2068, 0x7774, + 0x1078, 0x4187, 0x2c50, 0x1078, 0x43bd, 0x789b, 0x0010, 0x6814, + 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, + 0x0004, 0x0078, 0x2c32, 0x1078, 0x42e9, 0x00c0, 0x2962, 0x789b, + 0x0010, 0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2aed, + 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, + 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x4187, 0x2c50, + 0x1078, 0x43bd, 0x6824, 0xa005, 0x0040, 0x2afe, 0xa082, 0x0006, + 0x0048, 0x2afc, 0x0078, 0x2afe, 0x6827, 0x0005, 0x6814, 0xa084, + 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, + 0x0003, 0x0078, 0x2c32, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, + 0x7154, 0x8108, 0xa12a, 0x0048, 0x2b16, 0x71c0, 0x2164, 0x6504, + 0x85ff, 0x00c0, 0x2b2d, 0x7156, 0x8421, 0x00c0, 0x2b11, 0x70d4, + 0xd08c, 0x0040, 0x2b29, 0x70d0, 0xa005, 0x00c0, 0x2b29, 0x70d3, + 0x000a, 0x007c, 0x2200, 0x0078, 0x2b1b, 0x70d4, 0xc08c, 0x70d6, + 0x70d3, 0x0000, 0x6034, 0xa005, 0x00c0, 0x2b2a, 0x6708, 0xa784, + 0x073f, 0x0040, 0x2b5c, 0xd7d4, 0x00c0, 0x2b2a, 0xa784, 0x0021, + 0x00c0, 0x2b2a, 0xa784, 0x0002, 0x0040, 0x2b4d, 0xa784, 0x0004, + 0x0040, 0x2b2a, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, + 0x2b2a, 0xa784, 0x0100, 0x0040, 0x2b5c, 0x6018, 0xa005, 0x00c0, + 0x2b2a, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, + 0xa684, 0x000e, 0x6318, 0x0040, 0x2b6d, 0x601c, 0xa302, 0x0048, + 0x2b70, 0x0040, 0x2b70, 0x0078, 0x2b2a, 0x83ff, 0x00c0, 0x2b2a, + 0x2d58, 0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2b78, 0x7028, 0x6022, + 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, + 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040, + 0x2b8c, 0xd684, 0x0040, 0x2b8e, 0xa39c, 0xffbf, 0xd6a4, 0x0040, + 0x2b93, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2bde, 0xc7a5, + 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2bb2, + 0x70d4, 0xd0b4, 0x00c0, 0x2bb2, 0x7000, 0xa082, 0x0002, 0x00c8, + 0x2bb2, 0x7830, 0xd0bc, 0x00c0, 0x2bb2, 0x789b, 0x0010, 0x7baa, + 0x0078, 0x2c2a, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, + 0x70ac, 0xa606, 0x00c0, 0x2bbd, 0x76a8, 0x76b2, 0x2c3a, 0x8738, + 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, + 0xd0bc, 0x0040, 0x2bd5, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4, + 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040, + 0x2bdd, 0x8421, 0x2200, 0x00c0, 0x2b10, 0x007c, 0xd1dc, 0x0040, + 0x3d86, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2beb, 0x8528, 0xd68c, + 0x00c0, 0x2beb, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, + 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2c0a, 0x6014, + 0xa706, 0x00c0, 0x2bf3, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2bee, + 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0, + 0x2b10, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, + 0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2bb2, + 0x70d4, 0xd0b4, 0x00c0, 0x2bb2, 0x7000, 0xa082, 0x0002, 0x00c8, + 0x2bb2, 0x7830, 0xd0bc, 0x00c0, 0x2bb2, 0x789b, 0x0010, 0x7baa, + 0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a, + 0x0078, 0x2c33, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018, + 0x0040, 0x2c4f, 0xa184, 0x0010, 0x0040, 0x2c42, 0x1078, 0x3f99, + 0x00c0, 0x2c74, 0xa184, 0x0008, 0x0040, 0x2c4f, 0x69a0, 0xa184, + 0x0600, 0x00c0, 0x2c4f, 0x1078, 0x3e7c, 0x0078, 0x2c74, 0x69a0, + 0xa184, 0x1e00, 0x0040, 0x2c7f, 0xa184, 0x0800, 0x0040, 0x2c68, + 0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, + 0x0010, 0x6106, 0x0c7f, 0x1078, 0x3f99, 0x00c0, 0x2c74, 0x69a0, + 0xa184, 0x0200, 0x0040, 0x2c70, 0x1078, 0x3edc, 0x0078, 0x2c74, + 0xa184, 0x0400, 0x00c0, 0x2c4b, 0x69a0, 0xa184, 0x1000, 0x0040, + 0x2c7f, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x2755, 0x027f, + 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2c8c, 0xa086, 0x0060, + 0x00c0, 0x2c8c, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, + 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040, + 0x2ca7, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2ca5, + 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, + 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, + 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, + 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2cdf, 0x70d4, 0xc0b5, 0x70d6, + 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0xa286, 0x0002, 0x0040, 0x2d15, 0x70a4, 0x8000, 0x70a6, 0x74b4, + 0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2cd7, 0x73a8, 0x73b6, + 0xa286, 0x0010, 0x0040, 0x2962, 0x0d7f, 0x0c7f, 0x007c, 0x7000, + 0xa005, 0x00c0, 0x2cbd, 0xa286, 0x0002, 0x00c0, 0x2d2f, 0x1078, + 0x42e9, 0x00c0, 0x2cbd, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, + 0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, + 0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f, + 0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, + 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040, + 0x2d21, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, + 0x2090, 0x70a4, 0xa005, 0x00c0, 0x2d26, 0x007c, 0x8421, 0x0040, + 0x2d25, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2b10, 0xa286, + 0x0010, 0x00c0, 0x2d60, 0x1078, 0x42e9, 0x00c0, 0x2cbd, 0x6814, + 0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, + 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, + 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, + 0x00c0, 0x2d53, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, + 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, + 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, + 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b, + 0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, + 0x0040, 0x2d8b, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0, + 0x2d85, 0x2009, 0x0000, 0x0078, 0x2d87, 0x2009, 0x0001, 0xa284, + 0x000f, 0x1079, 0x2d8f, 0xad80, 0x0009, 0x7046, 0x007c, 0x2d97, + 0x4834, 0x4834, 0x4821, 0x4834, 0x2d97, 0x2d97, 0x2d97, 0x1078, + 0x290c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079, 0x4d00, + 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2dbf, 0x7064, 0xa086, 0x0001, + 0x00c0, 0x2dad, 0x7066, 0x0078, 0x2e96, 0x7064, 0xa086, 0x0005, + 0x00c0, 0x2dbd, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, 0x0000, + 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, + 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078, 0x2a5b, 0x157e, 0x2011, + 0x0004, 0x7164, 0xa186, 0x0001, 0x0040, 0x2ddf, 0xa186, 0x0007, + 0x00c0, 0x2dd6, 0x701f, 0x0005, 0x0078, 0x2ddf, 0x701f, 0x0001, + 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x2de1, 0x7067, + 0x0000, 0x2001, 0x4d0a, 0x2004, 0xa084, 0x00ff, 0xa086, 0x0018, + 0x0040, 0x2df1, 0x7018, 0x7016, 0xa005, 0x00c0, 0x2df1, 0x70a7, + 0x0001, 0x067e, 0x1078, 0x44fb, 0x20a9, 0x0010, 0x2039, 0x0000, + 0x1078, 0x4081, 0xa7b8, 0x0100, 0x00f0, 0x2df8, 0x067f, 0x7000, + 0x0079, 0x2e02, 0x2e3c, 0x2e17, 0x2e17, 0x2e0c, 0x2e3c, 0x2e3c, + 0x2e3c, 0x2e0a, 0x1078, 0x290c, 0x7060, 0xa005, 0x0040, 0x2e3c, + 0xad06, 0x00c0, 0x2e17, 0x6800, 0x7062, 0x0078, 0x2e29, 0x6820, + 0xd084, 0x00c0, 0x2e25, 0x6f14, 0x1078, 0x4187, 0x6008, 0xc0d4, + 0x600a, 0x1078, 0x3d56, 0x0078, 0x2e29, 0x705c, 0x2060, 0x6800, + 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, 0x0040, 0x2e31, + 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, + 0xc09d, 0x6822, 0x1078, 0x2013, 0xb284, 0x0400, 0x0040, 0x2e44, + 0x2021, 0x94d0, 0x0078, 0x2e46, 0x2021, 0x93c0, 0x1078, 0x2e9b, + 0xb284, 0x0400, 0x0040, 0x2e50, 0x2021, 0x4d98, 0x0078, 0x2e52, + 0x2021, 0x4d58, 0x1078, 0x2e9b, 0x20a9, 0x0101, 0xb284, 0x0400, + 0x0040, 0x2e5e, 0x2021, 0x93d0, 0x0078, 0x2e60, 0x2021, 0x92c0, + 0x1078, 0x2e9b, 0x8420, 0x00f0, 0x2e60, 0xb284, 0x0300, 0x0040, + 0x2e6d, 0x2061, 0x52c0, 0x0078, 0x2e6f, 0x2061, 0x72c0, 0x2021, + 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040, 0x2e8c, 0x6018, + 0x017e, 0x007e, 0x2011, 0x4d02, 0x220c, 0xa102, 0x2012, 0x007f, + 0x017f, 0xa102, 0x0050, 0x2e8c, 0x6012, 0x00c0, 0x2e8c, 0x2011, + 0x4d04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000, 0xace0, 0x0010, + 0x00f0, 0x2e73, 0x8421, 0x00c0, 0x2e71, 0x157f, 0x7003, 0x0000, + 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005, 0x0040, 0x2eb6, + 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, + 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, 0xc09d, + 0x6822, 0x1078, 0x2013, 0x007f, 0x0078, 0x2e9d, 0x047f, 0x2023, + 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2ec0, 0x1078, 0x290c, + 0x2300, 0x0079, 0x2ec3, 0x2ec6, 0x2f51, 0x2f6e, 0xa282, 0x0002, + 0x0040, 0x2ecc, 0x1078, 0x290c, 0x7064, 0x7067, 0x0000, 0x7083, + 0x0000, 0x0079, 0x2ed3, 0x2edb, 0x2edb, 0x2edd, 0x2f1d, 0x3d92, + 0x2edb, 0x2f1d, 0x2edb, 0x1078, 0x290c, 0x7774, 0x1078, 0x4081, + 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x4187, 0x6018, 0xa005, 0x0040, + 0x2f14, 0xd7fc, 0x00c0, 0x2ef0, 0x2021, 0x93c0, 0x0078, 0x2ef2, + 0x2021, 0x94d0, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2f89, + 0x0040, 0x2f14, 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2f04, + 0x2021, 0x92c0, 0x0078, 0x2f06, 0x2021, 0x93d0, 0x047e, 0x2009, + 0x0005, 0x2011, 0x0010, 0x1078, 0x2f89, 0x047f, 0x0040, 0x2f13, + 0x8420, 0x00f0, 0x2f06, 0x157f, 0x8738, 0xa784, 0x001f, 0x00c0, + 0x2ee3, 0x0078, 0x2966, 0x0078, 0x2966, 0x7774, 0x1078, 0x4187, + 0x6018, 0xa005, 0x0040, 0x2f4f, 0xd7fc, 0x00c0, 0x2f2b, 0x2021, + 0x93c0, 0x0078, 0x2f2d, 0x2021, 0x94d0, 0x2009, 0x0005, 0x2011, + 0x0020, 0x1078, 0x2f89, 0x0040, 0x2f4f, 0x157e, 0x20a9, 0x0101, + 0xd7fc, 0x00c0, 0x2f3f, 0x2021, 0x92c0, 0x0078, 0x2f41, 0x2021, + 0x93d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x2f89, + 0x047f, 0x0040, 0x2f4e, 0x8420, 0x00f0, 0x2f41, 0x157f, 0x0078, + 0x2966, 0x2200, 0x0079, 0x2f54, 0x2f57, 0x2f59, 0x2f59, 0x1078, + 0x290c, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0040, 0x2f62, + 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2f67, 0x691a, 0x7067, + 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x4296, 0x2200, 0x0079, + 0x2f71, 0x2f76, 0x2f59, 0x2f74, 0x1078, 0x290c, 0x1078, 0x44fb, + 0x7000, 0xa086, 0x0002, 0x00c0, 0x3d04, 0x1078, 0x3d73, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x1078, 0x3cf5, 0x0040, 0x3d04, 0x0078, + 0x2966, 0x2404, 0xa005, 0x0040, 0x2fc2, 0x2068, 0x2d04, 0x007e, + 0x6814, 0xa706, 0x0040, 0x2f98, 0x2d20, 0x007f, 0x0078, 0x2f8a, + 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, + 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, 0xa205, 0x6822, + 0x1078, 0x2013, 0x2021, 0x4d02, 0x241c, 0x8319, 0x2322, 0x6010, + 0x8001, 0x6012, 0x00c0, 0x2fb9, 0x2021, 0x4d04, 0x2404, 0xc0a5, + 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078, 0x2a7c, 0x1078, + 0x3d73, 0x007c, 0xa085, 0x0001, 0x0078, 0x2fc1, 0x2300, 0x0079, + 0x2fc9, 0x2fce, 0x2fcc, 0x304e, 0x1078, 0x290c, 0x78e4, 0xa005, + 0x00d0, 0x3004, 0x3208, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x2fdf, 0xa18c, 0x0300, 0x0078, 0x2fe1, 0xa18c, + 0x0400, 0x0040, 0x2fe7, 0x0018, 0x2962, 0x0078, 0x2fe9, 0x0028, + 0x2962, 0x2008, 0xa084, 0x0030, 0x00c0, 0x2ff0, 0x0078, 0x36fb, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x2fee, 0x2100, 0xa084, 0x0007, + 0x0079, 0x2ffa, 0x302e, 0x3038, 0x3023, 0x3002, 0x42de, 0x42de, + 0x3002, 0x3043, 0x1078, 0x290c, 0x7000, 0xa086, 0x0004, 0x00c0, + 0x301e, 0x7064, 0xa086, 0x0002, 0x00c0, 0x3014, 0x2011, 0x0002, + 0x2019, 0x0000, 0x0078, 0x2eba, 0x7064, 0xa086, 0x0006, 0x0040, + 0x300e, 0x7064, 0xa086, 0x0004, 0x0040, 0x300e, 0x79e4, 0x2001, + 0x0003, 0x0078, 0x3385, 0x6818, 0xd0fc, 0x0040, 0x3029, 0x681b, + 0x001d, 0x1078, 0x4051, 0x781b, 0x0061, 0x007c, 0x6818, 0xd0fc, + 0x0040, 0x3034, 0x681b, 0x001d, 0x1078, 0x4051, 0x0078, 0x42ba, + 0x6818, 0xd0fc, 0x0040, 0x303e, 0x681b, 0x001d, 0x1078, 0x4051, + 0x781b, 0x00f5, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x3049, 0x681b, + 0x001d, 0x1078, 0x4051, 0x781b, 0x00c5, 0x007c, 0xa584, 0x000f, + 0x00c0, 0x306b, 0x7000, 0x0079, 0x3055, 0x2966, 0x305d, 0x305f, + 0x3d04, 0x3d04, 0x3d04, 0x305d, 0x305d, 0x1078, 0x290c, 0x1078, + 0x3d73, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3cf5, 0x0040, + 0x3d04, 0x0078, 0x2966, 0x78e4, 0xa005, 0x00d0, 0x3004, 0x3208, + 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x307c, + 0xa18c, 0x0300, 0x0078, 0x307e, 0xa18c, 0x0400, 0x0040, 0x3084, + 0x0018, 0x3004, 0x0078, 0x3086, 0x0028, 0x3004, 0x2008, 0xa084, + 0x0030, 0x00c0, 0x308e, 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, + 0x0003, 0x0040, 0x308b, 0x2100, 0xa184, 0x0007, 0x0079, 0x3098, + 0x30a7, 0x30ab, 0x30a2, 0x30a0, 0x42de, 0x42de, 0x30a0, 0x42d8, + 0x1078, 0x290c, 0x1078, 0x4059, 0x781b, 0x0061, 0x007c, 0x1078, + 0x4059, 0x0078, 0x42ba, 0x1078, 0x4059, 0x781b, 0x00f5, 0x007c, + 0x1078, 0x4059, 0x781b, 0x00c5, 0x007c, 0x2300, 0x0079, 0x30b8, + 0x30bd, 0x30bb, 0x30bf, 0x1078, 0x290c, 0x0078, 0x38cf, 0x681b, + 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x38cf, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x38cf, 0xa184, 0x0100, 0x0040, + 0x30c3, 0xa184, 0x0007, 0x0079, 0x30d5, 0x30dd, 0x30ab, 0x3023, + 0x4296, 0x42de, 0x42de, 0x4296, 0x42d8, 0x1078, 0x42a2, 0x007c, + 0xa282, 0x0005, 0x0050, 0x30e6, 0x1078, 0x290c, 0x2300, 0x0079, + 0x30e9, 0x30ec, 0x330b, 0x3316, 0x2200, 0x0079, 0x30ef, 0x3109, + 0x30f6, 0x3109, 0x30f4, 0x32ee, 0x1078, 0x290c, 0x789b, 0x0018, + 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x4040, 0xa08a, + 0x0004, 0x00c8, 0x4040, 0x0079, 0x3105, 0x4040, 0x4040, 0x4040, + 0x3fea, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x311a, + 0x0078, 0x4040, 0x7000, 0xa005, 0x00c0, 0x3110, 0x2011, 0x0004, + 0x0078, 0x3aba, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x4040, + 0x0079, 0x3122, 0x3134, 0x3132, 0x3149, 0x314d, 0x320f, 0x4040, + 0x4040, 0x3211, 0x4040, 0x4040, 0x32ea, 0x32ea, 0x4040, 0x4040, + 0x4040, 0x32ec, 0x1078, 0x290c, 0xd6e4, 0x0040, 0x313f, 0x2001, + 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00c0, 0x007c, 0x6818, + 0xd0fc, 0x0040, 0x3147, 0x681b, 0x001d, 0x0078, 0x3137, 0x0078, + 0x4296, 0x681b, 0x001d, 0x0078, 0x404a, 0x6920, 0x6922, 0xa684, + 0x1800, 0x00c0, 0x31a1, 0x6820, 0xd084, 0x00c0, 0x31a7, 0x6818, + 0xa086, 0x0008, 0x00c0, 0x315e, 0x681b, 0x0000, 0xd6d4, 0x0040, + 0x320c, 0xd6bc, 0x0040, 0x319e, 0x7087, 0x0000, 0x6818, 0xa084, + 0x003f, 0xa08a, 0x000d, 0x0050, 0x319e, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x789b, 0x0061, 0x78aa, 0x157e, - 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3110, - 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x310c, - 0x20a1, 0x012b, 0x0078, 0x3112, 0x20a1, 0x022b, 0x0078, 0x3112, + 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3190, + 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x318c, + 0x20a1, 0x012b, 0x0078, 0x3192, 0x20a1, 0x022b, 0x0078, 0x3192, 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b, 0x0064, - 0x007c, 0xd6e4, 0x0040, 0x3127, 0x781b, 0x0076, 0x007c, 0xa684, - 0x0060, 0x0040, 0x3189, 0xd6dc, 0x0040, 0x3189, 0xd6fc, 0x00c0, - 0x3133, 0x0078, 0x314a, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, - 0x78d0, 0x801b, 0x00c8, 0x313d, 0x8000, 0xa084, 0x003f, 0xa108, + 0x007c, 0xd6e4, 0x0040, 0x31a7, 0x781b, 0x0076, 0x007c, 0xa684, + 0x0060, 0x0040, 0x3209, 0xd6dc, 0x0040, 0x3209, 0xd6fc, 0x00c0, + 0x31b3, 0x0078, 0x31ca, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, + 0x78d0, 0x801b, 0x00c8, 0x31bd, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, - 0xa303, 0x68ae, 0xd6f4, 0x0040, 0x3150, 0xc6f4, 0x7e5a, 0x6eb6, - 0x7000, 0xa086, 0x0003, 0x00c0, 0x315e, 0x007e, 0x1078, 0x4326, - 0x1078, 0x45f7, 0x007f, 0x781b, 0x0073, 0x007c, 0xa006, 0x1078, - 0x46e5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, - 0x316d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, - 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x317d, 0xc6f5, + 0xa303, 0x68ae, 0xd6f4, 0x0040, 0x31d0, 0xc6f4, 0x7e5a, 0x6eb6, + 0x7000, 0xa086, 0x0003, 0x00c0, 0x31de, 0x007e, 0x1078, 0x44fb, + 0x1078, 0x4834, 0x007f, 0x781b, 0x0073, 0x007c, 0xa006, 0x1078, + 0x493a, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, + 0x31ed, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, + 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x31fd, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0073, 0x007c, 0x781b, 0x0073, 0x2200, - 0xa115, 0x00c0, 0x3186, 0x1078, 0x45f7, 0x007c, 0x1078, 0x462d, + 0xa115, 0x00c0, 0x3206, 0x1078, 0x4834, 0x007c, 0x1078, 0x486c, 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0064, 0x007c, 0x1078, - 0x28ec, 0x0078, 0x31dd, 0x6920, 0xd1c4, 0x0040, 0x31a6, 0xc1c4, + 0x290c, 0x0078, 0x325d, 0x6920, 0xd1c4, 0x0040, 0x3226, 0xc1c4, 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, - 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x31d1, 0xd1cc, 0x0040, - 0x31d1, 0xc1cc, 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, + 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x3251, 0xd1cc, 0x0040, + 0x3251, 0xc1cc, 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004, 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, - 0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, - 0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, - 0xd6d4, 0x00c0, 0x31ce, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, - 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x31d8, 0x781b, 0x0064, 0x007c, - 0x781b, 0x0076, 0x007c, 0x0078, 0x3ea2, 0x2019, 0x0000, 0x7990, - 0xa18c, 0x0007, 0x00c0, 0x31eb, 0x6820, 0xa084, 0x0100, 0x0040, - 0x31db, 0x2009, 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, - 0xa286, 0x0001, 0x00c0, 0x3207, 0x2300, 0x7ca8, 0xa400, 0x2018, - 0xa102, 0x0040, 0x31ff, 0x0048, 0x31ff, 0x0078, 0x3201, 0x0078, - 0x3193, 0x24a8, 0x7aa8, 0x00f0, 0x3201, 0x0078, 0x31ed, 0xa284, - 0x00f0, 0xa086, 0x0020, 0x00c0, 0x325b, 0x8318, 0x8318, 0x2300, - 0xa102, 0x0040, 0x3217, 0x0048, 0x3217, 0x0078, 0x3258, 0xa286, - 0x0023, 0x0040, 0x31db, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, + 0x0040, 0x3251, 0x1078, 0x4183, 0x1078, 0x3e7c, 0x88ff, 0x0040, + 0x3251, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, + 0xd6d4, 0x00c0, 0x324e, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, + 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x3258, 0x781b, 0x0064, 0x007c, + 0x781b, 0x0076, 0x007c, 0x0078, 0x4045, 0x2019, 0x0000, 0x7990, + 0xa18c, 0x0007, 0x00c0, 0x326b, 0x6820, 0xa084, 0x0100, 0x0040, + 0x325b, 0x2009, 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, + 0xa286, 0x0001, 0x00c0, 0x3287, 0x2300, 0x7ca8, 0xa400, 0x2018, + 0xa102, 0x0040, 0x327f, 0x0048, 0x327f, 0x0078, 0x3281, 0x0078, + 0x3213, 0x24a8, 0x7aa8, 0x00f0, 0x3281, 0x0078, 0x326d, 0xa284, + 0x00f0, 0xa086, 0x0020, 0x00c0, 0x32db, 0x8318, 0x8318, 0x2300, + 0xa102, 0x0040, 0x3297, 0x0048, 0x3297, 0x0078, 0x32d8, 0xa286, + 0x0023, 0x0040, 0x325b, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, - 0x0040, 0x3238, 0x1078, 0x3fdd, 0x1078, 0x3df6, 0x0078, 0x3246, + 0x0040, 0x32b8, 0x1078, 0x4183, 0x1078, 0x3f99, 0x0078, 0x32c6, 0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, - 0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, - 0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, - 0x00c0, 0x3255, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, - 0x7aa8, 0x0078, 0x31ed, 0x8318, 0x2300, 0xa102, 0x0040, 0x3264, - 0x0048, 0x3264, 0x0078, 0x31ed, 0xa284, 0x0080, 0x00c0, 0x3ea7, - 0x0078, 0x3ea2, 0x0078, 0x3ea7, 0x0078, 0x3e9d, 0x7058, 0xa04d, + 0x0040, 0x3251, 0x1078, 0x4183, 0x1078, 0x3e7c, 0x88ff, 0x0040, + 0x3251, 0x789b, 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, + 0x00c0, 0x32d5, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, + 0x7aa8, 0x0078, 0x326d, 0x8318, 0x2300, 0xa102, 0x0040, 0x32e4, + 0x0048, 0x32e4, 0x0078, 0x326d, 0xa284, 0x0080, 0x00c0, 0x404a, + 0x0078, 0x4045, 0x0078, 0x404a, 0x0078, 0x4040, 0x7058, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, - 0x327b, 0x1078, 0x28ec, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, - 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3287, 0x3e9d, - 0x3c2c, 0x3e9d, 0x3d9e, 0xa282, 0x0000, 0x00c0, 0x3291, 0x1078, - 0x28ec, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0xa282, 0x0003, - 0x00c0, 0x329c, 0x1078, 0x28ec, 0xd4fc, 0x00c0, 0x32bc, 0x7064, - 0xa005, 0x0040, 0x32a5, 0x1078, 0x28ec, 0x6f14, 0x7776, 0xa7bc, - 0x8f00, 0x1078, 0x3fe1, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, - 0xa784, 0x001f, 0x00c0, 0x32a9, 0x1078, 0x3eb2, 0x7067, 0x0002, - 0x701f, 0x0009, 0x0078, 0x32be, 0x1078, 0x3ebe, 0x781b, 0x0075, - 0x007c, 0xa282, 0x0004, 0x0050, 0x32c7, 0x1078, 0x28ec, 0x2300, - 0x0079, 0x32ca, 0x32cd, 0x346b, 0x34ae, 0xa286, 0x0003, 0x0040, - 0x3304, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x0078, - 0x32fc, 0x0040, 0x32fc, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x32fc, - 0xa282, 0x0002, 0x00c8, 0x32fc, 0x0d7e, 0x783b, 0x8300, 0x781b, - 0x004c, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, - 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, - 0x2001, 0x0000, 0x0078, 0x3308, 0x783b, 0x1300, 0x781b, 0x004a, - 0x2001, 0x0000, 0x0078, 0x3308, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, - 0x704a, 0x68a0, 0xd0ec, 0x0040, 0x3310, 0x6008, 0xc08d, 0x600a, - 0xa284, 0x000f, 0x0079, 0x3314, 0x344b, 0x3321, 0x331e, 0x35ae, - 0x35f2, 0x2946, 0x331c, 0x331c, 0x1078, 0x28ec, 0x6008, 0xc0d4, - 0x600a, 0xd6e4, 0x00c0, 0x3328, 0x1078, 0x4326, 0x0040, 0x3404, - 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3369, 0xa186, 0x0008, 0x00c0, - 0x333e, 0x1078, 0x3bd2, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3b6b, - 0x0040, 0x3369, 0x1078, 0x4326, 0x0078, 0x3353, 0xa186, 0x0028, - 0x00c0, 0x3369, 0x1078, 0x4326, 0x6008, 0xc0a4, 0x600a, 0x6018, - 0xa005, 0x0040, 0x3353, 0x8001, 0x601a, 0x0040, 0x3353, 0x8001, - 0x0040, 0x3353, 0x601e, 0x6820, 0xd084, 0x0040, 0x2946, 0xc084, - 0x6822, 0x705c, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, - 0x6802, 0xa005, 0x2d00, 0x00c0, 0x3366, 0x6002, 0x6006, 0x0078, - 0x2946, 0x017e, 0x81ff, 0x00c0, 0x33b0, 0x7000, 0xa086, 0x0030, - 0x0040, 0x33b0, 0x71d4, 0xd1b4, 0x00c0, 0x3397, 0x7060, 0xa005, - 0x00c0, 0x33b0, 0x70a4, 0xa086, 0x0001, 0x0040, 0x33b0, 0x7003, - 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e, 0x1078, - 0x296c, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4, - 0xd1b4, 0x00c0, 0x33b0, 0x7003, 0x0040, 0x0078, 0x33b0, 0x1078, - 0x411c, 0x00c0, 0x33b0, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d, - 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, - 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x0d7f, - 0x1078, 0x34e8, 0x017f, 0x81ff, 0x0040, 0x3403, 0xa684, 0xdf00, - 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x3404, - 0x70d4, 0xd0b4, 0x0040, 0x33d1, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x6820, 0xd0dc, 0x00c0, 0x3404, 0x8717, 0xa294, 0x000f, - 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x33e3, 0xa290, - 0x4ec0, 0x0078, 0x33e5, 0xa290, 0x4f40, 0xa290, 0x0000, 0x221c, - 0xd3c4, 0x00c0, 0x33ed, 0x0078, 0x33f3, 0x8210, 0x2204, 0xa085, - 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x33fe, 0x68a0, 0xd0c4, - 0x00c0, 0x33fe, 0x1078, 0x3562, 0x0078, 0x2946, 0x6008, 0xc08d, - 0x600a, 0x0078, 0x3404, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, - 0x340b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, - 0x0040, 0x3420, 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, - 0x6412, 0x00c0, 0x3420, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, - 0x6018, 0xa005, 0x0040, 0x3428, 0x8001, 0x601a, 0x00c0, 0x342b, - 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3437, 0x6800, - 0xa005, 0x00c0, 0x3434, 0x6002, 0x6006, 0x0078, 0x343b, 0x705c, - 0x2060, 0x6800, 0x6002, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08, - 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x344a, 0x2d02, - 0x0078, 0x344b, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x345b, - 0xa286, 0x0040, 0x00c0, 0x2946, 0x7003, 0x0002, 0x704c, 0x2068, - 0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, - 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, - 0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3471, 0x1078, - 0x28ec, 0x2200, 0x0079, 0x3474, 0x3478, 0x3489, 0x3496, 0x3489, - 0xa586, 0x1300, 0x0040, 0x3489, 0xa586, 0x8300, 0x00c0, 0x346f, - 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x3493, 0x1078, 0x3eae, - 0x781b, 0x0075, 0x007c, 0x781b, 0x0076, 0x007c, 0x7890, 0x8007, - 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, - 0x00ff, 0xa186, 0x0003, 0x0040, 0x34ab, 0xa186, 0x0000, 0x0040, - 0x34ab, 0x0078, 0x3e9d, 0x781b, 0x0076, 0x007c, 0x6820, 0xc095, - 0x6822, 0x82ff, 0x00c0, 0x34b8, 0x1078, 0x3eae, 0x0078, 0x34bf, - 0x8211, 0x0040, 0x34bd, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, - 0x0075, 0x007c, 0x1078, 0x4131, 0x7830, 0xa084, 0x00c0, 0x00c0, - 0x34e5, 0x017e, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x007f, 0x0040, 0x34d7, 0xa18c, 0x0300, 0x0078, 0x34d9, 0xa18c, - 0x0400, 0x017f, 0x0040, 0x34e0, 0x0018, 0x34e5, 0x0078, 0x34e2, - 0x0028, 0x34e5, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, - 0xa684, 0x0060, 0x00c0, 0x34f2, 0x682f, 0x0000, 0x6833, 0x0000, - 0x0078, 0x3561, 0xd6dc, 0x00c0, 0x350a, 0x68b4, 0xd0dc, 0x00c0, - 0x350a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, - 0x3507, 0x2200, 0xa105, 0x0040, 0x4326, 0x704b, 0x0015, 0x0078, - 0x4326, 0x007c, 0xd6ac, 0x0040, 0x3530, 0xd6f4, 0x0040, 0x3516, - 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4326, 0x68b4, 0xa084, - 0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3510, 0x7048, 0xa005, 0x00c0, - 0x3523, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x352c, 0x68b4, 0xd0dc, - 0x0040, 0x352c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4326, - 0xd6f4, 0x0040, 0x3539, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, - 0x4326, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3533, - 0x7048, 0xa005, 0x00c0, 0x3546, 0x704b, 0x0015, 0x2408, 0x2510, - 0x2700, 0x80fb, 0x00c8, 0x354d, 0x8000, 0xa084, 0x003f, 0xa108, - 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x355a, - 0x0078, 0x4326, 0x7000, 0xa086, 0x0006, 0x0040, 0x3561, 0x0078, - 0x4326, 0x007c, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3568, 0xc08d, - 0x600a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, - 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, - 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0079, 0x3580, - 0x2946, 0x3592, 0x358a, 0x3588, 0x3588, 0x3588, 0x3588, 0x3588, - 0x1078, 0x28ec, 0x6820, 0xd084, 0x00c0, 0x3592, 0x1078, 0x3bb5, - 0x0078, 0x3598, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, - 0x3208, 0xa18c, 0x0300, 0x0040, 0x35a1, 0x2021, 0x4a58, 0x0078, - 0x35a3, 0x2021, 0x4a98, 0x2404, 0xa005, 0x0040, 0x35aa, 0x2020, - 0x0078, 0x35a3, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x3bbc, - 0x1078, 0x3bd2, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, - 0x000e, 0x6f14, 0x6817, 0x0002, 0x3208, 0xa18c, 0x0300, 0x0040, - 0x35c5, 0x2009, 0x0000, 0x0078, 0x35c7, 0x2009, 0x0001, 0x1078, - 0x471a, 0xd6dc, 0x0040, 0x35cf, 0x691c, 0xc1ed, 0x691e, 0x6818, - 0xd0fc, 0x0040, 0x35de, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x35dc, - 0x681b, 0x001e, 0x0078, 0x35de, 0x681b, 0x0000, 0xb284, 0x0300, - 0x00c0, 0x35e6, 0x2021, 0x4a98, 0x0078, 0x35e8, 0x2021, 0x4a58, - 0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x202a, - 0x0078, 0x2946, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078, 0x34e8, 0x682b, - 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4135, 0xa08c, 0x00ff, - 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3607, 0x7048, 0x681a, 0xa68c, - 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x2946, 0x7000, 0xa005, - 0x00c0, 0x3614, 0x0078, 0x2946, 0xa006, 0x1078, 0x4326, 0x6817, - 0x0000, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, - 0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0079, 0x3627, 0x2946, - 0x3634, 0x3631, 0x3636, 0x3636, 0x3636, 0x362f, 0x362f, 0x1078, - 0x28ec, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bd2, 0x6008, 0xc0a4, - 0x600a, 0x0078, 0x3b85, 0x2300, 0x0079, 0x363e, 0x3641, 0x3643, - 0x369f, 0x1078, 0x28ec, 0xd6fc, 0x00c0, 0x3686, 0x7000, 0xa00d, - 0x0079, 0x364a, 0x2946, 0x3654, 0x3654, 0x3678, 0x3654, 0x3683, - 0x3652, 0x3652, 0x1078, 0x28ec, 0xa684, 0x0060, 0xa086, 0x0060, - 0x00c0, 0x3675, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, - 0x681e, 0xa186, 0x0002, 0x0040, 0x3667, 0x1078, 0x4326, 0x1078, - 0x45f7, 0x781b, 0x0076, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4, - 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x365c, - 0x6818, 0xd0fc, 0x0040, 0x3683, 0x681b, 0x0015, 0xd6f4, 0x0040, - 0x3683, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0xc6fc, 0x7e5a, - 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x368f, 0x8000, 0xa084, - 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, - 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0076, 0x007c, 0x1078, - 0x28ec, 0x2300, 0x0079, 0x36a4, 0x36a9, 0x36c5, 0x3719, 0x1078, - 0x28ec, 0x7000, 0x0079, 0x36ac, 0x36b4, 0x36b6, 0x36b6, 0x36b4, - 0x36b4, 0x36b4, 0x36b4, 0x36b4, 0x1078, 0x28ec, 0x1078, 0x45f7, - 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x2942, 0x70a4, - 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6fc, 0x00c0, 0x3709, - 0x7000, 0xa00d, 0x0079, 0x36cc, 0x2946, 0x36dc, 0x36d6, 0x3700, - 0x36dc, 0x3706, 0x36d4, 0x36d4, 0x1078, 0x28ec, 0x6894, 0x78d6, - 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0xa086, 0x0060, - 0x00c0, 0x36fd, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0xa186, 0x0002, - 0x0040, 0x36ec, 0x1078, 0x4326, 0x1078, 0x45f7, 0x781b, 0x0076, - 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4, - 0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x36e4, - 0x6818, 0xd0fc, 0x0040, 0x3706, 0x681b, 0x0007, 0x781b, 0x00f0, - 0x007c, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, - 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0076, - 0x007c, 0xd6dc, 0x0040, 0x3722, 0x782b, 0x3009, 0x781b, 0x0076, - 0x0078, 0x2942, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, - 0x00c0, 0x3735, 0xa484, 0x0200, 0x0040, 0x372f, 0xc6f5, 0xc6dd, - 0x7e5a, 0x781b, 0x0076, 0x0078, 0x2942, 0x6820, 0xc095, 0x6822, - 0x1078, 0x4062, 0xc6dd, 0x1078, 0x3eae, 0x781b, 0x0075, 0x0078, - 0x2942, 0x2300, 0x0079, 0x3744, 0x3747, 0x3749, 0x374b, 0x1078, - 0x28ec, 0x0078, 0x3ea7, 0xd6d4, 0x00c0, 0x3771, 0x79e4, 0xd1ac, - 0x0040, 0x3759, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3759, 0x782b, - 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, - 0x79e4, 0xd1ac, 0x0040, 0x3769, 0x78ec, 0xa084, 0x0003, 0x00c0, - 0x376d, 0x2001, 0x0014, 0x0078, 0x3304, 0xa184, 0x0007, 0x0079, - 0x37a7, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, - 0x0040, 0x37a5, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, - 0x3798, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x378b, 0x2009, - 0xfff7, 0x0078, 0x3791, 0xa386, 0x0003, 0x00c0, 0x3798, 0x2009, - 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, - 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, - 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x2fae, - 0x2fb8, 0x37b1, 0x37b7, 0x37af, 0x37af, 0x40c9, 0x40c9, 0x1078, - 0x28ec, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40cf, 0x6920, - 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x79e4, 0xa184, 0x0030, - 0x0040, 0x37c7, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x37f1, 0x7000, - 0xa086, 0x0004, 0x00c0, 0x37e1, 0x7064, 0xa086, 0x0002, 0x00c0, - 0x37d7, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, - 0xa086, 0x0006, 0x0040, 0x37d1, 0x7064, 0xa086, 0x0004, 0x0040, - 0x37d1, 0x7000, 0xa086, 0x0000, 0x0040, 0x2942, 0x6820, 0xd0ac, - 0x00c0, 0x37ed, 0x6818, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078, - 0x3304, 0xa184, 0x0007, 0x0079, 0x37f5, 0x40c9, 0x40c9, 0x37fd, - 0x40c9, 0x4111, 0x4111, 0x40c9, 0x40c9, 0xd6bc, 0x0040, 0x383f, - 0x7184, 0x81ff, 0x0040, 0x383f, 0xa182, 0x000d, 0x00d0, 0x380c, - 0x7087, 0x0000, 0x0078, 0x3811, 0xa182, 0x000c, 0x7086, 0x2009, - 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x7088, - 0x8114, 0xa210, 0x728a, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, - 0x0300, 0x0040, 0x3833, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, - 0x007f, 0x0040, 0x382f, 0x20a1, 0x012b, 0x0078, 0x3835, 0x20a1, - 0x022b, 0x0078, 0x3835, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, - 0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078, 0x40cf, 0xd6d4, - 0x00c0, 0x3893, 0x6820, 0xd084, 0x0040, 0x40cf, 0xa68c, 0x0060, - 0xa684, 0x0060, 0x0040, 0x3851, 0xa086, 0x0060, 0x00c0, 0x3851, - 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, - 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, - 0x0040, 0x3beb, 0xa18c, 0x00f8, 0x00c0, 0x3beb, 0x157e, 0x137e, - 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x387f, 0x007e, - 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x387b, 0x20a1, - 0x012b, 0x0078, 0x3881, 0x20a1, 0x022b, 0x0078, 0x3881, 0x20a1, - 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, - 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007, - 0x7882, 0x0078, 0x40cf, 0x6818, 0xd0fc, 0x0040, 0x3899, 0x681b, - 0x0008, 0x6820, 0xc0ad, 0x6822, 0x1078, 0x3eb6, 0x781b, 0x00e1, - 0x007c, 0x2300, 0x0079, 0x38a4, 0x38a9, 0x397b, 0x38a7, 0x1078, - 0x28ec, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x00c0, 0x38d1, 0x7200, - 0xa286, 0x0003, 0x0040, 0x32d2, 0x71d4, 0xd1b4, 0x0078, 0x38d4, - 0x0040, 0x38d4, 0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, - 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, - 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, - 0x38d8, 0x7200, 0x0078, 0x38d8, 0x783b, 0x1800, 0x781b, 0x004a, - 0xa284, 0x000f, 0x0079, 0x38dc, 0x3966, 0x391a, 0x38e6, 0x3300, - 0x38e4, 0x3966, 0x38e4, 0x38e4, 0x1078, 0x28ec, 0x681c, 0xd0ec, - 0x0040, 0x38ed, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, - 0x6800, 0x6006, 0xa005, 0x00c0, 0x38f6, 0x6002, 0x6008, 0xc0d4, - 0x600a, 0x681c, 0xa084, 0x000e, 0x00c0, 0x390a, 0xb284, 0x0300, - 0x0040, 0x3906, 0x2009, 0x90c0, 0x0078, 0x390f, 0x2009, 0x91d0, - 0x0078, 0x390f, 0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, - 0x6802, 0x2d0a, 0x715e, 0xd6dc, 0x00c0, 0x391a, 0xc6fc, 0x6eb6, - 0x0078, 0x3966, 0x6eb6, 0xa684, 0x0060, 0x0040, 0x3966, 0xd6dc, - 0x00c0, 0x392d, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, - 0x68aa, 0x1078, 0x4326, 0x0078, 0x3966, 0xd6ac, 0x0040, 0x3939, - 0xa006, 0x1078, 0x4326, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0078, - 0x3949, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8, 0x3940, 0x8000, - 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x1078, - 0x4326, 0xd6fc, 0x0040, 0x3966, 0xa684, 0x7fff, 0x68b6, 0x2510, - 0x2408, 0xd6ac, 0x00c0, 0x395e, 0x2700, 0x801b, 0x00c8, 0x3959, - 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, - 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, - 0x0030, 0x00c0, 0x2946, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, - 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, - 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0, 0x3988, 0x7003, - 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x0078, 0x3ea7, 0x7047, 0x0000, 0xa282, 0x0006, 0x0050, 0x3992, - 0x1078, 0x28ec, 0x2300, 0x0079, 0x3995, 0x3998, 0x39cf, 0x3a01, - 0x2200, 0x0079, 0x399b, 0x39a1, 0x3ea7, 0x39a3, 0x39a1, 0x3a38, - 0x3a9b, 0x1078, 0x28ec, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, - 0x39ad, 0x2001, 0x91e0, 0x0078, 0x39af, 0x2001, 0x9212, 0x2068, + 0x32fb, 0x1078, 0x290c, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, + 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4040, 0x0079, 0x3307, 0x4040, + 0x3dce, 0x4040, 0x3f41, 0xa282, 0x0000, 0x00c0, 0x3311, 0x1078, + 0x290c, 0x1078, 0x4051, 0x781b, 0x0075, 0x007c, 0xa282, 0x0003, + 0x00c0, 0x331c, 0x1078, 0x290c, 0xd4fc, 0x00c0, 0x333c, 0x7064, + 0xa005, 0x0040, 0x3325, 0x1078, 0x290c, 0x6f14, 0x7776, 0xa7bc, + 0x8f00, 0x1078, 0x4187, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, + 0xa784, 0x001f, 0x00c0, 0x3329, 0x1078, 0x4055, 0x7067, 0x0002, + 0x701f, 0x0009, 0x0078, 0x333e, 0x1078, 0x4064, 0x781b, 0x0075, + 0x007c, 0xa282, 0x0004, 0x0050, 0x3347, 0x1078, 0x290c, 0x2300, + 0x0079, 0x334a, 0x334d, 0x350d, 0x3550, 0xa286, 0x0003, 0x0040, + 0x3385, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, + 0x337d, 0xd1b4, 0x0040, 0x337d, 0x7868, 0xa084, 0x00ff, 0x00c0, + 0x337d, 0xa282, 0x0002, 0x00c8, 0x337d, 0x0d7e, 0x783b, 0x8300, + 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, + 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, + 0x0d7f, 0x2001, 0x0000, 0x0078, 0x3389, 0x783b, 0x1300, 0x781b, + 0x004a, 0x2001, 0x0000, 0x0078, 0x3389, 0x7200, 0x7cd8, 0x7ddc, + 0x7fd0, 0x704a, 0x68a0, 0xd0ec, 0x0040, 0x3391, 0x6008, 0xc08d, + 0x600a, 0xa284, 0x000f, 0x0079, 0x3395, 0x34ed, 0x33a2, 0x339f, + 0x3653, 0x36df, 0x2966, 0x339d, 0x339d, 0x1078, 0x290c, 0x6008, + 0xc0d4, 0x600a, 0xd6e4, 0x0040, 0x33aa, 0x7048, 0xa086, 0x0014, + 0x00c0, 0x33ca, 0x1078, 0x44fb, 0x2009, 0x0000, 0x6818, 0xd0fc, + 0x0040, 0x33b3, 0x7048, 0xa086, 0x0014, 0x0040, 0x33c4, 0x6818, + 0xa086, 0x0008, 0x00c0, 0x34a5, 0x7858, 0xd09c, 0x0040, 0x34a5, + 0x6820, 0xd0ac, 0x0040, 0x34a5, 0x681b, 0x0014, 0x2009, 0x0002, + 0x0078, 0x3409, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3409, 0xa186, + 0x0008, 0x00c0, 0x33e0, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3cf5, + 0x0040, 0x3409, 0x1078, 0x3d73, 0x1078, 0x44fb, 0x0078, 0x33f1, + 0xa186, 0x0028, 0x00c0, 0x3409, 0x6018, 0xa005, 0x0040, 0x33d3, + 0x8001, 0x0040, 0x33d3, 0x8001, 0x0040, 0x33d3, 0x601e, 0x0078, + 0x33d3, 0x6820, 0xd084, 0x0040, 0x2966, 0xc084, 0x6822, 0x1078, + 0x2a6d, 0x705c, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, + 0x6802, 0xa005, 0x2d00, 0x00c0, 0x3406, 0x6002, 0x6006, 0x0078, + 0x2966, 0x017e, 0x81ff, 0x00c0, 0x3453, 0x7000, 0xa086, 0x0030, + 0x0040, 0x3453, 0x71d4, 0xd1bc, 0x00c0, 0x3453, 0xd1b4, 0x00c0, + 0x343a, 0x7060, 0xa005, 0x00c0, 0x3453, 0x70a4, 0xa086, 0x0001, + 0x0040, 0x3453, 0x7003, 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, + 0x0c7e, 0x0d7e, 0x1078, 0x298f, 0x0d7f, 0x0c7f, 0x067f, 0x077f, + 0x057f, 0x047f, 0x71d4, 0xd1b4, 0x00c0, 0x3453, 0x7003, 0x0040, + 0x0078, 0x3453, 0x1078, 0x42e9, 0x00c0, 0x3453, 0x781b, 0x005b, + 0x0d7e, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, + 0xc08d, 0x780a, 0x0d7f, 0x1078, 0x358a, 0x017f, 0x81ff, 0x0040, + 0x34a5, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, + 0x0002, 0x00c0, 0x34a6, 0x6818, 0xa086, 0x0014, 0x00c0, 0x346f, + 0x2008, 0xd6e4, 0x0040, 0x346f, 0x7868, 0xa08c, 0x00ff, 0x1078, + 0x2a5b, 0x1078, 0x2a7c, 0x6820, 0xd0dc, 0x00c0, 0x34a6, 0x8717, + 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, + 0x3485, 0xa290, 0x51c0, 0x0078, 0x3487, 0xa290, 0x5240, 0xa290, + 0x0000, 0x221c, 0xd3c4, 0x00c0, 0x348f, 0x0078, 0x3495, 0x8210, + 0x2204, 0xa085, 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x34a0, + 0x68a0, 0xd0c4, 0x00c0, 0x34a0, 0x1078, 0x3604, 0x0078, 0x2966, + 0x6008, 0xc08d, 0x600a, 0x0078, 0x34a6, 0x692a, 0x6916, 0x6818, + 0xd0fc, 0x0040, 0x34ad, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, + 0x6410, 0x84ff, 0x0040, 0x34c2, 0x2009, 0x4d02, 0x2104, 0x8001, + 0x200a, 0x8421, 0x6412, 0x00c0, 0x34c2, 0x2021, 0x4d04, 0x2404, + 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0040, 0x34ca, 0x8001, 0x601a, + 0x00c0, 0x34cd, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, + 0x34d9, 0x6800, 0xa005, 0x00c0, 0x34d6, 0x6002, 0x6006, 0x0078, + 0x34dd, 0x705c, 0x2060, 0x6800, 0x6002, 0x2061, 0x4d00, 0x6887, + 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, + 0x34ec, 0x2d02, 0x0078, 0x34ed, 0x616e, 0x7200, 0xa286, 0x0030, + 0x0040, 0x34fd, 0xa286, 0x0040, 0x00c0, 0x2966, 0x7003, 0x0002, + 0x704c, 0x2068, 0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, + 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, + 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, + 0x3513, 0x1078, 0x290c, 0x2200, 0x0079, 0x3516, 0x351a, 0x352b, + 0x3538, 0x352b, 0xa586, 0x1300, 0x0040, 0x352b, 0xa586, 0x8300, + 0x00c0, 0x3511, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x3535, + 0x1078, 0x4051, 0x781b, 0x0075, 0x007c, 0x781b, 0x0076, 0x007c, + 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, + 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0040, 0x354d, 0xa186, + 0x0000, 0x0040, 0x354d, 0x0078, 0x4040, 0x781b, 0x0076, 0x007c, + 0x6820, 0xc095, 0x6822, 0x82ff, 0x00c0, 0x355a, 0x1078, 0x4051, + 0x0078, 0x3561, 0x8211, 0x0040, 0x355f, 0x1078, 0x290c, 0x1078, + 0x4064, 0x781b, 0x0075, 0x007c, 0x1078, 0x42fe, 0x7830, 0xa084, + 0x00c0, 0x00c0, 0x3587, 0x017e, 0x3208, 0x007e, 0x2001, 0x4d04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3579, 0xa18c, 0x0300, 0x0078, + 0x357b, 0xa18c, 0x0400, 0x017f, 0x0040, 0x3582, 0x0018, 0x3587, + 0x0078, 0x3584, 0x0028, 0x3587, 0x791a, 0xa006, 0x007c, 0xa085, + 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0, 0x3594, 0x682f, 0x0000, + 0x6833, 0x0000, 0x0078, 0x3603, 0xd6dc, 0x00c0, 0x35ac, 0x68b4, + 0xd0dc, 0x00c0, 0x35ac, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, + 0xa005, 0x00c0, 0x35a9, 0x2200, 0xa105, 0x0040, 0x44fb, 0x704b, + 0x0015, 0x0078, 0x44fb, 0x007c, 0xd6ac, 0x0040, 0x35d2, 0xd6f4, + 0x0040, 0x35b8, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x44fb, + 0x68b4, 0xa084, 0x4000, 0xa635, 0xd6f4, 0x00c0, 0x35b2, 0x7048, + 0xa005, 0x00c0, 0x35c5, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x35ce, + 0x68b4, 0xd0dc, 0x0040, 0x35ce, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, + 0x0078, 0x44fb, 0xd6f4, 0x0040, 0x35db, 0x682f, 0x0000, 0x6833, + 0x0000, 0x0078, 0x44fb, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, + 0x00c0, 0x35d5, 0x7048, 0xa005, 0x00c0, 0x35e8, 0x704b, 0x0015, + 0x2408, 0x2510, 0x2700, 0x80fb, 0x00c8, 0x35ef, 0x8000, 0xa084, + 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, + 0x00c0, 0x35fc, 0x0078, 0x44fb, 0x7000, 0xa086, 0x0006, 0x0040, + 0x3603, 0x0078, 0x44fb, 0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, + 0x0040, 0x360b, 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, + 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, + 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, + 0x689b, 0x0020, 0x7000, 0x0079, 0x3625, 0x2966, 0x3637, 0x362f, + 0x362d, 0x362d, 0x362d, 0x362d, 0x362d, 0x1078, 0x290c, 0x6820, + 0xd084, 0x00c0, 0x3637, 0x1078, 0x3d56, 0x0078, 0x363d, 0x705c, + 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, + 0x0040, 0x3646, 0x2021, 0x4d58, 0x0078, 0x3648, 0x2021, 0x4d98, + 0x2404, 0xa005, 0x0040, 0x364f, 0x2020, 0x0078, 0x3648, 0x2d22, + 0x206b, 0x0000, 0x007c, 0x1078, 0x3d5d, 0x1078, 0x3d73, 0x6008, + 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, + 0x691a, 0x6944, 0x6916, 0x3208, 0xa18c, 0x0300, 0x0040, 0x366c, + 0x2009, 0x0000, 0x0078, 0x366e, 0x2009, 0x0001, 0x1078, 0x496f, + 0xd6dc, 0x0040, 0x3676, 0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, + 0x0040, 0x3685, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3683, 0x681b, + 0x001e, 0x0078, 0x3685, 0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, + 0x368d, 0x2021, 0x4d98, 0x0078, 0x368f, 0x2021, 0x4d58, 0x6800, + 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, + 0xd0a4, 0x0040, 0x36cf, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, + 0x0020, 0x0d7e, 0x0f7e, 0x157e, 0x147e, 0x2079, 0x4d00, 0x1078, + 0x1de6, 0x147f, 0x157f, 0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, + 0x027e, 0x2204, 0xa06d, 0x0040, 0x36bf, 0x6814, 0xa706, 0x0040, + 0x36bc, 0x6800, 0x0078, 0x36b2, 0x6820, 0xc0d5, 0x6822, 0x027f, + 0x8210, 0x8109, 0x00c0, 0x36b0, 0x0d7f, 0x7067, 0x0003, 0x707f, + 0x0000, 0x7776, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, + 0xa086, 0x0002, 0x00c0, 0x36db, 0x6817, 0x0000, 0x682b, 0x0000, + 0x681c, 0xc0ec, 0x681e, 0x1078, 0x2013, 0x0078, 0x2966, 0x7cd8, + 0x7ddc, 0x7fd0, 0x1078, 0x358a, 0x682b, 0x0000, 0x789b, 0x000e, + 0x6f14, 0x1078, 0x4302, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, + 0x0040, 0x36f4, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, + 0x0000, 0x0078, 0x2966, 0x7000, 0xa005, 0x00c0, 0x3701, 0x0078, + 0x2966, 0xa006, 0x1078, 0x44fb, 0x6920, 0xd1ac, 0x00c0, 0x370a, + 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, + 0xa084, 0x00ff, 0x6822, 0x7000, 0x0079, 0x3716, 0x2966, 0x3720, + 0x3720, 0x3723, 0x3723, 0x3723, 0x371e, 0x371e, 0x1078, 0x290c, + 0x6818, 0x0078, 0x3385, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, + 0x0078, 0x3d1b, 0x2300, 0x0079, 0x372d, 0x3730, 0x3732, 0x379d, + 0x1078, 0x290c, 0xd6fc, 0x00c0, 0x3784, 0x7000, 0xa00d, 0x0079, + 0x3739, 0x2966, 0x3743, 0x3743, 0x3772, 0x3743, 0x3781, 0x3741, + 0x3741, 0x1078, 0x290c, 0xa684, 0x0060, 0x0040, 0x3772, 0xa086, + 0x0060, 0x00c0, 0x376f, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, + 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0040, 0x3761, 0x1078, 0x44fb, + 0x69ac, 0x68b0, 0xa115, 0x0040, 0x3761, 0x1078, 0x486c, 0x0078, + 0x3763, 0x1078, 0x4834, 0x781b, 0x0076, 0x71d4, 0xd1b4, 0x00c0, + 0x2962, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x29ac, 0x007c, 0xd6ec, + 0x0040, 0x374d, 0x6818, 0xd0fc, 0x0040, 0x3781, 0xd6f4, 0x00c0, + 0x377f, 0x681b, 0x0015, 0x781b, 0x0076, 0x0078, 0x2962, 0x681b, + 0x0007, 0x1078, 0x42a2, 0x007c, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, + 0x78d0, 0x801b, 0x00c8, 0x378d, 0x8000, 0xa084, 0x003f, 0xa108, + 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, + 0xa303, 0x68ae, 0x781b, 0x0076, 0x007c, 0x1078, 0x290c, 0x2300, + 0x0079, 0x37a2, 0x37a7, 0x37cc, 0x382b, 0x1078, 0x290c, 0x7000, + 0x0079, 0x37aa, 0x37b2, 0x37b4, 0x37bd, 0x37b2, 0x37b2, 0x37b2, + 0x37b2, 0x37b2, 0x1078, 0x290c, 0x69ac, 0x68b0, 0xa115, 0x0040, + 0x37bd, 0x1078, 0x486c, 0x0078, 0x37bf, 0x1078, 0x4834, 0x681c, + 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x2962, 0x70a4, 0xa086, + 0x0001, 0x00c0, 0x29ac, 0x007c, 0xd6fc, 0x00c0, 0x381b, 0x7000, + 0xa00d, 0x0079, 0x37d3, 0x2966, 0x37e3, 0x37dd, 0x3812, 0x37e3, + 0x3818, 0x37db, 0x37db, 0x1078, 0x290c, 0x6894, 0x78d6, 0x78de, + 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0040, 0x3812, 0xa086, + 0x0060, 0x00c0, 0x380f, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0xa186, + 0x0002, 0x0040, 0x37fe, 0x1078, 0x44fb, 0x69ac, 0x68b0, 0xa115, + 0x0040, 0x37fe, 0x1078, 0x486c, 0x0078, 0x3800, 0x1078, 0x4834, + 0x781b, 0x0076, 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, 0x00c0, + 0x2962, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x29ac, 0x007c, 0xd6ec, + 0x0040, 0x37ed, 0x6818, 0xd0fc, 0x0040, 0x3818, 0x681b, 0x0007, + 0x781b, 0x00f6, 0x007c, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, + 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, + 0x781b, 0x0076, 0x007c, 0xd6dc, 0x0040, 0x3834, 0x782b, 0x3009, + 0x781b, 0x0076, 0x0078, 0x2962, 0x7884, 0xc0ac, 0x7886, 0x78e4, + 0xa084, 0x0008, 0x00c0, 0x3847, 0xa484, 0x0200, 0x0040, 0x3841, + 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0076, 0x0078, 0x2962, 0x6820, + 0xc095, 0x6822, 0x1078, 0x421b, 0xc6dd, 0x1078, 0x4051, 0x781b, + 0x0075, 0x0078, 0x2962, 0x2300, 0x0079, 0x3856, 0x3859, 0x385b, + 0x385d, 0x1078, 0x290c, 0x0078, 0x404a, 0xd6d4, 0x00c0, 0x3883, + 0x79e4, 0xd1ac, 0x0040, 0x386b, 0x78ec, 0xa084, 0x0003, 0x0040, + 0x386b, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, + 0xfffb, 0x785a, 0x79e4, 0xd1ac, 0x0040, 0x387b, 0x78ec, 0xa084, + 0x0003, 0x00c0, 0x387f, 0x2001, 0x0014, 0x0078, 0x3385, 0xa184, + 0x0007, 0x0079, 0x38b9, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, + 0x79a8, 0x81ff, 0x0040, 0x38b7, 0x789b, 0x0010, 0x7ba8, 0xa384, + 0x0001, 0x00c0, 0x38aa, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, + 0x389d, 0x2009, 0xfff7, 0x0078, 0x38a3, 0xa386, 0x0003, 0x00c0, + 0x38aa, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104, + 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, + 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, + 0x4296, 0x302e, 0x3038, 0x38c3, 0x38c9, 0x38c1, 0x38c1, 0x4296, + 0x4296, 0x1078, 0x290c, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, + 0x429c, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x4296, 0x79e4, + 0xa184, 0x0030, 0x0040, 0x38d9, 0x78ec, 0xa084, 0x0003, 0x00c0, + 0x390d, 0x7000, 0xa086, 0x0004, 0x00c0, 0x38f3, 0x7064, 0xa086, + 0x0002, 0x00c0, 0x38e9, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, + 0x2eba, 0x7064, 0xa086, 0x0006, 0x0040, 0x38e3, 0x7064, 0xa086, + 0x0004, 0x0040, 0x38e3, 0x7000, 0xa086, 0x0000, 0x0040, 0x2962, + 0x6920, 0xa184, 0x0420, 0x0040, 0x3902, 0xc1d4, 0x6922, 0x6818, + 0x0078, 0x3385, 0x6818, 0xa08e, 0x0002, 0x0040, 0x390b, 0xc0fd, + 0x681a, 0x2001, 0x0014, 0x0078, 0x3385, 0xa184, 0x0007, 0x0079, + 0x3911, 0x4296, 0x4296, 0x3919, 0x4296, 0x42de, 0x42de, 0x4296, + 0x4296, 0xd6bc, 0x0040, 0x395b, 0x7184, 0x81ff, 0x0040, 0x395b, + 0xa182, 0x000d, 0x00d0, 0x3928, 0x7087, 0x0000, 0x0078, 0x392d, + 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, + 0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a, 0xa080, + 0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x394f, 0x007e, + 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x394b, 0x20a1, + 0x012b, 0x0078, 0x3951, 0x20a1, 0x022b, 0x0078, 0x3951, 0x20a1, + 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f, + 0x157f, 0x0078, 0x429c, 0xd6d4, 0x00c0, 0x39af, 0x6820, 0xd084, + 0x0040, 0x429c, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x396d, + 0xa086, 0x0060, 0x00c0, 0x396d, 0xc1f5, 0xc194, 0x795a, 0x69b6, + 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, + 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3d8c, 0xa18c, 0x00f8, + 0x00c0, 0x3d8c, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, + 0x0300, 0x0040, 0x399b, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x007f, 0x0040, 0x3997, 0x20a1, 0x012b, 0x0078, 0x399d, 0x20a1, + 0x022b, 0x0078, 0x399d, 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, + 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, + 0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x429c, 0x6818, + 0xd0fc, 0x0040, 0x39b5, 0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822, + 0x1078, 0x4059, 0x781b, 0x00e7, 0x007c, 0x2300, 0x0079, 0x39c0, + 0x39c5, 0x3a9d, 0x39c3, 0x1078, 0x290c, 0x7cd8, 0x7ddc, 0x7fd0, + 0x82ff, 0x00c0, 0x39ee, 0x7200, 0xa286, 0x0003, 0x0040, 0x3352, + 0x71d4, 0xd1bc, 0x00c0, 0x39f1, 0xd1b4, 0x0040, 0x39f1, 0x0d7e, + 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4, 0xc0a5, + 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, + 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x39f5, 0x7200, 0x0078, + 0x39f5, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f, 0x0079, + 0x39f9, 0x3a88, 0x3a37, 0x3a03, 0x3381, 0x3a01, 0x3a88, 0x3a01, + 0x3a01, 0x1078, 0x290c, 0x681c, 0xd0ec, 0x0040, 0x3a0a, 0x6008, + 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, + 0x00c0, 0x3a13, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, + 0x000e, 0x00c0, 0x3a27, 0xb284, 0x0300, 0x0040, 0x3a23, 0x2009, + 0x93c0, 0x0078, 0x3a2c, 0x2009, 0x94d0, 0x0078, 0x3a2c, 0x7030, + 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e, + 0xd6dc, 0x00c0, 0x3a37, 0xc6fc, 0x6eb6, 0x0078, 0x3a88, 0x6eb6, + 0xa684, 0x0060, 0x00c0, 0x3a41, 0xa684, 0x7fff, 0x68b6, 0x0078, + 0x3a88, 0xd6dc, 0x00c0, 0x3a4f, 0xa684, 0x7fff, 0x68b6, 0x6894, + 0x68a6, 0x6898, 0x68aa, 0x1078, 0x44fb, 0x0078, 0x3a88, 0xd6ac, + 0x0040, 0x3a5b, 0xa006, 0x1078, 0x44fb, 0x2408, 0x2510, 0x69aa, + 0x6aa6, 0x0078, 0x3a6b, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8, + 0x3a62, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa, + 0x6aa6, 0x1078, 0x44fb, 0xd6fc, 0x0040, 0x3a88, 0xa684, 0x7fff, + 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3a80, 0x2700, 0x801b, + 0x00c8, 0x3a7b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, + 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, + 0x7000, 0xa086, 0x0030, 0x00c0, 0x2966, 0x7003, 0x0002, 0x70bc, + 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, + 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0, + 0x3aaa, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x0078, 0x404a, 0x7047, 0x0000, 0xa282, 0x0006, + 0x0050, 0x3ab4, 0x1078, 0x290c, 0x2300, 0x0079, 0x3ab7, 0x3aba, + 0x3af1, 0x3b23, 0x2200, 0x0079, 0x3abd, 0x3ac3, 0x404a, 0x3ac5, + 0x3ac3, 0x3b5a, 0x3bc2, 0x1078, 0x290c, 0x7003, 0x0005, 0xb284, + 0x0300, 0x0040, 0x3acf, 0x2001, 0x94e0, 0x0078, 0x3ad1, 0x2001, + 0x9512, 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, + 0x8000, 0x00f0, 0x3ad6, 0x157f, 0xb284, 0x0300, 0x0040, 0x3ae4, + 0x6817, 0x0000, 0x0078, 0x3ae6, 0x6817, 0x8000, 0xad80, 0x0009, + 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, + 0x4040, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b02, 0x1078, 0x3d73, + 0x0078, 0x3afc, 0x1078, 0x44fb, 0x6008, 0xa084, 0xfbef, 0x600a, + 0x0078, 0x3b07, 0x7000, 0xa086, 0x0003, 0x0040, 0x3afa, 0x7003, + 0x0005, 0xb284, 0x0300, 0x0040, 0x3b11, 0x2001, 0x94e0, 0x0078, + 0x3b13, 0x2001, 0x9512, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, + 0x2200, 0x0079, 0x3b1b, 0x404a, 0x3b21, 0x3b21, 0x3b5a, 0x3b21, + 0x404a, 0x1078, 0x290c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b34, + 0x1078, 0x3d73, 0x0078, 0x3b2e, 0x1078, 0x44fb, 0x6008, 0xa084, + 0xfbef, 0x600a, 0x0078, 0x3b39, 0x7000, 0xa086, 0x0003, 0x0040, + 0x3b2c, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3b43, 0x2001, + 0x94e0, 0x0078, 0x3b45, 0x2001, 0x9512, 0x2068, 0x704e, 0xad80, + 0x0009, 0x7046, 0x2200, 0x0079, 0x3b4d, 0x3b55, 0x3b53, 0x3b53, + 0x3b55, 0x3b53, 0x3b55, 0x1078, 0x290c, 0x1078, 0x4064, 0x781b, + 0x0075, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b6c, 0x70d4, + 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3b71, + 0x1078, 0x44fb, 0x0078, 0x3b71, 0x7000, 0xa086, 0x0003, 0x0040, + 0x3b68, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, + 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x93c0, 0xb284, 0x0300, + 0x00c0, 0x3b85, 0xc2fd, 0x2069, 0x94d0, 0x2d04, 0x2d08, 0x715e, + 0xa06d, 0x0040, 0x3b92, 0x6814, 0xa206, 0x0040, 0x3bb2, 0x6800, + 0x0078, 0x3b86, 0x7003, 0x0005, 0xd2fc, 0x00c0, 0x3b9b, 0x2001, + 0x94e0, 0x0078, 0x3b9d, 0x2001, 0x9512, 0x2068, 0x704e, 0x157e, + 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3ba2, 0x157f, + 0xad80, 0x0009, 0x7046, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, + 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6920, 0xa184, 0x0c00, 0x0040, + 0x3c3c, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4059, + 0x0078, 0x3c3c, 0x7200, 0xa286, 0x0002, 0x00c0, 0x3bd4, 0x70d4, + 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3bd8, + 0x1078, 0x44fb, 0x0078, 0x3bd8, 0xa286, 0x0003, 0x0040, 0x3bd0, + 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, + 0xa484, 0x001f, 0xa215, 0xb284, 0x0300, 0x00c0, 0x3be8, 0xc2fd, + 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, 0x2d08, + 0x715e, 0xa06d, 0x0040, 0x3bfb, 0x6814, 0xa206, 0x0040, 0x3c24, + 0x6800, 0x0078, 0x3bef, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, + 0x3c05, 0x2001, 0x94e0, 0x0078, 0x3c07, 0x2001, 0x9512, 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, - 0x39b4, 0x157f, 0xb284, 0x0300, 0x0040, 0x39c2, 0x6817, 0x0000, - 0x0078, 0x39c4, 0x6817, 0x8000, 0xad80, 0x0009, 0x7046, 0x68b7, - 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x3e9d, 0x7000, - 0xa086, 0x0002, 0x00c0, 0x39e0, 0x1078, 0x3bd2, 0x0078, 0x39da, - 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0078, 0x39e5, - 0x7000, 0xa086, 0x0003, 0x0040, 0x39d8, 0x7003, 0x0005, 0xb284, - 0x0300, 0x0040, 0x39ef, 0x2001, 0x91e0, 0x0078, 0x39f1, 0x2001, - 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0079, - 0x39f9, 0x3ea7, 0x39ff, 0x39ff, 0x3a38, 0x39ff, 0x3ea7, 0x1078, - 0x28ec, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a12, 0x1078, 0x3bd2, - 0x0078, 0x3a0c, 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x0078, 0x3a17, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a0a, 0x7003, - 0x0005, 0xb284, 0x0300, 0x0040, 0x3a21, 0x2001, 0x91e0, 0x0078, - 0x3a23, 0x2001, 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, - 0x2200, 0x0079, 0x3a2b, 0x3a33, 0x3a31, 0x3a31, 0x3a33, 0x3a31, - 0x3a33, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, 0x0075, 0x007c, - 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a4a, 0x70d4, 0xc0b5, 0x70d6, - 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3a4f, 0x1078, 0x4326, - 0x0078, 0x3a4f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a46, 0x7003, - 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, - 0x001f, 0xa215, 0x2069, 0x90c0, 0xb284, 0x0300, 0x00c0, 0x3a63, - 0xc2fd, 0x2069, 0x91d0, 0x2d04, 0x2d08, 0x715e, 0xa06d, 0x0040, - 0x3a70, 0x6814, 0xa206, 0x0040, 0x3a90, 0x6800, 0x0078, 0x3a64, - 0x7003, 0x0005, 0xd2fc, 0x00c0, 0x3a79, 0x2001, 0x91e0, 0x0078, - 0x3a7b, 0x2001, 0x9212, 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, - 0x2003, 0x0000, 0x8000, 0x00f0, 0x3a80, 0x157f, 0xad80, 0x0009, - 0x7046, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, - 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3b10, 0x1078, - 0x3eb6, 0x0078, 0x3b10, 0x7200, 0xa286, 0x0002, 0x00c0, 0x3aad, - 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, - 0x3ab1, 0x1078, 0x4326, 0x0078, 0x3ab1, 0xa286, 0x0003, 0x0040, - 0x3aa9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, - 0x7ca8, 0xa484, 0x001f, 0xa215, 0xb284, 0x0300, 0x00c0, 0x3ac1, - 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, - 0x2d08, 0x715e, 0xa06d, 0x0040, 0x3ad4, 0x6814, 0xa206, 0x0040, - 0x3afd, 0x6800, 0x0078, 0x3ac8, 0x7003, 0x0005, 0xb284, 0x0300, - 0x0040, 0x3ade, 0x2001, 0x91e0, 0x0078, 0x3ae0, 0x2001, 0x9212, - 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, - 0x00f0, 0x3ae5, 0x157f, 0xb284, 0x0300, 0x0040, 0x3af2, 0xc2fc, - 0x0078, 0x3af3, 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, - 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6820, 0xa084, - 0x0c00, 0x0040, 0x3b10, 0xd0dc, 0x0040, 0x3b0a, 0x1078, 0x3eba, - 0x0078, 0x3b10, 0x1078, 0x3eb6, 0x707f, 0x0000, 0x0078, 0x3b10, - 0xa6ac, 0x0060, 0x0040, 0x3b4e, 0x6b98, 0x6c94, 0x69ac, 0x68b0, - 0xa105, 0x00c0, 0x3b33, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, - 0xb7ff, 0xa586, 0x0060, 0x0040, 0x3b4e, 0xc6ed, 0x7e5a, 0x2009, - 0x0076, 0xd69c, 0x0040, 0x3b2e, 0x2009, 0x0075, 0x791a, 0x1078, - 0x45f7, 0x0078, 0x3b57, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, - 0xa305, 0x0040, 0x3b4e, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, - 0xc6f4, 0x7e5a, 0x2011, 0x0076, 0xd69c, 0x0040, 0x3b49, 0x2011, - 0x0075, 0x7a1a, 0x1078, 0x462d, 0x0078, 0x3b57, 0x7e5a, 0x2009, - 0x0076, 0xd69c, 0x0040, 0x3b56, 0x2009, 0x0075, 0x791a, 0x68c0, - 0x705a, 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0xd1b4, 0x00c0, - 0x2942, 0x2300, 0xa405, 0x0040, 0x2942, 0x70a4, 0xa086, 0x0001, - 0x00c0, 0x2989, 0x007c, 0x6020, 0xa005, 0x0040, 0x3b79, 0x8001, - 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, - 0x6026, 0x007c, 0xa006, 0x1078, 0x4326, 0x6817, 0x0000, 0x681b, - 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, - 0x0079, 0x3b8a, 0x2946, 0x3b94, 0x3b94, 0x3bb1, 0x3b9c, 0x2946, - 0x3b92, 0x3b92, 0x1078, 0x28ec, 0x1078, 0x3bbc, 0x1078, 0x3bb5, - 0x1078, 0x202a, 0x0078, 0x2946, 0x7064, 0x7067, 0x0000, 0x7083, - 0x0000, 0x0079, 0x3ba3, 0x3bad, 0x3bad, 0x3bab, 0x3bab, 0x3bab, - 0x3bad, 0x3bab, 0x3bad, 0x0079, 0x2e5c, 0x7067, 0x0000, 0x0078, - 0x2946, 0x681b, 0x0000, 0x0078, 0x35ae, 0x6800, 0xa005, 0x00c0, - 0x3bba, 0x6002, 0x6006, 0x007c, 0x6410, 0x84ff, 0x0040, 0x3bce, - 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x00c0, - 0x3bce, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4, - 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x3bd8, 0x8001, 0x601a, - 0x007c, 0x1078, 0x4131, 0x681b, 0x0018, 0x0078, 0x3c1a, 0x1078, - 0x4131, 0x681b, 0x0019, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, - 0x001a, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, 0x0003, 0x0078, - 0x3c1a, 0x7774, 0x1078, 0x3fe1, 0x7178, 0xa18c, 0x00ff, 0x3210, - 0xa294, 0x0300, 0x0040, 0x3c00, 0xa1e8, 0x8fc0, 0x0078, 0x3c02, - 0xa1e8, 0x90d0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x3c0a, - 0x0078, 0x2946, 0x6814, 0xc0fc, 0x7274, 0xc2fc, 0xa206, 0x0040, - 0x3c14, 0x6800, 0x0078, 0x3c03, 0x6800, 0x200a, 0x681b, 0x0005, - 0x707f, 0x0000, 0x1078, 0x3bbc, 0x6820, 0xd084, 0x00c0, 0x3c22, - 0x1078, 0x3bb5, 0x1078, 0x3bd2, 0x681f, 0x0000, 0x6823, 0x0020, - 0x1078, 0x202a, 0x0078, 0x2946, 0xa282, 0x0003, 0x00c0, 0x3e9d, - 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd, - 0x6922, 0xd1c4, 0x0040, 0x3c86, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, - 0x0040, 0x3c73, 0xa682, 0x000c, 0x0048, 0x3c4a, 0x0040, 0x3c4a, - 0x2031, 0x000c, 0x2500, 0xa086, 0x000a, 0x0040, 0x3c51, 0x852b, - 0x852b, 0x1078, 0x3f73, 0x0040, 0x3c59, 0x1078, 0x3d55, 0x0078, - 0x3c7c, 0x1078, 0x3f2e, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, - 0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x6920, 0xc1c5, 0x6922, 0x7e58, - 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3c70, 0x781b, 0x0061, 0x007c, - 0x781b, 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, - 0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x7e58, 0xd6d4, 0x00c0, 0x3c83, - 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, 0x007c, 0x0c7e, 0x7058, - 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3ccf, 0x6208, 0x8217, 0xa294, - 0x00ff, 0xa282, 0x000c, 0x0048, 0x3c99, 0x0040, 0x3c99, 0x2011, - 0x000c, 0x2600, 0xa202, 0x00c8, 0x3c9e, 0x2230, 0x6208, 0xa294, - 0x00ff, 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3cb3, 0x78ec, - 0xd0e4, 0x0040, 0x3cb3, 0xa282, 0x000a, 0x00c8, 0x3cb9, 0x2011, - 0x000a, 0x0078, 0x3cb9, 0xa282, 0x000c, 0x00c8, 0x3cb9, 0x2011, - 0x000c, 0x2200, 0xa502, 0x00c8, 0x3cbe, 0x2228, 0x1078, 0x3f32, - 0x2500, 0xa086, 0x000a, 0x0040, 0x3cc7, 0x852b, 0x852b, 0x1078, - 0x3f73, 0x0040, 0x3ccf, 0x1078, 0x3d55, 0x0078, 0x3cd3, 0x1078, - 0x3f2e, 0x1078, 0x3d8a, 0x7858, 0xc095, 0x785a, 0x0c7f, 0x781b, - 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0, 0x3cf1, - 0x6010, 0xa084, 0x000f, 0x00c0, 0x3ceb, 0x6104, 0xa18c, 0xfff5, - 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, - 0x3d1c, 0x68a0, 0xd0cc, 0x00c0, 0x3ceb, 0x6208, 0xa294, 0x00ff, - 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3d0a, 0x78ec, 0xd0e4, - 0x0040, 0x3d0a, 0xa282, 0x000a, 0x00c0, 0x3d0a, 0x2011, 0x000a, - 0x0078, 0x3d10, 0xa282, 0x000c, 0x00c8, 0x3d10, 0x2011, 0x000c, - 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3d1c, - 0x0040, 0x3d1c, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, - 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, - 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3d38, 0xc0b4, 0x70d6, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, - 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3d46, 0x78ab, 0x0001, + 0x3c0c, 0x157f, 0xb284, 0x0300, 0x0040, 0x3c19, 0xc2fc, 0x0078, + 0x3c1a, 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, + 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, + 0x0040, 0x3c3c, 0xd0dc, 0x0040, 0x3c31, 0x1078, 0x4060, 0x0078, + 0x3c3c, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4059, + 0x707f, 0x0000, 0x0078, 0x3c3c, 0xc6ec, 0xa6ac, 0x0060, 0x0040, + 0x3c90, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3c69, + 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3c8e, + 0xd6f4, 0x00c0, 0x3c54, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, + 0x0076, 0xd69c, 0x0040, 0x3c61, 0x2009, 0x0075, 0x2019, 0x0000, + 0x2320, 0x791a, 0xd6ec, 0x0040, 0x3c99, 0x1078, 0x4834, 0x0078, + 0x3c99, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, + 0x3c90, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0, + 0x3c7a, 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0076, 0xd69c, 0x0040, + 0x3c86, 0x2011, 0x0075, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, + 0x0040, 0x3c99, 0x1078, 0x486c, 0x0078, 0x3c99, 0xa6b4, 0xb7ff, + 0x7e5a, 0x2009, 0x0076, 0xd69c, 0x0040, 0x3c98, 0x2009, 0x0075, + 0x791a, 0x68c0, 0x705a, 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, + 0x70d8, 0xa02d, 0x0040, 0x3cc1, 0xd1bc, 0x0040, 0x3cdb, 0x7a80, + 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040, 0x3cb2, 0x78e0, 0xa504, + 0x00c0, 0x3ce8, 0x70da, 0xc1bc, 0x71d6, 0x0078, 0x3ce8, 0x2031, + 0x0001, 0x852c, 0x0048, 0x3cc0, 0x8633, 0x8210, 0x0078, 0x3cb9, + 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040, 0x3cce, 0x2011, 0x0008, + 0x852f, 0x1078, 0x3cb7, 0x8637, 0x0078, 0x3cd0, 0x1078, 0x3cb7, + 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0040, 0x3ce8, 0x72de, + 0x76da, 0x0078, 0x3ce8, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa236, + 0x0040, 0x3cd8, 0x78e0, 0xa534, 0x0040, 0x3cd8, 0xc1bd, 0x71d6, + 0xd1b4, 0x00c0, 0x2962, 0x2300, 0xa405, 0x0040, 0x2962, 0x70a4, + 0xa086, 0x0001, 0x00c0, 0x29ac, 0x007c, 0x6020, 0xa005, 0x0040, + 0x3d03, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, 0x700f, + 0x0100, 0x702c, 0x6026, 0x007c, 0xa006, 0x1078, 0x44fb, 0x7000, + 0xa086, 0x0002, 0x0040, 0x3d11, 0x7064, 0xa086, 0x0005, 0x00c0, + 0x3d1b, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, + 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0079, 0x3d20, + 0x2966, 0x3d30, 0x3d2a, 0x3d52, 0x3d3a, 0x2966, 0x3d28, 0x3d28, + 0x1078, 0x290c, 0x1078, 0x3d5d, 0x1078, 0x3d56, 0x0078, 0x3d36, + 0x1078, 0x3d5d, 0x705c, 0x2060, 0x6800, 0x6002, 0x1078, 0x2013, + 0x0078, 0x2966, 0x7064, 0x7067, 0x0000, 0x7083, 0x0000, 0x0079, + 0x3d41, 0x3d4e, 0x3d4e, 0x3d49, 0x3d49, 0x3d49, 0x3d4e, 0x3d49, + 0x3d4e, 0x77d4, 0xc7dd, 0x77d6, 0x0079, 0x2ed3, 0x7067, 0x0000, + 0x0078, 0x2966, 0x681b, 0x0000, 0x0078, 0x3653, 0x6800, 0xa005, + 0x00c0, 0x3d5b, 0x6002, 0x6006, 0x007c, 0x6410, 0x84ff, 0x0040, + 0x3d6f, 0x2009, 0x4d02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, + 0x00c0, 0x3d6f, 0x2021, 0x4d04, 0x2404, 0xc0a5, 0x2022, 0x6008, + 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x3d79, 0x8001, + 0x601a, 0x007c, 0x1078, 0x42fe, 0x681b, 0x0018, 0x0078, 0x3dbc, + 0x1078, 0x42fe, 0x681b, 0x0019, 0x0078, 0x3dbc, 0x1078, 0x42fe, + 0x681b, 0x001a, 0x0078, 0x3dbc, 0x1078, 0x42fe, 0x681b, 0x0003, + 0x0078, 0x3dbc, 0x7774, 0x1078, 0x4187, 0x7178, 0xa18c, 0x00ff, + 0x3210, 0xa294, 0x0300, 0x0040, 0x3da1, 0xa1e8, 0x92c0, 0x0078, + 0x3da3, 0xa1e8, 0x93d0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, + 0x3dac, 0x707e, 0x0078, 0x2966, 0x6814, 0xc0fc, 0x7274, 0xc2fc, + 0xa206, 0x0040, 0x3db6, 0x6800, 0x0078, 0x3da4, 0x6800, 0x200a, + 0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3d5d, 0x6820, 0xd084, + 0x00c0, 0x3dc4, 0x1078, 0x3d56, 0x1078, 0x3d73, 0x681f, 0x0000, + 0x6823, 0x0020, 0x1078, 0x2013, 0x0078, 0x2966, 0xa282, 0x0003, + 0x00c0, 0x4040, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, + 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3e28, 0xc1c4, 0x6922, + 0xa6b4, 0x00ff, 0x0040, 0x3e15, 0xa682, 0x000c, 0x0048, 0x3dec, + 0x0040, 0x3dec, 0x2031, 0x000c, 0x2500, 0xa086, 0x000a, 0x0040, + 0x3df3, 0x852b, 0x852b, 0x1078, 0x4119, 0x0040, 0x3dfb, 0x1078, + 0x3ef7, 0x0078, 0x3e1e, 0x1078, 0x40d4, 0x0c7e, 0x2960, 0x6004, + 0xa084, 0xfff5, 0x6006, 0x1078, 0x3f2d, 0x0c7f, 0x6920, 0xc1c5, + 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3e12, 0x781b, + 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6004, + 0xa084, 0xfff5, 0x6006, 0x1078, 0x3f2d, 0x0c7f, 0x7e58, 0xd6d4, + 0x00c0, 0x3e25, 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, 0x007c, + 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3e71, 0x6208, + 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x3e3b, 0x0040, + 0x3e3b, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8, 0x3e40, 0x2230, + 0x6208, 0xa294, 0x00ff, 0x2001, 0x4d05, 0x2004, 0xd0e4, 0x00c0, + 0x3e55, 0x78ec, 0xd0e4, 0x0040, 0x3e55, 0xa282, 0x000a, 0x00c8, + 0x3e5b, 0x2011, 0x000a, 0x0078, 0x3e5b, 0xa282, 0x000c, 0x00c8, + 0x3e5b, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x3e60, 0x2228, + 0x1078, 0x40d8, 0x2500, 0xa086, 0x000a, 0x0040, 0x3e69, 0x852b, + 0x852b, 0x1078, 0x4119, 0x0040, 0x3e71, 0x1078, 0x3ef7, 0x0078, + 0x3e75, 0x1078, 0x40d4, 0x1078, 0x3f2d, 0x7858, 0xc095, 0x785a, + 0x0c7f, 0x781b, 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6000, 0xd0e4, + 0x00c0, 0x3e93, 0x6010, 0xa084, 0x000f, 0x00c0, 0x3e8d, 0x6104, + 0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, + 0x0000, 0x0078, 0x3ebe, 0x68a0, 0xd0cc, 0x00c0, 0x3e8d, 0x6208, + 0xa294, 0x00ff, 0x2001, 0x4d05, 0x2004, 0xd0e4, 0x00c0, 0x3eac, + 0x78ec, 0xd0e4, 0x0040, 0x3eac, 0xa282, 0x000b, 0x00c8, 0x3eac, + 0x2011, 0x000a, 0x0078, 0x3eb2, 0xa282, 0x000c, 0x00c8, 0x3eb2, + 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, + 0x0048, 0x3ebe, 0x0040, 0x3ebe, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, - 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160, - 0x2018, 0xa08c, 0x0020, 0x0040, 0x3d5e, 0xc0ac, 0x2008, 0xa084, - 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, - 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xa39c, 0x0020, 0x0040, - 0x3d73, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3d78, 0xc0fd, - 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004, - 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, - 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4, - 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, - 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002, - 0x00c0, 0x3e9d, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040, - 0x3dd9, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, - 0x3e9d, 0x1078, 0x3e2a, 0x1078, 0x3d8a, 0xa980, 0x0001, 0x200c, - 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, 0x3dcf, 0x789b, - 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, - 0x3dcc, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, 0x7e58, - 0xd6d4, 0x00c0, 0x3dd6, 0x781b, 0x0064, 0x007c, 0x781b, 0x0076, - 0x007c, 0xa282, 0x0002, 0x00c8, 0x3de1, 0xa284, 0x0001, 0x0040, - 0x3dea, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x3dea, - 0x2011, 0x0000, 0x1078, 0x3f0f, 0x1078, 0x3e2a, 0x1078, 0x3d8a, - 0x7858, 0xc095, 0x785a, 0x781b, 0x0075, 0x007c, 0x0c7e, 0x027e, - 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x3e0b, 0x6014, - 0xa084, 0x0040, 0x00c0, 0x3e09, 0xc1a4, 0x6106, 0xa006, 0x0078, - 0x3e27, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, - 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3e23, - 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, - 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, - 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff, 0x0040, 0x3e32, - 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, - 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x3e3f, 0xc0fd, 0x78a6, - 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f, 0x007c, 0x007e, - 0x7000, 0xa086, 0x0003, 0x0040, 0x3e50, 0x007f, 0x0078, 0x3e53, - 0x007f, 0x0078, 0x3e9a, 0xd6ac, 0x0040, 0x3e9a, 0x7888, 0xa084, - 0x0040, 0x0040, 0x3e9a, 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, - 0x3e62, 0x8000, 0xa005, 0x0040, 0x3e77, 0x831b, 0x00c8, 0x3e6b, - 0x8001, 0x0040, 0x3e97, 0xd6f4, 0x0040, 0x3e77, 0x78b8, 0x801b, - 0x00c8, 0x3e73, 0x8000, 0xa084, 0x003f, 0x00c0, 0x3e97, 0xc6f4, - 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3e82, - 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x46e5, - 0x781b, 0x0073, 0xb284, 0x0300, 0x0040, 0x3e92, 0x2001, 0x0000, - 0x0078, 0x3e94, 0x2001, 0x0001, 0x1078, 0x4585, 0x007c, 0x781b, - 0x0073, 0x007c, 0x781b, 0x0076, 0x007c, 0x1078, 0x3ec2, 0x781b, - 0x0075, 0x007c, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0x6827, - 0x0002, 0x1078, 0x3eb6, 0x781b, 0x0075, 0x007c, 0x2001, 0x0005, - 0x0078, 0x3ec4, 0x2001, 0x000c, 0x0078, 0x3ec4, 0x2001, 0x0006, - 0x0078, 0x3ec4, 0x2001, 0x000d, 0x0078, 0x3ec4, 0x2001, 0x0009, - 0x0078, 0x3ec4, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, - 0x7e5a, 0x70d4, 0xd0b4, 0x0040, 0x3eda, 0xc0b4, 0x70d6, 0x0c7e, - 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, - 0x601a, 0x0c7f, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, - 0x873b, 0x8703, 0x017e, 0xb28c, 0x0300, 0x0040, 0x3eeb, 0xa0e0, - 0x4ec0, 0x0078, 0x3eed, 0xa0e0, 0x4f40, 0x017f, 0xa7b8, 0x0020, - 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x3efd, 0xa184, 0xfff0, - 0x78a6, 0x6012, 0x6004, 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, - 0x79a4, 0xa184, 0x0040, 0x0040, 0x3f0d, 0xa184, 0xffbf, 0xc0fd, - 0x78a6, 0x6016, 0x6004, 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, - 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, - 0x789b, 0x0060, 0x78ab, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3f2d, - 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, - 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, - 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, - 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, - 0x70d4, 0xd0b4, 0x0040, 0x3f51, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, - 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, - 0x0c7f, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, - 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x3fc6, - 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, - 0xfff0, 0xa106, 0x0040, 0x3f71, 0x8420, 0x2300, 0xa210, 0x00f0, - 0x3f66, 0x157f, 0x007c, 0x157e, 0x2001, 0x4a05, 0x2004, 0xd0e4, - 0x00c0, 0x3fa4, 0x2021, 0x3fd4, 0x20a9, 0x0009, 0x2011, 0x0028, - 0xa582, 0x0019, 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x95a9, - 0x2011, 0x0032, 0xa582, 0x0032, 0x0040, 0x3fba, 0x0048, 0x3fba, - 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, - 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, - 0x3f96, 0x157f, 0x0078, 0x3fb8, 0x2021, 0x3fc6, 0x2019, 0x0011, - 0x20a9, 0x000e, 0x2011, 0x0032, 0x2200, 0xa502, 0x0040, 0x3fba, - 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, 0x3fac, 0x157f, - 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x3fc3, 0x7808, - 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, - 0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, - 0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, - 0x6a06, 0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, - 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, - 0x8003, 0x8003, 0xa105, 0xd7fc, 0x0040, 0x3ff2, 0xa0e0, 0x6fc0, - 0x0078, 0x3ff4, 0xa0e0, 0x4fc0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, - 0x0040, 0x4002, 0x2079, 0x0100, 0x2009, 0x4a80, 0x2071, 0x4a80, - 0x0078, 0x4014, 0x2009, 0x4a40, 0x007e, 0x2001, 0x4a04, 0x2004, - 0xd0ec, 0x007f, 0x0040, 0x4010, 0x2079, 0x0100, 0x0078, 0x4014, - 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x8000, 0x2104, 0xa084, - 0x000f, 0x0079, 0x401b, 0x405d, 0x4025, 0x4025, 0x4025, 0x4025, - 0x4025, 0x4023, 0x4023, 0x1078, 0x28ec, 0x784b, 0x0004, 0x7848, - 0xa084, 0x0004, 0x00c0, 0x4027, 0x784b, 0x0008, 0x7848, 0xa084, - 0x0008, 0x00c0, 0x402e, 0x68b4, 0xc0f5, 0x68b6, 0x7858, 0xc0f5, - 0x785a, 0x7830, 0xd0bc, 0x00c0, 0x405d, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4049, 0xb284, 0x0300, 0x0078, - 0x404b, 0xb284, 0x0400, 0x0040, 0x4051, 0x0018, 0x405d, 0x0078, - 0x4053, 0x0028, 0x405d, 0x681c, 0xd0ac, 0x00c0, 0x405b, 0x1078, - 0x40d5, 0x0078, 0x405d, 0x781b, 0x00f0, 0x2091, 0x8001, 0x0f7f, - 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, - 0x40c7, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xb28c, 0x0300, 0x0040, 0x4078, 0xa0e0, 0x4ec0, 0x0078, 0x407a, - 0xa0e0, 0x4f40, 0x6004, 0xa084, 0x000a, 0x00c0, 0x40c7, 0x6108, - 0xa194, 0xff00, 0x0040, 0x40c7, 0xa18c, 0x00ff, 0x2001, 0x000a, - 0xa106, 0x0040, 0x40a6, 0x2001, 0x000c, 0xa106, 0x0040, 0x40aa, - 0x2001, 0x0012, 0xa106, 0x0040, 0x40ae, 0x2001, 0x0014, 0xa106, - 0x0040, 0x40b2, 0x2001, 0x0019, 0xa106, 0x0040, 0x40b6, 0x2001, - 0x0032, 0xa106, 0x0040, 0x40ba, 0x0078, 0x40be, 0x2009, 0x000c, - 0x0078, 0x40c0, 0x2009, 0x0012, 0x0078, 0x40c0, 0x2009, 0x0014, - 0x0078, 0x40c0, 0x2009, 0x0019, 0x0078, 0x40c0, 0x2009, 0x0020, - 0x0078, 0x40c0, 0x2009, 0x003f, 0x0078, 0x40c0, 0x2011, 0x0000, - 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, - 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0075, 0x007c, 0x781b, - 0x0064, 0x007c, 0x781b, 0x0061, 0x007c, 0x2009, 0x4a19, 0x210c, - 0xa186, 0x0000, 0x0040, 0x40e7, 0xa186, 0x0001, 0x0040, 0x40ea, - 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x781b, - 0x00e7, 0x007c, 0x701f, 0x000a, 0x007c, 0x2009, 0x4a19, 0x210c, - 0xa186, 0x0000, 0x0040, 0x4102, 0xa186, 0x0001, 0x0040, 0x40ff, - 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x701f, - 0x000a, 0x007c, 0x781b, 0x00e6, 0x007c, 0x781b, 0x00f0, 0x007c, - 0x781b, 0x00ef, 0x007c, 0x781b, 0x00c0, 0x007c, 0x781b, 0x00bf, - 0x007c, 0x6818, 0xd0fc, 0x0040, 0x4117, 0x681b, 0x001d, 0x7067, - 0x0001, 0x781b, 0x0047, 0x007c, 0x7830, 0xa084, 0x00c0, 0x00c0, - 0x4130, 0x7808, 0xc08c, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, - 0x78ec, 0xa084, 0x0021, 0x0040, 0x4130, 0x7808, 0xc08d, 0x780a, - 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, - 0x00c0, 0x4135, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4144, - 0xb284, 0x0300, 0x0078, 0x4146, 0xb284, 0x0400, 0x0040, 0x414c, - 0x0098, 0x4150, 0x0078, 0x414e, 0x00a8, 0x4150, 0x78ac, 0x007c, - 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, - 0x78ec, 0xa084, 0x0021, 0x0040, 0x4173, 0x007e, 0x2001, 0x4a04, - 0x2004, 0xd0ec, 0x007f, 0x0040, 0x4169, 0xb284, 0x0300, 0x0078, - 0x416b, 0xb284, 0x0400, 0x0040, 0x4171, 0x0098, 0x416d, 0x0078, - 0x4173, 0x00a8, 0x4171, 0x78ac, 0x007e, 0x7808, 0xa085, 0x0002, - 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0, 0x360e, 0xa784, - 0x0070, 0x0040, 0x418b, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2881, - 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x4198, 0x784b, - 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, 0x0078, 0x40c9, - 0xa784, 0x0004, 0x0040, 0x41c7, 0x78b8, 0xa084, 0x4001, 0x0040, - 0x41c7, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, - 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x41c7, 0x78c0, - 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f0, 0x007c, 0x784b, - 0x0008, 0x6818, 0xd0fc, 0x0040, 0x41c4, 0x681b, 0x0015, 0xd6f4, - 0x0040, 0x41c4, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0x681b, - 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, - 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f84, - 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x41e4, - 0xb284, 0x0300, 0x0078, 0x41e6, 0xb284, 0x0400, 0x0040, 0x41ec, - 0x0018, 0x2942, 0x0078, 0x41ee, 0x0028, 0x2942, 0x0078, 0x3ea2, - 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, - 0x0040, 0x41fe, 0xa080, 0x4f40, 0x0078, 0x4200, 0xa080, 0x4ec0, - 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, - 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, - 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014, 0x9906, 0x98f4, - 0x0014, 0x0014, 0x0080, 0x00f1, 0x0100, 0x0402, 0x2008, 0xf880, - 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, - 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, - 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, - 0x3806, 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d0d, - 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, - 0x883a, 0xa808, 0x28e2, 0x9cc2, 0xa8f3, 0x0864, 0xa83e, 0x300c, - 0xa801, 0x3008, 0x28e1, 0x9cc2, 0x2021, 0xa81b, 0xa205, 0x870c, - 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, - 0x883d, 0x9d25, 0x882b, 0x1814, 0x883b, 0x9d2b, 0x883b, 0x7027, - 0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa812, 0x883e, - 0xa810, 0x280c, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x9d25, - 0x1814, 0x9d2b, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861, - 0x883e, 0x206b, 0x28c1, 0x9d0d, 0x2044, 0x2103, 0x20a2, 0x2081, - 0xa8c9, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, 0x8000, 0x85a4, - 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x866f, - 0x7161, 0x0014, 0x0704, 0x3008, 0x9cc2, 0x0014, 0xa202, 0x8000, - 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, - 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, - 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, - 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x284a, - 0x1011, 0xa8fc, 0x3008, 0x9d25, 0x8000, 0xa000, 0x2802, 0x1011, - 0xa8fd, 0x9d2b, 0xa887, 0x3008, 0x9d25, 0x283b, 0x1011, 0xa8fd, - 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, - 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, - 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d17, - 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, - 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021, - 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822, - 0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944, - 0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4, - 0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205, - 0x00c0, 0x4342, 0x720c, 0x82ff, 0x0040, 0x433d, 0x8aff, 0x00c0, - 0x4342, 0x7200, 0xd284, 0x00c0, 0x4342, 0x7003, 0x0008, 0x127f, - 0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084, - 0x0040, 0x4374, 0x2001, 0x4a05, 0x2004, 0xd0ec, 0x00c0, 0x43a5, - 0xd0e4, 0x00c0, 0x435a, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, - 0x0040, 0x43a5, 0x0e7e, 0x2071, 0x0010, 0x2009, 0x0007, 0x7008, - 0xa084, 0x3000, 0x00c0, 0x435d, 0x8109, 0x00c0, 0x435f, 0x0e7f, - 0x2009, 0x0007, 0x7008, 0xa084, 0x3000, 0x00c0, 0x435a, 0x8109, - 0x00c0, 0x436a, 0x0078, 0x43a5, 0x7108, 0xd1fc, 0x0040, 0x437f, - 0x1078, 0x44ba, 0x8aff, 0x0040, 0x432c, 0x0078, 0x4374, 0x700c, - 0xa08c, 0x03ff, 0x0040, 0x43aa, 0x7004, 0xd084, 0x0040, 0x439c, - 0x7014, 0xa005, 0x00c0, 0x4398, 0x7010, 0x7310, 0xa306, 0x00c0, - 0x438c, 0x2300, 0xa005, 0x0040, 0x439c, 0xa102, 0x00c8, 0x4374, - 0x7007, 0x0010, 0x0078, 0x43a5, 0x8aff, 0x0040, 0x43aa, 0x1078, - 0x46a3, 0x00c0, 0x439f, 0x0040, 0x4374, 0x1078, 0x4443, 0x127f, - 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x43b9, - 0x1078, 0x44ba, 0x0078, 0x43aa, 0x7003, 0x0008, 0x127f, 0x2000, - 0x007c, 0xa205, 0x00c0, 0x43a5, 0x7003, 0x0008, 0x127f, 0x2000, - 0x007c, 0x6428, 0x84ff, 0x0040, 0x43ed, 0x2c70, 0x7004, 0xa0bc, - 0x000f, 0xa7b8, 0x43fd, 0x273c, 0x87fb, 0x00c0, 0x43db, 0x0048, - 0x43d3, 0x1078, 0x28ec, 0x609c, 0xa075, 0x0040, 0x43ed, 0x0078, - 0x43c6, 0x2039, 0x43f2, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, - 0xa529, 0x8421, 0x0040, 0x43ed, 0x8738, 0x2704, 0xa005, 0x00c0, - 0x43dc, 0x709c, 0xa075, 0x00c0, 0x43c6, 0x007c, 0x0000, 0x0005, - 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, - 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x43f2, 0x43ef, - 0x0000, 0x0000, 0x8000, 0x0000, 0x43f2, 0x0000, 0x43fa, 0x43f7, - 0x0000, 0x0000, 0x0000, 0x0000, 0x43fa, 0x0000, 0x43f5, 0x43f5, - 0x0000, 0x0000, 0x8000, 0x0000, 0x43f5, 0x0000, 0x43fb, 0x43fb, - 0x0000, 0x0000, 0x0000, 0x0000, 0x43fb, 0x2079, 0x4a00, 0x2071, - 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x7810, - 0xd0ec, 0x0040, 0x4431, 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, - 0x4435, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, - 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x4442, 0x2071, 0x0020, - 0x0078, 0x4435, 0x007c, 0x7004, 0x8004, 0x00c8, 0x44a6, 0x7007, - 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x444b, - 0xa184, 0x01e0, 0x0040, 0x4456, 0x1078, 0x28ec, 0x7810, 0xd0ec, - 0x0040, 0x4470, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0, - 0x4474, 0xa184, 0x4000, 0x0040, 0x4478, 0xa382, 0x0003, 0x00c8, - 0x4478, 0xa184, 0x0004, 0x0040, 0x444b, 0x8318, 0x0078, 0x444b, - 0x7814, 0xd0ec, 0x00c0, 0x4478, 0xa184, 0x4000, 0x00c0, 0x444b, - 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4486, 0xa386, 0x0008, - 0x0040, 0x4491, 0xa386, 0x200c, 0x00c0, 0x444b, 0x7200, 0x8204, - 0x0048, 0x4491, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4491, 0x1078, - 0x28ec, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x44a6, 0x7008, - 0xa084, 0x01e0, 0x00c0, 0x44a6, 0x7310, 0x7014, 0xa305, 0x0040, - 0x44a6, 0x710c, 0xa184, 0x03ff, 0x00c0, 0x4443, 0x7007, 0x0012, - 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x44aa, 0x7007, 0x0012, - 0x7108, 0x8103, 0x0048, 0x44ae, 0x7003, 0x0008, 0x007c, 0x7108, - 0x0078, 0x44ba, 0xa184, 0x01e0, 0x00c0, 0x44ee, 0x7108, 0xa184, - 0x01e0, 0x00c0, 0x44ee, 0xa184, 0x0007, 0x0079, 0x44c7, 0x44d1, - 0x44e1, 0x44cf, 0x44e1, 0x44cf, 0x4533, 0x44cf, 0x4531, 0x1078, - 0x28ec, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, - 0x44dc, 0x2049, 0x0000, 0x007c, 0x1078, 0x46a3, 0x00c0, 0x44dc, - 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0040, - 0x44ed, 0x1078, 0x46a3, 0x00c0, 0x44e9, 0x007c, 0x7007, 0x0012, - 0x7108, 0x00e0, 0x44f1, 0x2091, 0x6000, 0x00e0, 0x44f5, 0x2091, - 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, - 0x44fd, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0, 0x4501, 0x7003, - 0x0000, 0x7000, 0xa005, 0x00c0, 0x4515, 0x7004, 0xa005, 0x00c0, - 0x4515, 0x700c, 0xa005, 0x0040, 0x4517, 0x0078, 0x44f9, 0x2049, - 0x0000, 0xb284, 0x0100, 0x0040, 0x4521, 0x2001, 0x0000, 0x0078, - 0x4523, 0x2001, 0x0001, 0x1078, 0x3ff5, 0x6818, 0xa084, 0x8000, - 0x0040, 0x452c, 0x681b, 0x0002, 0x007c, 0x1078, 0x28ec, 0x1078, - 0x28ec, 0x1078, 0x4570, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff, - 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x4570, 0x2704, - 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, - 0x2400, 0xa305, 0x0040, 0x4556, 0x00c8, 0x4556, 0x8412, 0x8210, - 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x453d, 0x2b60, 0x8a07, - 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4562, 0xa7ba, 0x43f7, - 0x0078, 0x4564, 0xa7ba, 0x43ef, 0x007f, 0xa73d, 0x2c00, 0x6886, - 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4443, 0x007c, - 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4584, 0x6000, 0xa064, - 0x00c0, 0x457b, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x440d, - 0x203c, 0x87fb, 0x1040, 0x28ec, 0x007c, 0x127e, 0x0d7e, 0x70d4, - 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, - 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, - 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x45a2, 0xa0b8, 0x43f7, - 0x0078, 0x45a4, 0xa0b8, 0x43ef, 0xb284, 0x0100, 0x0040, 0x45ab, - 0x7e20, 0x0078, 0x45ac, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, - 0x0040, 0x45b3, 0xc685, 0x2400, 0xa305, 0x0040, 0x45dd, 0x2c58, - 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, - 0x701e, 0xa184, 0x0008, 0x0040, 0x45cd, 0x6010, 0xa081, 0x0000, - 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, - 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, - 0x2b60, 0x1078, 0x46c6, 0x0078, 0x45df, 0x1078, 0x46a3, 0x00c0, - 0x45dd, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, - 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, - 0x00c0, 0x45ee, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, - 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7e20, - 0xb284, 0x0100, 0x00c0, 0x4605, 0x7e24, 0xa6b5, 0x000c, 0x681c, - 0xd0ac, 0x00c0, 0x4610, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, - 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, - 0x273c, 0x87fb, 0x00c0, 0x4626, 0x0048, 0x4620, 0x1078, 0x28ec, - 0x689c, 0xa065, 0x0040, 0x462a, 0x0078, 0x4613, 0x1078, 0x46a3, - 0x00c0, 0x4626, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, - 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x7e20, 0xb284, - 0x0100, 0x00c0, 0x463c, 0x7e24, 0x0d7f, 0x037f, 0x047f, 0xa6b5, - 0x000c, 0x681c, 0xd0b4, 0x0040, 0x464a, 0xc685, 0x7003, 0x0000, - 0x7007, 0x0004, 0x2049, 0x462d, 0x6828, 0xa055, 0x0040, 0x46a0, - 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, 0x273c, - 0x87fb, 0x00c0, 0x4666, 0x0048, 0x465f, 0x1078, 0x28ec, 0x709c, - 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x2704, 0xae68, - 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x467f, 0x8a51, 0x00c0, - 0x4673, 0x1078, 0x28ec, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4667, - 0x709c, 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x8422, - 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, - 0x2300, 0xa11b, 0x00c8, 0x468e, 0x1078, 0x28ec, 0xb284, 0x0100, - 0x0040, 0x469c, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x00c0, 0x469c, - 0x2071, 0x0050, 0x0078, 0x469e, 0x2071, 0x0020, 0x0078, 0x45b3, - 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, - 0x00c0, 0x46ab, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, - 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xa084, 0x0008, - 0x0040, 0x46be, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, - 0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4a00, 0x8a51, 0x0040, - 0x46e1, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46dc, 0x609c, 0xa005, - 0x0040, 0x46e2, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x43fd, - 0x203c, 0x87fb, 0x1040, 0x28ec, 0x7008, 0xa084, 0x0003, 0xa086, - 0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, - 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, - 0xa184, 0x0003, 0x00c0, 0x46fa, 0x6828, 0xa005, 0x0040, 0x470a, - 0x0078, 0x4342, 0x7108, 0xd1fc, 0x0040, 0x4702, 0x1078, 0x44ba, - 0x0078, 0x46ef, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4704, - 0x1078, 0x44ba, 0x7008, 0xa086, 0x0008, 0x00c0, 0x46ef, 0x7000, - 0xa005, 0x00c0, 0x46ef, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, - 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, - 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x471a, - 0xad80, 0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x473d, 0x2001, - 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4739, 0x2099, 0x0031, 0x0078, - 0x473f, 0x2099, 0x0032, 0x0078, 0x473f, 0x2099, 0x0031, 0x700c, - 0xa084, 0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, - 0x0001, 0x0040, 0x474e, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, - 0x03ff, 0x0040, 0x475a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, - 0x00c0, 0x4755, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, - 0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, - 0x6000, 0x78ac, 0xa005, 0x00c0, 0x477c, 0x7974, 0x70d0, 0xa106, - 0x00c0, 0x477c, 0x781c, 0xa005, 0x0040, 0x477c, 0x781f, 0x0000, - 0x0068, 0x477c, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, - 0x4804, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x47fd, 0x2061, - 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4796, - 0x8001, 0x68d2, 0x00c0, 0x4796, 0x1078, 0x4998, 0x6800, 0xa084, - 0x000f, 0x0040, 0x47ab, 0xa086, 0x0001, 0x0040, 0x47ab, 0x6844, - 0xa00d, 0x0040, 0x47ab, 0x2104, 0xa005, 0x0040, 0x47ab, 0x8001, - 0x200a, 0x0040, 0x4909, 0x6814, 0xa005, 0x0040, 0x47d0, 0x8001, - 0x6816, 0x00c0, 0x47d0, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, - 0x47c5, 0x7810, 0xd0ec, 0x0040, 0x47c1, 0x2079, 0x0100, 0x0078, - 0x47c7, 0x2079, 0x0200, 0x0078, 0x47c7, 0x2079, 0x0100, 0x1078, - 0x4131, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x47d0, 0x1078, 0x25de, - 0x6880, 0xa005, 0x0040, 0x47dd, 0x8001, 0x6882, 0x00c0, 0x47dd, - 0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, - 0x47fa, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x603c, 0xa005, 0x0040, - 0x47f6, 0x8001, 0x603e, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x47f6, - 0x6010, 0xa005, 0x0040, 0x47f6, 0x1078, 0x25de, 0xace0, 0x0010, - 0x00f0, 0x47e5, 0xd7fc, 0x0040, 0x4804, 0x2061, 0x4fc0, 0x2069, - 0x4a40, 0xc7fc, 0x0078, 0x478c, 0x1078, 0x4840, 0x7838, 0x8001, - 0x783a, 0x00c0, 0x4826, 0x783c, 0x783a, 0x2061, 0x4fc0, 0x2069, - 0x4a40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4818, 0x1078, 0x487f, - 0xd7fc, 0x00c0, 0x4826, 0x7810, 0xd0ec, 0x00c0, 0x4826, 0x2061, - 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x4812, 0x7814, 0xd0e4, - 0x00c0, 0x482a, 0x7810, 0xd0cc, 0x0040, 0x483d, 0xd0ac, 0x00c0, - 0x4836, 0xd0a4, 0x0040, 0x483d, 0xc0ad, 0x7812, 0x2091, 0x8001, - 0x0068, 0x483c, 0x1078, 0x2368, 0x007c, 0x2091, 0x8001, 0x007c, - 0x7840, 0x8001, 0x7842, 0x00c0, 0x487e, 0x7844, 0x7842, 0x2091, - 0x8000, 0x2061, 0x4fc0, 0x2069, 0x4a40, 0xc7fc, 0x6810, 0xa005, - 0x00c0, 0x4854, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040, - 0x485d, 0xa080, 0x90d0, 0x0078, 0x485f, 0xa080, 0x8fc0, 0x2040, - 0x2004, 0xa065, 0x0040, 0x4870, 0x6024, 0xa005, 0x0040, 0x486c, - 0x8001, 0x6026, 0x0040, 0x48ad, 0x6000, 0x2c40, 0x0078, 0x4861, - 0xd7fc, 0x00c0, 0x487e, 0x7810, 0xd0ec, 0x00c0, 0x487e, 0x2061, - 0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x484e, 0x007c, 0x2009, - 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4899, 0x6024, - 0xa005, 0x0040, 0x488f, 0x8001, 0x6026, 0x0078, 0x4897, 0x6008, - 0xc09c, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4899, 0xa18d, - 0x0100, 0xace0, 0x0010, 0x00f0, 0x4883, 0xa184, 0x0001, 0x0040, - 0x48a8, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x25de, 0x0078, 0x48a9, - 0x690e, 0x007c, 0x00c0, 0x48a9, 0x786c, 0x6800, 0xa005, 0x0040, - 0x48b5, 0x684c, 0xac06, 0x0040, 0x4909, 0x6864, 0xa005, 0x0040, - 0x48bd, 0x6027, 0x0001, 0x0078, 0x4906, 0x2c00, 0x687e, 0x601b, + 0x6820, 0xc0c5, 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3eda, 0xc0b4, + 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, + 0x8001, 0x601a, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, + 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3ee8, + 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, + 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, + 0x7158, 0x2160, 0x2018, 0xa08c, 0x0020, 0x0040, 0x3f00, 0xc0ac, + 0x2008, 0xa084, 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, + 0x6612, 0x78a4, 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4, + 0xa39c, 0x0020, 0x0040, 0x3f16, 0xa085, 0x4000, 0xc0fc, 0xd0b4, + 0x00c0, 0x3f1b, 0xc0fd, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, + 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, + 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, + 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, + 0xa084, 0xfff0, 0x7886, 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, + 0x007c, 0xa282, 0x0002, 0x00c0, 0x4040, 0x7aa8, 0x6920, 0xc1bd, + 0x6922, 0xd1cc, 0x0040, 0x3f7c, 0xc1cc, 0x6922, 0xa294, 0x00ff, + 0xa282, 0x0002, 0x00c8, 0x4040, 0x1078, 0x3fcd, 0x1078, 0x3f2d, + 0xa980, 0x0001, 0x200c, 0x1078, 0x4183, 0x1078, 0x3e7c, 0x88ff, + 0x0040, 0x3f72, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, + 0x7e5a, 0xd6d4, 0x00c0, 0x3f6f, 0x781b, 0x0061, 0x007c, 0x781b, + 0x0075, 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x3f79, 0x781b, 0x0064, + 0x007c, 0x781b, 0x0076, 0x007c, 0xa282, 0x0002, 0x00c8, 0x3f84, + 0xa284, 0x0001, 0x0040, 0x3f8d, 0x7158, 0xa188, 0x0000, 0x210c, + 0xd1ec, 0x00c0, 0x3f8d, 0x2011, 0x0000, 0x1078, 0x40b5, 0x1078, + 0x3fcd, 0x1078, 0x3f2d, 0x7858, 0xc095, 0x785a, 0x781b, 0x0075, + 0x007c, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, + 0x00c0, 0x3fae, 0x6014, 0xa084, 0x0040, 0x00c0, 0x3fac, 0xc1a4, + 0x6106, 0xa006, 0x0078, 0x3fca, 0x2011, 0x0000, 0x78ab, 0x0001, + 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, + 0xd0b4, 0x0040, 0x3fc6, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, + 0x0200, 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, + 0x82ff, 0x0040, 0x3fd5, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, + 0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, + 0x3fe2, 0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, + 0x0c7f, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3ff3, + 0x007f, 0x0078, 0x3ff6, 0x007f, 0x0078, 0x403d, 0xd6ac, 0x0040, + 0x403d, 0x7888, 0xa084, 0x0040, 0x0040, 0x403d, 0x7bb8, 0xa384, + 0x003f, 0x831b, 0x00c8, 0x4005, 0x8000, 0xa005, 0x0040, 0x401a, + 0x831b, 0x00c8, 0x400e, 0x8001, 0x0040, 0x403a, 0xd6f4, 0x0040, + 0x401a, 0x78b8, 0x801b, 0x00c8, 0x4016, 0x8000, 0xa084, 0x003f, + 0x00c0, 0x403a, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, + 0xa108, 0x00c8, 0x4025, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, + 0x7ade, 0x1078, 0x493a, 0x781b, 0x0073, 0xb284, 0x0300, 0x0040, + 0x4035, 0x2001, 0x0000, 0x0078, 0x4037, 0x2001, 0x0001, 0x1078, + 0x47c2, 0x007c, 0x781b, 0x0073, 0x007c, 0x781b, 0x0076, 0x007c, + 0x1078, 0x4068, 0x781b, 0x0075, 0x007c, 0x1078, 0x4051, 0x781b, + 0x0075, 0x007c, 0x6827, 0x0002, 0x1078, 0x4059, 0x781b, 0x0075, + 0x007c, 0x2001, 0x0005, 0x0078, 0x406a, 0x2001, 0x000c, 0x0078, + 0x406a, 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x406a, + 0x2001, 0x000d, 0x0078, 0x406a, 0x2001, 0x0009, 0x0078, 0x406a, + 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, + 0xd0b4, 0x0040, 0x4080, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, + 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, + 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, + 0x017e, 0xb28c, 0x0300, 0x0040, 0x4091, 0xa0e0, 0x51c0, 0x0078, + 0x4093, 0xa0e0, 0x5240, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, + 0xa184, 0x000f, 0x0040, 0x40a3, 0xa184, 0xfff0, 0x78a6, 0x6012, + 0x6004, 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, + 0x0040, 0x0040, 0x40b3, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, + 0x6004, 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, + 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, + 0x78ab, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x40d3, 0xc0b4, 0x70d6, + 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, + 0x8001, 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, + 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, + 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, + 0x0040, 0x40f7, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, + 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, + 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, + 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x416c, 0x2019, 0x0011, + 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, + 0x0040, 0x4117, 0x8420, 0x2300, 0xa210, 0x00f0, 0x410c, 0x157f, + 0x007c, 0x157e, 0x2001, 0x4d05, 0x2004, 0xd0e4, 0x00c0, 0x414a, + 0x2021, 0x417a, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, + 0x0040, 0x4160, 0x0048, 0x4160, 0x8420, 0x95a9, 0x2011, 0x0032, + 0xa582, 0x0032, 0x0040, 0x4160, 0x0048, 0x4160, 0x8420, 0x95a9, + 0x2019, 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x4160, + 0x0048, 0x4160, 0x8420, 0x2300, 0xa210, 0x00f0, 0x413c, 0x157f, + 0x0078, 0x415e, 0x2021, 0x416c, 0x2019, 0x0011, 0x20a9, 0x000e, + 0x2011, 0x0032, 0x2200, 0xa502, 0x0040, 0x4160, 0x0048, 0x4160, + 0x8420, 0x2300, 0xa210, 0x00f0, 0x4152, 0x157f, 0xa006, 0x007c, + 0x157f, 0xa582, 0x0064, 0x00c8, 0x4169, 0x7808, 0xa085, 0x0070, + 0x780a, 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, + 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, + 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, + 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, + 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, + 0xa105, 0xd7fc, 0x0040, 0x4198, 0xa0e0, 0x72c0, 0x0078, 0x419a, + 0xa0e0, 0x52c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x41a8, + 0x2079, 0x0100, 0x2009, 0x4d80, 0x2071, 0x4d80, 0x0078, 0x41b8, + 0x2009, 0x4d40, 0x2071, 0x4d40, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x0040, 0x41b6, 0x2079, 0x0100, 0x0078, 0x41b8, 0x2079, 0x0200, + 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x41bf, 0x41c9, + 0x41c9, 0x41c9, 0x41c9, 0x41c9, 0x41c9, 0x41c7, 0x41c7, 0x1078, + 0x290c, 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, + 0x4218, 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, + 0xa086, 0x1814, 0x00c0, 0x4218, 0x784b, 0x0004, 0x7848, 0xa084, + 0x0004, 0x00c0, 0x41de, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, + 0x00c0, 0x41e5, 0x7830, 0xd0bc, 0x00c0, 0x4218, 0x007e, 0x2001, + 0x4d04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x41fa, 0xb284, 0x0300, + 0x0078, 0x41fc, 0xb284, 0x0400, 0x0040, 0x4202, 0x0018, 0x4218, + 0x0078, 0x4204, 0x0028, 0x4218, 0x79e4, 0xa184, 0x0030, 0x0040, + 0x4218, 0x78ec, 0xa084, 0x0003, 0x0040, 0x4218, 0x681c, 0xd0ac, + 0x00c0, 0x4216, 0x1078, 0x42a2, 0x0078, 0x4218, 0x781b, 0x00f6, + 0x0f7f, 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4d01, 0x2004, 0xd0ac, + 0x00c0, 0x4294, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, + 0x8003, 0xb28c, 0x0300, 0x0040, 0x4231, 0xa0e0, 0x51c0, 0x0078, + 0x4233, 0xa0e0, 0x5240, 0x6004, 0xa084, 0x000a, 0x00c0, 0x4294, + 0x6108, 0xa194, 0xff00, 0x0040, 0x4294, 0xa18c, 0x00ff, 0x2001, + 0x000a, 0xa106, 0x0040, 0x425f, 0x2001, 0x000c, 0xa106, 0x0040, + 0x4263, 0x2001, 0x0012, 0xa106, 0x0040, 0x4267, 0x2001, 0x0014, + 0xa106, 0x0040, 0x426b, 0x2001, 0x0019, 0xa106, 0x0040, 0x426f, + 0x2001, 0x0032, 0xa106, 0x0040, 0x4273, 0x0078, 0x4277, 0x2009, + 0x000c, 0x0078, 0x4279, 0x2009, 0x0012, 0x0078, 0x4279, 0x2009, + 0x0014, 0x0078, 0x4279, 0x2009, 0x0019, 0x0078, 0x4279, 0x2009, + 0x0020, 0x0078, 0x4279, 0x2009, 0x003f, 0x0078, 0x4279, 0x2011, + 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, + 0x2061, 0x4d00, 0x6004, 0xd0bc, 0x0040, 0x4294, 0x6814, 0xd0fc, + 0x00c0, 0x428f, 0x60ea, 0x2061, 0x4d40, 0x0078, 0x4292, 0x60ee, + 0x2061, 0x4d80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0076, + 0x007c, 0x781b, 0x0075, 0x007c, 0x781b, 0x0064, 0x007c, 0x781b, + 0x0061, 0x007c, 0x2009, 0x4d19, 0x210c, 0xa186, 0x0000, 0x0040, + 0x42b4, 0xa186, 0x0001, 0x0040, 0x42b7, 0x701f, 0x000b, 0x7067, + 0x0001, 0x781b, 0x0047, 0x007c, 0x781b, 0x00ed, 0x007c, 0x701f, + 0x000a, 0x007c, 0x2009, 0x4d19, 0x210c, 0xa186, 0x0000, 0x0040, + 0x42cf, 0xa186, 0x0001, 0x0040, 0x42cc, 0x701f, 0x000b, 0x7067, + 0x0001, 0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, + 0x00ec, 0x007c, 0x781b, 0x00f6, 0x007c, 0x781b, 0x00f5, 0x007c, + 0x781b, 0x00c6, 0x007c, 0x781b, 0x00c5, 0x007c, 0x6818, 0xd0fc, + 0x0040, 0x42e4, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, + 0x007c, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x42fd, 0x7808, 0xc08c, + 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, + 0x0040, 0x42fd, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, + 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, 0x00c0, 0x4302, 0x2001, + 0x4d04, 0x2004, 0xd0ec, 0x0040, 0x4311, 0xb284, 0x0300, 0x0078, + 0x4313, 0xb284, 0x0400, 0x0040, 0x4319, 0x0098, 0x431d, 0x0078, + 0x431b, 0x00a8, 0x431d, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, + 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, + 0x0040, 0x4340, 0x007e, 0x2001, 0x4d04, 0x2004, 0xd0ec, 0x007f, + 0x0040, 0x4336, 0xb284, 0x0300, 0x0078, 0x4338, 0xb284, 0x0400, + 0x0040, 0x433e, 0x0098, 0x433a, 0x0078, 0x4340, 0x00a8, 0x433e, + 0x78ac, 0x007e, 0x7808, 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, + 0xa784, 0x0001, 0x00c0, 0x36fb, 0xa784, 0x0070, 0x0040, 0x4358, + 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x288d, 0x2d78, 0x2c68, 0x0c7f, + 0xa784, 0x0008, 0x0040, 0x4365, 0x784b, 0x0008, 0x78ec, 0xa084, + 0x0003, 0x0040, 0x2966, 0x0078, 0x4296, 0xa784, 0x0004, 0x0040, + 0x4394, 0x78b8, 0xa084, 0x4001, 0x0040, 0x4394, 0x784b, 0x0008, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x2966, 0x78e4, 0xa084, 0x0007, + 0xa086, 0x0001, 0x00c0, 0x4394, 0x78c0, 0xa685, 0x4800, 0x2030, + 0x7e5a, 0x781b, 0x00f6, 0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, + 0x0040, 0x4391, 0x681b, 0x0015, 0xd6f4, 0x0040, 0x4391, 0x681b, + 0x0007, 0x1078, 0x42a2, 0x007c, 0x681b, 0x0003, 0x7858, 0xa084, + 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, + 0x78ec, 0xa084, 0x0003, 0x0040, 0x3004, 0x007e, 0x2001, 0x4d04, + 0x2004, 0xd0ec, 0x007f, 0x0040, 0x43b1, 0xb284, 0x0300, 0x0078, + 0x43b3, 0xb284, 0x0400, 0x0040, 0x43b9, 0x0018, 0x2962, 0x0078, + 0x43bb, 0x0028, 0x2962, 0x0078, 0x4045, 0x6b14, 0x8307, 0xa084, + 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0040, 0x43cb, 0xa080, + 0x5240, 0x0078, 0x43cd, 0xa080, 0x51c0, 0x2060, 0x2048, 0x705a, + 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, + 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, + 0x9848, 0x0014, 0x0014, 0x990e, 0x98fa, 0x0014, 0x0014, 0x0080, + 0x00f9, 0x0100, 0x0402, 0x2008, 0xf880, 0x0018, 0xa20a, 0x0014, + 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, + 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, + 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, 0x3806, 0x8839, 0x20c4, + 0x0864, 0xa856, 0x3008, 0x28c1, 0x9d15, 0xa201, 0x300c, 0x2847, + 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, + 0x9cc8, 0xa8f3, 0x0864, 0xa844, 0x300c, 0xa801, 0x3008, 0x28e1, + 0x9cc8, 0x2021, 0xa81d, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, + 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x7942, 0x8020, + 0xa4a1, 0x882b, 0x1814, 0x883b, 0x80df, 0x94a1, 0x7027, 0x85f2, + 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa816, 0x883e, 0xa814, + 0x2001, 0xa812, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x7942, + 0x8020, 0xa4a1, 0x1814, 0x80df, 0x94a1, 0x883b, 0x7023, 0x8576, + 0x8677, 0xa802, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d15, 0x2044, + 0x2103, 0x20a2, 0x2081, 0xa8c3, 0xa207, 0x2901, 0xa80a, 0x0014, + 0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, + 0xa208, 0x856e, 0x866f, 0x7161, 0x0014, 0x0704, 0x3008, 0x9cc8, + 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, + 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, + 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, + 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, + 0x3008, 0x8000, 0x284a, 0x1011, 0xa8fc, 0x3008, 0x9d2d, 0x8000, + 0xa000, 0x2802, 0x1011, 0xa8fd, 0x9d33, 0xa8bd, 0x3008, 0x9d2d, + 0x283b, 0x1011, 0xa8fd, 0xa209, 0x0017, 0x300c, 0xa209, 0x8000, + 0x85a4, 0x1de2, 0xa209, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014, + 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, 0x18f2, 0x0014, 0xa20b, + 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d1f, 0x0704, 0xa206, 0x6865, + 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa, + 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021, 0x3008, 0x84a8, 0x11d6, + 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822, 0x0016, 0x7944, 0x8421, + 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944, 0x8421, 0xa0df, 0x9532, + 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4, 0xa084, 0x4600, 0x8004, + 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205, 0x00c0, 0x4517, 0x720c, + 0x82ff, 0x0040, 0x4512, 0x8aff, 0x00c0, 0x4517, 0x7200, 0xd284, + 0x00c0, 0x4517, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x7000, + 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084, 0x0040, 0x455a, 0x7108, + 0x0005, 0x7008, 0xa106, 0x00c0, 0x451f, 0xa184, 0x0003, 0x0040, + 0x458b, 0xa184, 0x01e0, 0x00c0, 0x458b, 0xd1f4, 0x00c0, 0x451f, + 0xa184, 0x3000, 0xa086, 0x1000, 0x0040, 0x451f, 0x2011, 0x0180, + 0x710c, 0x8211, 0x0040, 0x4544, 0x7008, 0xd0f4, 0x00c0, 0x451f, + 0x700c, 0xa106, 0x0040, 0x4539, 0x7007, 0x0012, 0x7108, 0x0005, + 0x7008, 0xa106, 0x00c0, 0x4546, 0xa184, 0x0003, 0x0040, 0x458b, + 0xd194, 0x0040, 0x4546, 0xd1f4, 0x0040, 0x458b, 0x7007, 0x0002, + 0x0078, 0x451f, 0x7108, 0xd1fc, 0x0040, 0x4565, 0x1078, 0x46e0, + 0x8aff, 0x0040, 0x4501, 0x0078, 0x455a, 0x700c, 0xa08c, 0x03ff, + 0x0040, 0x4590, 0x7004, 0xd084, 0x0040, 0x4582, 0x7014, 0xa005, + 0x00c0, 0x457e, 0x7010, 0x7310, 0xa306, 0x00c0, 0x4572, 0x2300, + 0xa005, 0x0040, 0x4582, 0xa102, 0x00c8, 0x455a, 0x7007, 0x0010, + 0x0078, 0x458b, 0x8aff, 0x0040, 0x4590, 0x1078, 0x48e7, 0x00c0, + 0x4585, 0x0040, 0x455a, 0x1078, 0x4629, 0x127f, 0x2000, 0x007c, + 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x459f, 0x1078, 0x46e0, + 0x0078, 0x4590, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0xa205, + 0x00c0, 0x458b, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x6428, + 0x84ff, 0x0040, 0x45d3, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, + 0x45e3, 0x273c, 0x87fb, 0x00c0, 0x45c1, 0x0048, 0x45b9, 0x1078, + 0x290c, 0x609c, 0xa075, 0x0040, 0x45d3, 0x0078, 0x45ac, 0x2039, + 0x45d8, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, + 0x0040, 0x45d3, 0x8738, 0x2704, 0xa005, 0x00c0, 0x45c2, 0x709c, + 0xa075, 0x00c0, 0x45ac, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, + 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, + 0x0015, 0x001b, 0x0000, 0x0000, 0x45d8, 0x45d5, 0x0000, 0x0000, + 0x8000, 0x0000, 0x45d8, 0x0000, 0x45e0, 0x45dd, 0x0000, 0x0000, + 0x0000, 0x0000, 0x45e0, 0x0000, 0x45db, 0x45db, 0x0000, 0x0000, + 0x8000, 0x0000, 0x45db, 0x0000, 0x45e1, 0x45e1, 0x0000, 0x0000, + 0x0000, 0x0000, 0x45e1, 0x2079, 0x4d00, 0x2071, 0x0010, 0x7007, + 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x7810, 0xd0ec, 0x0040, + 0x4617, 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, 0x461b, 0x2009, + 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, + 0x0000, 0x8109, 0x0040, 0x4628, 0x2071, 0x0020, 0x0078, 0x461b, + 0x007c, 0x7004, 0x8004, 0x00c8, 0x46b2, 0x7108, 0x7008, 0xa106, + 0x00c0, 0x462d, 0xa184, 0x01e0, 0x0040, 0x463a, 0x1078, 0x4723, + 0x0078, 0x46da, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, + 0xa106, 0x00c0, 0x463e, 0xa184, 0x01e0, 0x0040, 0x464b, 0x1078, + 0x4723, 0x0078, 0x46da, 0x7810, 0xd0ec, 0x0040, 0x4665, 0x2001, + 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0, 0x4669, 0xa184, 0x4000, + 0x0040, 0x466d, 0xa382, 0x0003, 0x00c8, 0x466d, 0xa184, 0x0004, + 0x0040, 0x463e, 0x8318, 0x0078, 0x463e, 0x7814, 0xd0ec, 0x00c0, + 0x466d, 0xa184, 0x4000, 0x00c0, 0x463e, 0xa19c, 0x300c, 0xa386, + 0x2004, 0x0040, 0x468a, 0xa386, 0x0008, 0x0040, 0x4695, 0x7004, + 0xd084, 0x00c0, 0x4686, 0x7108, 0x7008, 0xa106, 0x00c0, 0x467b, + 0xa184, 0x0003, 0x0040, 0x4686, 0x0078, 0x4723, 0xa386, 0x200c, + 0x00c0, 0x463e, 0x7200, 0x8204, 0x0048, 0x4695, 0x730c, 0xa384, + 0x03ff, 0x0040, 0x4695, 0x1078, 0x290c, 0x7108, 0x7008, 0xa106, + 0x00c0, 0x4695, 0xa184, 0x01e0, 0x0040, 0x46a2, 0x1078, 0x4723, + 0x0078, 0x46da, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x46b2, + 0x7310, 0x7014, 0xa305, 0x0040, 0x46b2, 0x710c, 0xa184, 0x03ff, + 0x00c0, 0x4629, 0x7108, 0x7008, 0xa106, 0x00c0, 0x46b2, 0xa184, + 0x01e0, 0x0040, 0x46bf, 0x1078, 0x4723, 0x0078, 0x46da, 0x7007, + 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x46c3, 0x7108, + 0x7008, 0xa106, 0x00c0, 0x46c7, 0xa184, 0x01e0, 0x0040, 0x46d4, + 0x1078, 0x4723, 0x0078, 0x46da, 0x7007, 0x0012, 0x7108, 0x8103, + 0x0048, 0x46c7, 0x7003, 0x0008, 0x007c, 0x7108, 0x0078, 0x46e0, + 0xa184, 0x01e0, 0x00c0, 0x4723, 0x7108, 0xa184, 0x01e0, 0x00c0, + 0x4723, 0xa184, 0x0007, 0x0079, 0x46ed, 0x46f7, 0x4707, 0x46f5, + 0x4707, 0x46f5, 0x4765, 0x46f5, 0x4763, 0x1078, 0x290c, 0x7004, + 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, 0x4702, 0x2049, + 0x0000, 0x007c, 0x1078, 0x48e7, 0x00c0, 0x4702, 0x007c, 0x7004, + 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x00c0, 0x471b, + 0x7108, 0x7008, 0xa106, 0x00c0, 0x4710, 0xa184, 0x0003, 0x0040, + 0x471b, 0x0078, 0x4723, 0x8aff, 0x0040, 0x4722, 0x1078, 0x48e7, + 0x00c0, 0x471e, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, 0x4726, + 0x2091, 0x6000, 0x00e0, 0x472a, 0x2091, 0x6000, 0x7007, 0x0012, + 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x4732, 0x7007, 0x0012, + 0x7108, 0xd1fc, 0x00c0, 0x4736, 0x7003, 0x0000, 0x7000, 0xa005, + 0x00c0, 0x474a, 0x7004, 0xa005, 0x00c0, 0x474a, 0x700c, 0xa005, + 0x0040, 0x474c, 0x0078, 0x472e, 0x2049, 0x0000, 0xb284, 0x0100, + 0x0040, 0x4756, 0x2001, 0x0000, 0x0078, 0x4758, 0x2001, 0x0001, + 0x1078, 0x419b, 0x681b, 0x0002, 0x2051, 0x0000, 0x007c, 0x1078, + 0x290c, 0x1078, 0x290c, 0x1078, 0x47ad, 0x7210, 0x7114, 0x700c, + 0xa09c, 0x03ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, + 0x47ad, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, + 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4788, 0x00c8, 0x4788, + 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x476f, + 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4794, + 0xa7ba, 0x45dd, 0x0078, 0x4796, 0xa7ba, 0x45d5, 0x007f, 0xa73d, + 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108, 0x7008, 0xa106, + 0x00c0, 0x479d, 0xa184, 0x01e0, 0x0040, 0x47a8, 0x1078, 0x4723, + 0x7007, 0x0012, 0x1078, 0x4629, 0x007c, 0x8a50, 0x8739, 0x2704, + 0xa004, 0x00c0, 0x47c1, 0x6000, 0xa064, 0x00c0, 0x47b8, 0x2d60, + 0x6004, 0xa084, 0x000f, 0xa080, 0x45f3, 0x203c, 0x87fb, 0x1040, + 0x290c, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, + 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, + 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084, 0x0008, + 0x007f, 0x0040, 0x47df, 0xa0b8, 0x45dd, 0x0078, 0x47e1, 0xa0b8, + 0x45d5, 0xb284, 0x0100, 0x0040, 0x47e8, 0x7e20, 0x0078, 0x47e9, + 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x47f0, 0xc685, + 0x2400, 0xa305, 0x0040, 0x481a, 0x2c58, 0x2704, 0x6104, 0xac60, + 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, + 0x0040, 0x480a, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, + 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, + 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x4912, + 0x0078, 0x481c, 0x1078, 0x48e7, 0x00c0, 0x481a, 0x127f, 0x2000, + 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, + 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0, 0x482b, 0x7003, + 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, + 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, 0x0d7f, 0x7e20, 0xb284, + 0x0100, 0x00c0, 0x4844, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0ac, + 0x00c0, 0x484f, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, 0x6828, + 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x45e3, 0x273c, + 0x87fb, 0x00c0, 0x4865, 0x0048, 0x485f, 0x1078, 0x290c, 0x689c, + 0xa065, 0x0040, 0x4869, 0x0078, 0x4852, 0x1078, 0x48e7, 0x00c0, + 0x4865, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, 0x0d7e, + 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, 0x7e20, + 0xb284, 0x0100, 0x00c0, 0x487d, 0x7e24, 0x0d7f, 0x037f, 0x047f, + 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x488b, 0xc685, 0x7003, + 0x0000, 0x7007, 0x0004, 0x2049, 0x486c, 0x6828, 0xa055, 0x0d7e, + 0x0040, 0x48e3, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, + 0x45e3, 0x273c, 0x87fb, 0x00c0, 0x48a8, 0x0048, 0x48a1, 0x1078, + 0x290c, 0x709c, 0xa075, 0x2060, 0x0040, 0x48e3, 0x0078, 0x4894, + 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x48c1, + 0x8a51, 0x00c0, 0x48b5, 0x1078, 0x290c, 0x8738, 0x2704, 0xa005, + 0x00c0, 0x48a9, 0x709c, 0xa075, 0x2060, 0x0040, 0x48e3, 0x0078, + 0x4894, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, + 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x48d0, 0x1078, 0x290c, + 0xb284, 0x0100, 0x0040, 0x48de, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x00c0, 0x48de, 0x2071, 0x0050, 0x0078, 0x48e0, 0x2071, 0x0020, + 0x0d7f, 0x0078, 0x47f0, 0x0d7f, 0x127f, 0x2000, 0x007c, 0x7008, + 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x48f0, 0xa006, 0x007c, + 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0, 0x48f7, 0x007c, 0x2704, + 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, 0x7012, 0x780c, + 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x490a, 0x7810, 0x7022, + 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, + 0x2079, 0x4d00, 0x8a51, 0x0040, 0x4936, 0x8738, 0x2704, 0xa005, + 0x00c0, 0x4928, 0x609c, 0xa005, 0x0040, 0x4937, 0x2060, 0x6004, + 0xa084, 0x000f, 0xa080, 0x45e3, 0x203c, 0x87fb, 0x1040, 0x290c, + 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x4932, 0xa006, + 0x0078, 0x4937, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, + 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4, 0xa084, 0x4600, + 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, + 0x494f, 0x6828, 0xa005, 0x0040, 0x495f, 0x0078, 0x4517, 0x7108, + 0xd1fc, 0x0040, 0x4957, 0x1078, 0x46e0, 0x0078, 0x4944, 0x7007, + 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4959, 0x1078, 0x46e0, 0x7008, + 0xa086, 0x0008, 0x00c0, 0x4944, 0x7000, 0xa005, 0x00c0, 0x4944, + 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x127e, + 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4, 0xa084, 0x4600, + 0x8004, 0x2090, 0x0d7f, 0x2049, 0x496f, 0xad80, 0x0011, 0x20a0, + 0xb284, 0x0100, 0x0040, 0x4992, 0x2001, 0x4d04, 0x2004, 0xd0ec, + 0x0040, 0x498e, 0x2099, 0x0031, 0x0078, 0x4994, 0x2099, 0x0032, + 0x0078, 0x4994, 0x2099, 0x0031, 0x700c, 0xa084, 0x03ff, 0x682a, + 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040, 0x49a3, + 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff, 0x0040, 0x49af, + 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x49aa, 0x0c7f, + 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, + 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, + 0x00c0, 0x49d1, 0x7974, 0x70d0, 0xa106, 0x00c0, 0x49d1, 0x781c, + 0xa005, 0x0040, 0x49d1, 0x781f, 0x0000, 0x0068, 0x49d1, 0x2091, + 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, 0x4a59, 0x7834, 0x7832, + 0x7810, 0xd0ec, 0x00c0, 0x4a52, 0x2061, 0x72c0, 0x2069, 0x4d80, + 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x49eb, 0x8001, 0x68d2, 0x00c0, + 0x49eb, 0x1078, 0x4c22, 0x6800, 0xa084, 0x000f, 0x0040, 0x4a00, + 0xa086, 0x0001, 0x0040, 0x4a00, 0x6844, 0xa00d, 0x0040, 0x4a00, + 0x2104, 0xa005, 0x0040, 0x4a00, 0x8001, 0x200a, 0x0040, 0x4b95, + 0x6814, 0xa005, 0x0040, 0x4a25, 0x8001, 0x6816, 0x00c0, 0x4a25, + 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, 0x4a1a, 0x7810, 0xd0ec, + 0x0040, 0x4a16, 0x2079, 0x0100, 0x0078, 0x4a1c, 0x2079, 0x0200, + 0x0078, 0x4a1c, 0x2079, 0x0100, 0x1078, 0x42fe, 0x0f7f, 0x6864, + 0xa005, 0x0040, 0x4a25, 0x1078, 0x25ea, 0x6880, 0xa005, 0x0040, + 0x4a32, 0x8001, 0x6882, 0x00c0, 0x4a32, 0x6867, 0x0000, 0x68d4, + 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, 0x4a4f, 0xc0fc, 0x68d6, + 0x20a9, 0x0200, 0x6034, 0xa005, 0x0040, 0x4a4b, 0x8001, 0x6036, + 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x4a4b, 0x6010, 0xa005, 0x0040, + 0x4a4b, 0x1078, 0x25ea, 0xace0, 0x0010, 0x00f0, 0x4a3a, 0xd7fc, + 0x0040, 0x4a59, 0x2061, 0x52c0, 0x2069, 0x4d40, 0xc7fc, 0x0078, + 0x49e1, 0x1078, 0x4a95, 0x7838, 0x8001, 0x783a, 0x00c0, 0x4a7b, + 0x783c, 0x783a, 0x2061, 0x52c0, 0x2069, 0x4d40, 0xc7fc, 0x680c, + 0xa005, 0x0040, 0x4a6d, 0x1078, 0x4aec, 0xd7fc, 0x00c0, 0x4a7b, + 0x7810, 0xd0ec, 0x00c0, 0x4a7b, 0x2061, 0x72c0, 0x2069, 0x4d80, + 0xc7fd, 0x0078, 0x4a67, 0x7814, 0xd0e4, 0x00c0, 0x4a7f, 0x7810, + 0xd0cc, 0x0040, 0x4a92, 0xd0ac, 0x00c0, 0x4a8b, 0xd0a4, 0x0040, + 0x4a92, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0068, 0x4a91, 0x1078, + 0x2356, 0x007c, 0x2091, 0x8001, 0x007c, 0x7840, 0x8001, 0x7842, + 0x00c0, 0x4aeb, 0x7844, 0x7842, 0x2091, 0x8000, 0x2061, 0x52c0, + 0x2069, 0x4d40, 0xc7fc, 0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040, + 0x4aab, 0x2079, 0x0100, 0x68d8, 0xa005, 0x0040, 0x4ab7, 0x7de0, + 0xa504, 0x00c0, 0x4ab7, 0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079, + 0x4d00, 0x6810, 0xa005, 0x00c0, 0x4abf, 0x2001, 0x0101, 0x8001, + 0x6812, 0xd7fc, 0x0040, 0x4ac8, 0xa080, 0x93d0, 0x0078, 0x4aca, + 0xa080, 0x92c0, 0x2040, 0x2004, 0xa065, 0x0040, 0x4adb, 0x6024, + 0xa005, 0x0040, 0x4ad7, 0x8001, 0x6026, 0x0040, 0x4b37, 0x6000, + 0x2c40, 0x0078, 0x4acc, 0xd7fc, 0x00c0, 0x4aeb, 0x7810, 0xd0ec, + 0x00c0, 0x4aeb, 0x2061, 0x72c0, 0x2069, 0x4d80, 0xc7fd, 0x2079, + 0x0200, 0x0078, 0x4aab, 0x007c, 0x2009, 0x0000, 0x20a9, 0x0200, + 0x6008, 0xd09c, 0x0040, 0x4b23, 0x6024, 0xa005, 0x0040, 0x4afc, + 0x8001, 0x6026, 0x0078, 0x4b21, 0x6008, 0xc09c, 0xd084, 0x00c0, + 0x4b04, 0xd0ac, 0x0040, 0x4b1b, 0x600a, 0x6004, 0xa06d, 0x0040, + 0x4b23, 0x0c7e, 0x017e, 0x6010, 0x8001, 0x6012, 0x1078, 0x3d56, + 0x2d00, 0x2c68, 0x2060, 0x1078, 0x1e42, 0x1078, 0x2004, 0x017f, + 0x0c7f, 0x0078, 0x4b23, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, + 0x4b23, 0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0, 0x4af0, 0xa184, + 0x0001, 0x0040, 0x4b32, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x25ea, + 0x0078, 0x4b33, 0x690e, 0x007c, 0x00c0, 0x4b33, 0x786c, 0x6800, + 0xa005, 0x0040, 0x4b3f, 0x684c, 0xac06, 0x0040, 0x4b95, 0x6864, + 0xa005, 0x0040, 0x4b47, 0x6027, 0x0001, 0x0078, 0x4b94, 0x2c00, + 0x687e, 0x6714, 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, - 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f76, 0x1078, - 0x1e02, 0x6818, 0xa005, 0x0040, 0x48d7, 0x8001, 0x681a, 0x6808, - 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, - 0x48e3, 0x1078, 0x28ec, 0x6812, 0x00c0, 0x48e9, 0x7910, 0xc1a5, - 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x202a, - 0xd7fc, 0x00c0, 0x48f7, 0x2069, 0x4a40, 0x0078, 0x48f9, 0x2069, - 0x4a80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4903, - 0x697a, 0x2001, 0x0004, 0x2708, 0x1078, 0x25d1, 0x2091, 0x8001, - 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0, 0x491b, 0x7810, - 0xd0ec, 0x0040, 0x4917, 0x2069, 0x0100, 0x0078, 0x491d, 0x2069, - 0x0200, 0x0078, 0x491d, 0x2069, 0x0100, 0x1078, 0x2881, 0x601b, - 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, - 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, - 0xd0b4, 0x0040, 0x494b, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, - 0xd094, 0x0040, 0x493d, 0x00f0, 0x4937, 0x684b, 0x0009, 0x20a9, - 0x0014, 0x6848, 0xd084, 0x0040, 0x4947, 0x00f0, 0x4941, 0x20a9, - 0x00fa, 0x00f0, 0x4949, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, - 0x0047, 0x0d7f, 0x6867, 0x0007, 0x2091, 0x8001, 0x007c, 0x2079, - 0x4a00, 0x1078, 0x498b, 0x1078, 0x4971, 0x1078, 0x497e, 0x2009, - 0x0002, 0x2069, 0x4a80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, - 0x0000, 0x8109, 0x0040, 0x4970, 0x2069, 0x4a40, 0x0078, 0x4963, - 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4979, 0x2019, 0x00cc, 0x0078, - 0x497b, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4, - 0x00c0, 0x4986, 0x2019, 0x0040, 0x0078, 0x4988, 0x2019, 0x0026, - 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4993, 0x2019, - 0x3f94, 0x0078, 0x4995, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c, - 0x6950, 0xa185, 0x0000, 0x0040, 0x49ad, 0x0c7e, 0x6ac0, 0x2264, - 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, - 0x8109, 0x00c0, 0x499f, 0x6952, 0x0c7f, 0x007c, 0x70ec, 0xd0dc, - 0x00c0, 0x49b7, 0xd0d4, 0x0040, 0x49d6, 0x0078, 0x49d9, 0x7810, - 0xd0ec, 0x0040, 0x49c2, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x49dd, - 0x0078, 0x49d9, 0xae8e, 0x0100, 0x0040, 0x49ce, 0x7814, 0xc0f5, - 0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0x7814, 0xc0fd, - 0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0xd0e4, 0x0040, - 0x49df, 0x7804, 0xd08c, 0x0040, 0x49df, 0x681f, 0x000c, 0x70a0, - 0x70a2, 0x007c, 0x699a + 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x1078, 0x1dcb, 0x6818, + 0xa005, 0x0040, 0x4b65, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, + 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, 0x4b71, 0x1078, + 0x290c, 0x6812, 0x00c0, 0x4b77, 0x7910, 0xc1a5, 0x7912, 0x602f, + 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x2013, 0xd7fc, 0x00c0, + 0x4b85, 0x2069, 0x4d40, 0x0078, 0x4b87, 0x2069, 0x4d80, 0x6910, + 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4b91, 0x697a, 0x2001, + 0x0004, 0x2708, 0x1078, 0x25dd, 0x007c, 0x0d7e, 0x694c, 0x2160, + 0xd7fc, 0x00c0, 0x4ba7, 0x7810, 0xd0ec, 0x0040, 0x4ba3, 0x2069, + 0x0100, 0x0078, 0x4ba9, 0x2069, 0x0200, 0x0078, 0x4ba9, 0x2069, + 0x0100, 0x1078, 0x288d, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, + 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, + 0x0000, 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, + 0xd0b4, 0x0040, 0x4bdb, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, + 0xd094, 0x0040, 0x4bcd, 0x00f0, 0x4bc7, 0x684b, 0x0009, 0x20a9, + 0x0014, 0x6848, 0xd084, 0x0040, 0x4bd7, 0x00f0, 0x4bd1, 0x20a9, + 0x00fa, 0x00f0, 0x4bd9, 0x681b, 0x0047, 0x0d7f, 0x6867, 0x0007, + 0x007c, 0x2079, 0x4d00, 0x1078, 0x4c15, 0x1078, 0x4bfb, 0x1078, + 0x4c08, 0x2009, 0x0002, 0x2069, 0x4d80, 0x680f, 0x0000, 0x6813, + 0x0000, 0x6817, 0x0000, 0x8109, 0x0040, 0x4bfa, 0x2069, 0x4d40, + 0x0078, 0x4bed, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4c03, 0x2019, + 0x00cc, 0x0078, 0x4c05, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, + 0x7814, 0xd0e4, 0x00c0, 0x4c10, 0x2019, 0x0040, 0x0078, 0x4c12, + 0x2019, 0x0026, 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, + 0x4c1d, 0x2019, 0x3f94, 0x0078, 0x4c1f, 0x2019, 0x2624, 0x7b32, + 0x7b36, 0x007c, 0x6950, 0xa185, 0x0000, 0x0040, 0x4c37, 0x0c7e, + 0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, + 0x600a, 0x8210, 0x8109, 0x00c0, 0x4c29, 0x6952, 0x0c7f, 0x007c, + 0x70ec, 0xd0dc, 0x00c0, 0x4c41, 0xd0d4, 0x0040, 0x4c64, 0x0078, + 0x4c67, 0x2008, 0x7810, 0xd0ec, 0x0040, 0x4c50, 0xd1c4, 0x00c0, + 0x4c6f, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x4c6b, 0x0078, 0x4c67, + 0xae8e, 0x0100, 0x0040, 0x4c5c, 0x7814, 0xc0f5, 0x7816, 0xd0d4, + 0x00c0, 0x4c6b, 0x0078, 0x4c67, 0x7814, 0xc0fd, 0x7816, 0xd0d4, + 0x00c0, 0x4c6b, 0x0078, 0x4c67, 0xd0e4, 0x0040, 0x4c6d, 0x7804, + 0xd08c, 0x0040, 0x4c6d, 0x681f, 0x000c, 0x70a0, 0x70a2, 0x007c, + 0x3782 }; -unsigned short fw1280ei_length01 = 0x39e3; +#ifdef UNIQUE_FW_NAME +unsigned short fw1280ei_length01 = 0x3c71; +#else +unsigned short risc_code_length01 = 0x3c71; +#endif diff -urN linux-2.4.0-test12/drivers/scsi/qla1280.c linux-2.4.0-test12-lia/drivers/scsi/qla1280.c --- linux-2.4.0-test12/drivers/scsi/qla1280.c Wed Dec 13 17:30:12 2000 +++ linux-2.4.0-test12-lia/drivers/scsi/qla1280.c Thu Dec 14 14:42:57 2000 @@ -1,162 +1,84 @@ /******************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP1x80/1x160 device driver for Linux 2.3.x (redhat 6.X). - * - * COPYRIGHT (C) 1999-2000 QLOGIC CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the Qlogic's Linux Software License. See below. - * - * This program is WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistribution's or source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - ********************************************************************************/ - -/***************************************************************************************** - QLOGIC CORPORATION SOFTWARE - "GNU" GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION - AND MODIFICATION - -This GNU General Public License ("License") applies solely to QLogic Linux -Software ("Software") and may be distributed under the terms of this License. - -1. You may copy and distribute verbatim copies of the Software's source code as -you receive it, in any medium, provided that you conspicuously and appropriately -publish on each copy an appropriate copyright notice and disclaimer of warranty; -keep intact all the notices that refer to this License and to the absence of any -warranty; and give any other recipients of the Software a copy of this License along -with the Software. - -You may charge a fee for the physical act of transferring a copy, and you may at your -option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Software or any portion of it, thus forming -a work based on the Software, and copy and distribute such modifications or work under -the terms of Section 1 above, provided that you also meet all of these conditions: - -* a) You must cause the modified files to carry prominent notices stating that you -changed the files and the date of any change. - -* b) You must cause any work that you distribute or publish that in whole or in part -contains or is derived from the Software or any part thereof, to be licensed as a -whole at no charge to all third parties under the terms of this License. - -* c) If the modified Software normally reads commands interactively when run, you -must cause it, when started running for such interactive use in the most ordinary way, -to print or display an announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide a warranty) and that -users may redistribute the Software under these conditions, and telling the user how to -view a copy of this License. (Exception:if the Software itself is interactive but does -not normally print such an announcement, your work based on the Software is not required -to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable sections of -that work are not derived from the Software, and can be reasonably considered independent -and separate works in themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you distribute the same -sections as part of a whole which is a work based on the Software, the distribution of the -whole must be on the terms of this License, whose permissions for other licensees extend -to the entire whole, and thus to each and every part regardless of who wrote it. - -3. You may copy and distribute the Software (or a work based on it, under Section 2) in -object code or executable form under the terms of Sections 1 and 2 above provided that -you also do one of the following: - -* a) Accompany it with the complete corresponding machine-readable source code, which must -be distributed under the terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or, - -* b) Accompany it with a written offer, valid for at least three years, to give any third -party, for a charge no more than your cost of physically performing source distribution, -a complete machine-readable copy of the corresponding source code, to be distributed under -the terms of Sections 1 and 2 above on a medium customarily used for software interchange; -or, - -* c) Accompany it with the information you received as to the offer to distribute -corresponding source code. (This alternative is allowed only for noncommercial distribution -and only if you received the Software in object code or executable form with such an offer, -in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for making modifications -to it. For an executable work, complete source code means all the source code for all -modules it contains, plus any associated interface definition files, plus the scripts used -to control compilation and installation of the executable. - -If distribution of executable or object code is made by offering access to copy from a -designated place, then offering equivalent access to copy the source code from the same -place counts as distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Software except as expressly -provided under this License. Any attempt otherwise to copy, modify, sublicense or -distribute the Software is void, and will automatically terminate your rights under this -License. However, parties who have received copies, or rights, from you under this License -will not have their licenses terminated so long as such parties remain in full compliance. - -5. This license grants you world wide, royalty free non-exclusive rights to modify or -distribute the Software or its derivative works. These actions are prohibited by law -if you do not accept this License. Therefore, by modifying or distributing the Software -(or any work based on the Software), you indicate your acceptance of this License to do -so, and all its terms and conditions for copying, distributing or modifying the Software -or works based on it. - -6. Each time you redistribute the Software (or any work based on the Software), the -recipient automatically receives a license from the original licensor to copy, distribute -or modify the Software subject to these terms and conditions. You may not impose any -further restrictions on the recipients' exercise of the rights granted herein. You are -not responsible for enforcing compliance by third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent infringement or for -any other reason (not limited to patent issues), conditions are imposed on you -(whether by court order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this License -and any other pertinent obligations, then as a consequence you may not distribute the -Software at all. - -If any portion of this section is held invalid or unenforceable under any particular -circumstance, the balance of the section is intended to apply and the section as a whole -is intended to apply in other circumstances. -NO WARRANTY - -11. THE SOFTWARE IS PROVIDED WITHOUT A WARRANTY OF ANY KIND. THERE IS NO -WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, -EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE -ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. -SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL -NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING -BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO -OPERATE WITH ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -END OF TERMS AND CONDITIONS - -*******************************************************************************************/ - +* QLOGIC LINUX SOFTWARE +* +* QLogic QLA1280 (Ultra2) and QLA12160 (Ultra3) SCSI driver +* Copyright (C) 2000 Qlogic Corporation +* (www.qlogic.com) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2, or (at your option) any +* later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +** +******************************************************************************/ +#define QLA1280_VERSION "3.19 Beta" /**************************************************************************** Revision History: - Rev. 3.00 Jan 17, 1999 DG Qlogic + Rev 3.19 Beta October 13, 2000 BN Qlogic + - Declare driver_template for new kernel + (2.4.0 and greater) scsi initialization scheme. + - Update /proc/scsi entry for 2.3.18 kernels and + above as qla1280 + Rev 3.18 Beta October 10, 2000 BN Qlogic + - Changed scan order of adapters to map + the QLA12160 followed by the QLA1280. + Rev 3.17 Beta September 18, 2000 BN Qlogic + - Removed warnings for 32 bit 2.4.x compiles + - Corrected declared size for request and response + DMA addresses that are kept in each ha + Rev. 3.16 Beta August 25, 2000 BN Qlogic + - Corrected 64 bit addressing issue on IA-64 + where the upper 32 bits were not properly + passed to the RISC engine. + Rev. 3.15 Beta August 22, 2000 BN Qlogic + - Modified qla1280_setup_chip to properly load + ISP firmware for greater that 4 Gig memory on IA-64 + Rev. 3.14 Beta August 16, 2000 BN Qlogic + - Added setting of dma_mask to full 64 bit + if flags.enable_64bit_addressing is set in NVRAM + Rev. 3.13 Beta August 16, 2000 BN Qlogic + - Use new PCI DMA mapping APIs for 2.4.x kernel + Rev. 3.12 July 18, 2000 Redhat & BN Qlogic + - Added check of pci_enable_device to detect() for 2.3.x + - Use pci_resource_start() instead of + pdev->resource[0].start in detect() for 2.3.x + - Updated driver version + Rev. 3.11 July 14, 2000 BN Qlogic + - Updated SCSI Firmware to following versions: + qla1x80: 8.13.08 + qla1x160: 10.04.08 + - Updated driver version to 3.11 + Rev. 3.10 June 23, 2000 BN Qlogic + - Added filtering of AMI SubSys Vendor ID devices + Rev. 3.9 + - DEBUG_QLA1280 undefined and new version BN Qlogic + Rev. 3.08b May 9, 2000 MD Dell + - Added logic to check against AMI subsystem vendor ID + Rev. 3.08 May 4, 2000 DG Qlogic + - Added logic to check for PCI subsystem ID. + Rev. 3.07 Apr 24, 2000 DG & BN Qlogic + - Updated SCSI Firmware to following versions: + qla12160: 10.01.19 + qla1280: 8.09.00 + Rev. 3.06 Apr 12, 2000 DG & BN Qlogic + - Internal revision; not released + Rev. 3.05 Mar 28, 2000 DG & BN Qlogic + - Edit correction for virt_to_bus and PROC. + Rev. 3.04 Mar 28, 2000 DG & BN Qlogic + - Merge changes from ia64 port. + Rev. 3.03 Mar 28, 2000 BN Qlogic + - Increase version to reflect new code drop with compile fix + of issue with inclusion of linux/spinlock for 2.3 kernels + Rev. 3.02 Mar 15, 2000 BN Qlogic + - Merge qla1280_proc_info from 2.10 code base + Rev. 3.01 Feb 10, 2000 BN Qlogic + - Corrected code to compile on a 2.2.x kernel. + Rev. 3.00 Jan 17, 2000 DG Qlogic - Added 64-bit support. Rev. 2.07 Nov 9, 1999 DG Qlogic - Added new routine to set target parameters for ISP12160. @@ -183,12 +105,11 @@ *****************************************************************************/ +#include #ifdef MODULE #include #endif -#define QLA1280_VERSION " 3.00-Beta" - #include #include #include @@ -207,8 +128,16 @@ #include #include #include -/* MRS #include */ +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) +#include +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) +#include # include #endif #include "sd.h" @@ -216,23 +145,16 @@ #include "hosts.h" #define UNIQUE_FW_NAME #include "qla1280.h" -#include "ql12160_fw.h" /* ISP RISC code */ +#include "ql12160_fw.h" /* ISP RISC codes */ #include "ql1280_fw.h" #include -#include /* for kmalloc() */ - - -#ifndef KERNEL_VERSION -# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -#endif - +#include /* * Compile time Options: * 0 - Disable and 1 - Enable */ -#define QLA1280_64BIT_SUPPORT 1 /* 64-bit Support */ #define QL1280_TARGET_MODE_SUPPORT 0 /* Target mode support */ #define WATCHDOGTIMER 0 #define MEMORY_MAPPED_IO 0 @@ -244,15 +166,16 @@ #define AUTO_ESCALATE_ABORT 0 /* Automatically escalate aborts */ #define STOP_ON_ERROR 0 /* Stop on aborts and resets */ #define STOP_ON_RESET 0 -#define STOP_ON_ABORT 0 -#undef DYNAMIC_MEM_ALLOC - -#define DEBUG_QLA1280 0 /* Debugging */ -/* #define CHECKSRBSIZE */ +#define STOP_ON_ABORT 0 + +#define DEBUG_QLA1280 0 -/* - * These macros to assist programming - */ +/*************** 64 BIT PCI DMA ******************************************/ +#define FORCE_64BIT_PCI_DMA 0 /* set to one for testing only */ +/* Applicable to 64 version of the Linux 2.4.x and above only */ +/* NVRAM bit nv->cntr_flags_1.enable_64bit_addressing should be used for */ +/* administrator control of PCI DMA width size per system configuration */ +/*************************************************************************/ #define BZERO(ptr, amt) memset(ptr, 0, amt) #define BCOPY(src, dst, amt) memcpy(dst, src, amt) @@ -260,19 +183,28 @@ #define KMFREE(ip,siz) kfree((ip)) #define SYS_DELAY(x) udelay(x);barrier() #define QLA1280_DELAY(sec) mdelay(sec * 1000) -#define VIRT_TO_BUS(a) virt_to_bus((a)) -#if QLA1280_64BIT_SUPPORT + +/* 3.16 */ +#if BITS_PER_LONG > 32 +#define pci_dma_lo32(a) (a & 0xffffffff) +#define pci_dma_hi32(a) ((a >> 32) & 0xffffffff) +#else +#define pci_dma_lo32(a) (a & 0xffffffff) +#define pci_dma_hi32(a) 0 +#endif + +#define VIRT_TO_BUS(a) virt_to_bus(((void *)a)) + #if BITS_PER_LONG <= 32 -#define VIRT_TO_BUS_LOW(a) (uint32_t)virt_to_bus((a)) +#define VIRT_TO_BUS_LOW(a) (uint32_t)virt_to_bus(((void *)a)) #define VIRT_TO_BUS_HIGH(a) (uint32_t)(0x0) #else -#define VIRT_TO_BUS_LOW(a) (uint32_t)(0xffffffff & virt_to_bus((a))) -#define VIRT_TO_BUS_HIGH(a) (uint32_t)(0xffffffff & (virt_to_bus((a))>>32)) +#define VIRT_TO_BUS_LOW(a) (uint32_t)(0xffffffff & virt_to_bus((void *)(a))) +#define VIRT_TO_BUS_HIGH(a) (uint32_t)(0xffffffff & (virt_to_bus((void *)(a))>>32)) #endif -#endif /* QLA1280_64BIT_SUPPORT */ -#define STATIC +#define STATIC #define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */ void qla1280_device_queue_depth(scsi_qla_host_t *, Scsi_Device *); @@ -285,11 +217,11 @@ #define LSB(x) (uint8_t)(x) #if BITS_PER_LONG <= 32 -#define LS_64BITS(x) (uint32_t)(x) -#define MS_64BITS(x) (uint32_t)(0x0) +#define LS_64BITS(x) (uint32_t)((unsigned long) x) +#define MS_64BITS(x) (uint32_t)((unsigned long) 0x0) #else -#define LS_64BITS(x) (uint32_t)(0xffffffff & (x)) -#define MS_64BITS(x) (uint32_t)(0xffffffff & ((x)>>32) ) +#define LS_64BITS(x) (uint32_t)(0xffffffff & ((unsigned long)x)) +#define MS_64BITS(x) (uint32_t)(0xffffffff & (((unsigned long)x)>>32) ) #endif /* @@ -300,9 +232,6 @@ STATIC void qla1280_putq_t(scsi_lu_t *, srb_t *); STATIC void qla1280_done_q_put(srb_t *, srb_t **, srb_t **); STATIC void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *); -#ifdef QLA1280_UNUSED -static void qla1280_dump_regs(struct Scsi_Host *host); -#endif #if STOP_ON_ERROR static void qla1280_panic(char *, struct Scsi_Host *host); #endif @@ -313,9 +242,6 @@ STATIC void qla1280_removeq(scsi_lu_t *q, srb_t *sp); STATIC void qla1280_mem_free(scsi_qla_host_t *ha); static void qla1280_do_dpc(void *p); -#ifdef QLA1280_UNUSED -static void qla1280_set_flags(char * s); -#endif static char *qla1280_get_token(char *, char *); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) STATIC inline void mdelay(int); @@ -339,9 +265,7 @@ STATIC uint8_t qla1280_device_reset(scsi_qla_host_t *, uint8_t, uint32_t); STATIC uint8_t qla1280_abort_device(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t); STATIC uint8_t qla1280_abort_command(scsi_qla_host_t *, srb_t *), -#if QLA1280_64BIT_SUPPORT qla1280_64bit_start_scsi(scsi_qla_host_t *, srb_t *), -#endif qla1280_32bit_start_scsi(scsi_qla_host_t *, srb_t *), qla1280_abort_isp(scsi_qla_host_t *); STATIC void qla1280_nv_write(scsi_qla_host_t *, uint16_t), @@ -374,12 +298,12 @@ qla1280_notify_ack(scsi_qla_host_t *, notify_entry_t *), qla1280_immed_notify(scsi_qla_host_t *, notify_entry_t *), qla1280_accept_io(scsi_qla_host_t *, ctio_ret_entry_t *), -#if QLA1280_64BIT_SUPPORT - qla1280_64bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t, - paddr32_t *), -#endif - qla1280_32bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t, - paddr32_t *), + qla1280_64bit_continue_io(scsi_qla_host_t *, + atio_entry_t *, uint32_t, + paddr32_t *), + qla1280_32bit_continue_io(scsi_qla_host_t *, + atio_entry_t *, uint32_t, + paddr32_t *), qla1280_atio_entry(scsi_qla_host_t *, atio_entry_t *), qla1280_notify_entry(scsi_qla_host_t *, notify_entry_t *); #endif /* QLA1280_TARGET_MODE_SUPPORT */ @@ -400,7 +324,7 @@ qla1280_dump_buffer(caddr_t, uint32_t); char debug_buff[80]; -#if DEBUG_QLA1280 +#if DEBUG_QLA1280 STATIC uint8_t ql_debug_print = 1; #else STATIC uint8_t ql_debug_print = 0; @@ -426,6 +350,22 @@ #endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) +/* + * Our directory Entry in /proc/scsi for the user to + * access the driver. + */ +/* Need to add in proc_fs.h PROC_SCSI_QL1280 */ +#define PROC_SCSI_QL1280 PROC_SCSI_QLOGICISP + +struct proc_dir_entry proc_scsi_qla1280 = { + PROC_SCSI_QL1280, 7, "qla1280", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif + /* We use the Scsi_Pointer structure that's included with each command * SCSI_Cmnd as a scratchpad for our SRB. * @@ -471,17 +411,17 @@ unsigned char *fwver; /* Ptr to F/W version array */ } qla_boards_t; -struct _qlaboards QLBoardTbl[NUM_OF_ISP_DEVICES] = +struct _qlaboards QL1280BoardTbl[NUM_OF_ISP_DEVICES] = { /* Name , Board PCI Device ID, Number of ports */ + {"QLA12160 ", QLA12160_DEVICE_ID, 2, + &fw12160i_code01[0], (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] }, {"QLA1080 ", QLA1080_DEVICE_ID, 1, &fw1280ei_code01[0], (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] }, {"QLA1240 ", QLA1240_DEVICE_ID, 2, &fw1280ei_code01[0], (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] }, {"QLA1280 ", QLA1280_DEVICE_ID, 2, &fw1280ei_code01[0], (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] }, - {"QLA12160 ", QLA12160_DEVICE_ID, 2, - &fw12160i_code01[0], (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] }, {"QLA10160 ", QLA10160_DEVICE_ID, 1, &fw12160i_code01[0], (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] }, {" ", 0, 0} @@ -567,152 +507,149 @@ * * Returns: *************************************************************************/ -#ifdef QLA1280_PROFILE -#define PROC_BUF (&qla1280_buffer[size]) -#define LUN_ID (targ_lun>>(MAX_T_BITS+MAX_L_BITS)),((targ_lun>>MAX_L_BITS)&0xf), targ_lun&0x7 -#endif +#define PROC_BUF (&qla1280_buffer[len]) int -qla1280_proc_info ( char *buffer, char **start, off_t offset, int length, - int hostno, int inout) -{ -#ifdef QLA1280_PROFILE +qla1280_proc_info( char *buffer, char **start, off_t offset, int length, + int hostno, int inout) { +#if QLA1280_PROFILE struct Scsi_Host *host; scsi_qla_host_t *ha; int size = 0; - int targ_lun; scsi_lu_t *up; - int no_devices; + int len = 0; + qla_boards_t *bdp; + uint32_t b, t, l; - printk("Entering proc_info 0x%p,0x%lx,0x%x,0x%x\n",buffer,offset,length,hostno); host = NULL; - /* find the host they want to look at */ - for(ha=qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno; ha=ha->next) + + /* Find the host that was specified */ + for( ha=qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno; ha=ha->next ) ; - if (!ha) - { - size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno); - if (size > length) - { + /* if host wasn't found then exit */ + if( !ha ) { + size = sprintf(buffer, "Can't find adapter for host number %d\n", hostno); + if( size > length ) { return (size); - } - else - { - return (length); + } else { + return (0); } } host = ha->host; - if (inout == TRUE) /* Has data been written to the file? */ - { - return (qla1280_set_info(buffer, length, host)); - } - /* compute number of active devices */ - no_devices = 0; - for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++) + if( inout == TRUE ) /* Has data been written to the file? */ { - if( (up = ha->dev[targ_lun]) == NULL ) - continue; - no_devices++; + printk("qla1280_proc: has data been written to the file. \n"); + return (qla1280_set_info(buffer, length, host)); } - /* size = 112 * no_devices; */ - size = 4096; - /* round up to the next page */ /* * if our old buffer is the right size use it otherwise * allocate a new one. */ - if (qla1280_buffer_size != size) - { + size = 4096; /* get a page */ + if( qla1280_buffer_size != size ) { /* deallocate this buffer and get a new one */ - if (qla1280_buffer != NULL) - { + if( qla1280_buffer != NULL ) { kfree(qla1280_buffer); qla1280_buffer_size = 0; } qla1280_buffer = kmalloc(size, GFP_KERNEL); } - if (qla1280_buffer == NULL) - { + if( qla1280_buffer == NULL ) { size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n", __LINE__); return size; } + /* save the size of our buffer */ qla1280_buffer_size = size; - size = 0; - size += sprintf(PROC_BUF, "Qlogic 1280/1080 SCSI driver version: "); /* 43 bytes */ - size += sprintf(PROC_BUF, "%5s, ", QLA1280_VERSION); /* 5 */ - size += sprintf(PROC_BUF, "Qlogic Firmware version: "); /* 25 */ - size += sprintf(PROC_BUF, "%2d.%2d.%2d",_firmware_version[0], /* 8 */ - ql12_firmware_version[1], - ql12_firmware_version[2]); - size += sprintf(PROC_BUF, "\n"); /* 1 */ - - size += sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", QLBoardTbl[ha->devnum].bdName); - size += sprintf(PROC_BUF, "Request Queue = 0x%lx, Response Queue = 0x%lx\n", + /* start building the print buffer */ + bdp = &QL1280BoardTbl[ha->devnum]; + size = sprintf(PROC_BUF, + "QLogic PCI to SCSI Adapter for ISP 1280/12160:\n" + " Firmware version: %2d.%02d.%02d, Driver version %s\n", bdp->fwver[0], bdp->fwver[1], bdp->fwver[2], QLA1280_VERSION); + + len += size; + + size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", bdp->bdName); + len += size; + size = sprintf(PROC_BUF, "Request Queue = 0x%lx, Response Queue = 0x%lx\n", ha->request_dma, ha->response_dma); - size += sprintf(PROC_BUF, "Request Queue count= 0x%x, Response Queue count= 0x%x\n", + len += size; + size = sprintf(PROC_BUF, "Request Queue count= 0x%lx, Response Queue count= 0x%lx\n", REQUEST_ENTRY_CNT, RESPONSE_ENTRY_CNT); - size += sprintf(PROC_BUF,"Number of pending commands = 0x%lx\n", ha->actthreads); - size += sprintf(PROC_BUF,"Number of queued commands = 0x%lx\n", ha->qthreads); - size += sprintf(PROC_BUF,"Number of free request entries = %d\n",ha->req_q_cnt); - size += sprintf(PROC_BUF, "\n"); /* 1 */ + len += size; + size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n", ha->actthreads); + len += size; + size = sprintf(PROC_BUF, "Number of queued commands = 0x%lx\n", ha->qthreads); + len += size; + size = sprintf(PROC_BUF, "Number of free request entries = %d\n",ha->req_q_cnt); + len += size; + size = sprintf(PROC_BUF, "\n"); /* 1 */ + len += size; - size += sprintf(PROC_BUF, "Attached devices:\n"); + size = sprintf(PROC_BUF, "SCSI device Information:\n"); + len += size; /* scan for all equipment stats */ - for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++) - { - if( (up = ha->dev[targ_lun]) == NULL ) + for (b = 0; b < MAX_BUSES; b++) + for (t = 0; t < MAX_TARGETS; t++) { + for( l = 0; l < MAX_LUNS; l++ ) { + up = (scsi_lu_t *) LU_Q(ha, b, t, l); + if( up == NULL ) continue; - if( up->io_cnt == 0 ) - { - size += sprintf(PROC_BUF,"(%2d:%2d:%2d) No stats\n",LUN_ID); + /* unused device/lun */ + if( up->io_cnt == 0 || up->io_cnt < 2 ) continue; - } /* total reads since boot */ /* total writes since boot */ /* total requests since boot */ - size += sprintf(PROC_BUF, "Total requests %ld,",up->io_cnt); + size = sprintf(PROC_BUF, "(%2d:%2d:%2d): Total reqs %ld,",b,t,l,up->io_cnt); + len += size; /* current number of pending requests */ - size += sprintf(PROC_BUF, "(%2d:%2d:%2d) pending requests %d,",LUN_ID,up->q_outcnt); + size = sprintf(PROC_BUF, " Pend reqs %d,",up->q_outcnt); + len += size; +#if 0 /* avg response time */ - size += sprintf(PROC_BUF, "Avg response time %ld%%,",(up->resp_time/up->io_cnt)*100); + size = sprintf(PROC_BUF, " Avg resp time %ld%%,",(up->resp_time/up->io_cnt)*100); + len += size; /* avg active time */ - size += sprintf(PROC_BUF, "Avg active time %ld%%\n",(up->act_time/up->io_cnt)*100); + size = sprintf(PROC_BUF, " Avg active time %ld%%\n",(up->act_time/up->io_cnt)*100); +#else + size = sprintf(PROC_BUF, "\n"); +#endif + len += size; + } + if( len >= qla1280_buffer_size ) + break; } - if (size >= qla1280_buffer_size) - { + if( len >= qla1280_buffer_size ) { printk(KERN_WARNING "qla1280: Overflow buffer in qla1280_proc.c\n"); } - if (offset > size - 1) - { + if( offset > len - 1 ) { kfree(qla1280_buffer); qla1280_buffer = NULL; qla1280_buffer_size = length = 0; *start = NULL; - } - else - { + } else { *start = &qla1280_buffer[offset]; /* Start of wanted data */ - if (size - offset < length) - { - length = size - offset; + if( len - offset < length ) { + length = len - offset; } } + return (length); +#else + return (0); #endif - return (length); } - /************************************************************************** * qla1280_detect * This routine will probe for Qlogic 1280 SCSI host adapters. @@ -735,6 +672,9 @@ scsi_qla_host_t *ha, *cur_ha; struct _qlaboards *bdp; int i, j; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + unsigned short subsys; +#endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,95) unsigned int piobase; unsigned char pci_bus, pci_devfn, pci_irq; @@ -747,13 +687,19 @@ #else int index; #endif +#ifndef PCI_VENDOR_ID_AMI +#define PCI_VENDOR_ID_AMI 0x101e +#endif ENTER("qla1280_detect"); + if (sizeof(srb_t) > sizeof(Scsi_Pointer) ) + printk("qla1280_detect: [WARNING] srb_t Must Be Redefined"); + #ifdef CHECKSRBSIZE if (sizeof(srb_t) > sizeof(Scsi_Pointer) ) { - printk("Redefine SRB - its too big"); + printk("qla1280_detect: srb_t Must Be Redefined - its too big"); return 0; } #endif @@ -784,40 +730,77 @@ "qla1280: insmod or else it might trash certain memory areas.\n"); #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) if ((int) !pcibios_present()) +#else + if (!pci_present()) +#endif { - printk("scsi: PCI not present\n"); - return 0; - } /* end of IF */ - bdp = &QLBoardTbl[0]; + printk("scsi: PCI not present\n"); + return 0; + } + + bdp = &QL1280BoardTbl[0]; qla1280_hostlist = NULL; -#if 0 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) template->proc_dir = &proc_scsi_qla1280; #else template->proc_name = "qla1280"; #endif - /* Try and find each different type of adapter we support */ for( i=0; bdp->device_id != 0 && i < NUM_OF_ISP_DEVICES; i++, bdp++ ) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) + /* PCI_SUBSYSTEM_IDS supported */ + while ((pdev = pci_find_subsys(QLA1280_VENDOR_ID, + bdp->device_id, PCI_ANY_ID, PCI_ANY_ID, pdev) )) { + if (pci_enable_device(pdev)) continue; +#else while ((pdev = pci_find_device(QLA1280_VENDOR_ID, bdp->device_id, pdev ) )) { - if (pci_enable_device(pdev)) continue; -#else +#endif /* 2,3,18 */ +#else /* less than 2,1,95 */ while (!(pcibios_find_device(QLA1280_VENDOR_ID, bdp->device_id, index++, &pci_bus, &pci_devfn)) ) { -#endif +#endif /* 2,1,95 */ /* found a adapter */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) + printk("qla1280: detect() found an HBA\n"); + printk("qla1280: VID=%x DID=%x SSVID=%x SSDID=%x\n", + pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device); + /* If it's an AMI SubSys Vendor ID adapter, skip it. */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) + { + printk("qla1280: Skip AMI SubSys Vendor ID Chip\n"); + continue; + } +#else +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, + &subsys); + /* Bypass all AMI SUBSYS VENDOR IDs */ + if (subsys == PCI_VENDOR_ID_AMI) + { + printk("qla1280: Skip AMI SubSys Vendor ID Chip\n"); + continue; + } +#endif /* 2,1,95 */ +#endif /* 2,3,18 */ host = scsi_register(template, sizeof(scsi_qla_host_t)); ha = (scsi_qla_host_t *) host->hostdata; /* Clear our data area */ for( j =0, cp = (char *)ha; j < sizeof(scsi_qla_host_t); j++) - *cp = 0; + *cp++ = 0; /* Sanitize the information from PCI BIOS. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95) host->irq = pdev->irq; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + host->io_port = (unsigned int) pdev->base_address[0]; +#else host->io_port = pci_resource_start(pdev, 0); +#endif ha->pci_bus = pdev->bus->number; ha->pci_device_fn = pdev->devfn; ha->pdev = pdev; @@ -834,35 +817,35 @@ ha->devnum = i; if( qla1280_mem_alloc(ha) ) { - printk(KERN_INFO "qla1280: Failed to allocate memory for adapter\n"); + printk(KERN_INFO "qla1280: Failed to get memory\n"); } ha->ports = bdp->numPorts; + /* following needed for all cases of OS versions */ + host->io_port &= PCI_BASE_ADDRESS_IO_MASK; ha->iobase = (device_reg_t *) host->io_port; ha->host = host; ha->host_no = host->host_no; /* load the F/W, read paramaters, and init the H/W */ + ha->instance = num_hosts; if (qla1280_initialize_adapter(ha)) { - - printk(KERN_INFO "qla1280: Failed to initialized adapter\n"); - qla1280_mem_free(ha); - scsi_unregister(host); - continue; + printk(KERN_INFO "qla1280: Failed to initialize adapter\n"); + qla1280_mem_free(ha); + scsi_unregister(host); + continue; } host->max_channel = bdp->numPorts-1; - ha->instance = num_hosts; /* Register our resources with Linux */ if( qla1280_register_with_Linux(ha, bdp->numPorts-1) ) { - printk(KERN_INFO "qla1280: Failed to register our resources\n"); - qla1280_mem_free(ha); - scsi_unregister(host); - continue; + printk(KERN_INFO "qla1280: Failed to register resources\n"); + qla1280_mem_free(ha); + scsi_unregister(host); + continue; } - reg = ha->iobase; /* Disable ISP interrupts. */ qla1280_disable_intrs(ha); @@ -919,8 +902,11 @@ host->can_queue = 0xfffff; /* unlimited */ host->cmd_per_lun = 1; host->select_queue_depths = qla1280_select_queue_depth; - host->n_io_port = 0xFF; - host->base = (unsigned long) ha->mmpbase; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + host->base = (unsigned char *) ha->mmpbase; +#else + host->base = (u_long) ha->mmpbase; +#endif host->max_channel = maxchannels; host->max_lun = MAX_LUNS-1; host->unique_id = ha->instance; @@ -1011,10 +997,10 @@ bp = &qla1280_buffer[0]; ha = (scsi_qla_host_t *)host->hostdata; - bdp = &QLBoardTbl[ha->devnum]; + bdp = &QL1280BoardTbl[ha->devnum]; memset(bp, 0, sizeof(qla1280_buffer)); sprintf(bp, - "QLogic %sPCI to SCSI Host Adapter: bus %d device %d irq %d\n" + "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n" " Firmware version: %2d.%02d.%02d, Driver version %s", (char *)&bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, host->irq, bdp->fwver[0],bdp->fwver[1],bdp->fwver[2], @@ -1046,8 +1032,8 @@ scsi_lu_t *q; u_long handle; - ENTER("qla1280_queuecommand"); - COMTRACE('C') + /*ENTER("qla1280_queuecommand"); + COMTRACE('C')*/ host = cmd->host; ha = (scsi_qla_host_t *) host->hostdata; @@ -1074,7 +1060,7 @@ { LU_Q(ha, b, t, l) = q; BZERO(q,sizeof(struct scsi_lu)); - DEBUG(sprintf(debug_buff,"Allocate new device queue 0x%x\n",q)); + DEBUG(sprintf(debug_buff,"Allocate new device queue 0x%x\n\r",q)); DEBUG(qla1280_print(debug_buff)); DRIVER_UNLOCK } @@ -1094,15 +1080,13 @@ handle = INVALID_HANDLE; CMD_HANDLE(cmd) = (unsigned char *)handle; - /* Bookkeeping information */ - sp->r_start = jiffies; /* time the request was recieved */ - sp->u_start = 0; - /* add the command to our queue */ ha->qthreads++; qla1280_putq_t(q,sp); - DEBUG(sprintf(debug_buff,"qla1280_queuecmd: queue pid=%d, hndl=0x%x\n\r",cmd->pid,handle)); + DEBUG(sprintf(debug_buff, + "qla1280_QC: t=%x CDB=%x I/OSize=0x%x haQueueCount=0x%x\n\r", + t,cmd->cmnd[0],CMD_XFRLEN(cmd),ha->qthreads)); DEBUG(qla1280_print(debug_buff)); /* send command to adapter */ @@ -1112,7 +1096,7 @@ DRIVER_UNLOCK - LEAVE("qla1280_queuecommand"); + /*LEAVE("qla1280_queuecommand");*/ return (0); } @@ -1723,6 +1707,7 @@ scsi_lu_t *q; uint32_t b, t, l; Scsi_Cmnd *cmd; + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) unsigned long cpu_flags = 0; #endif @@ -1739,7 +1724,8 @@ *done_q_last = NULL; else (*done_q_first)->s_prev = NULL; - cmd = sp->cmd; + + cmd = sp->cmd; b = SCSI_BUS_32(cmd); t = SCSI_TCN_32(cmd); l = SCSI_LUN_32(cmd); @@ -1753,8 +1739,6 @@ q->q_flag &= ~QLA1280_QBUSY; } - q->resp_time += jiffies - sp->r_start; /* Lun bookkeeping information */ - q->act_time += jiffies - sp->u_start; q->io_cnt++; if( sp->dir & BIT_5 ) q->r_cnt++; @@ -1777,7 +1761,28 @@ default: break; } - + /* 3.13 64 and 32 bit */ + /* Release memory used for this I/O */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + if (cmd->use_sg) { + DEBUG(sprintf(debug_buff, + "S/G unmap_sg cmd=%x\n\r",cmd);) + DEBUG(qla1280_print(debug_buff)); + pci_unmap_sg(ha->pdev, cmd->request_buffer, + cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + } + else if (cmd->request_bufflen) { + DEBUG(sprintf(debug_buff, + "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n\r", + cmd,sp->saved_dma_handle);) + DEBUG(qla1280_print(debug_buff);) + + pci_unmap_single(ha->pdev,sp->saved_dma_handle, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + } +#endif /* Call the mid-level driver interrupt handler */ CMD_HANDLE(sp->cmd) = (unsigned char *) 0; ha->actthreads--; @@ -1791,8 +1796,6 @@ qla1280_next(ha, q, b); } DRIVER_UNLOCK - - COMTRACE('d') LEAVE("qla1280_done"); } @@ -1964,7 +1967,7 @@ if (q->q_outcnt >= ha->bus_settings[b].hiwat) q->q_flag |= QLA1280_QBUSY; -#if QLA1280_64BIT_SUPPORT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) if (ha->flags.enable_64bit_addressing) status = qla1280_64bit_start_scsi(ha, sp); else @@ -1981,7 +1984,7 @@ /* Wait for 30 sec for command to be accepted. */ for (cnt = 6000000; cnt; cnt--) { -#if QLA1280_64BIT_SUPPORT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) if (ha->flags.enable_64bit_addressing) status = qla1280_64bit_start_scsi(ha, sp); else @@ -2072,7 +2075,7 @@ ENTER("qla1280_putq_t"); #endif DRIVER_LOCK - DEBUG(sprintf(debug_buff,"Adding to device 0x%p<-(0x%p)\n\r",q,sp)); + DEBUG(sprintf(debug_buff,"Adding to device q=0x%p<-(0x%p)sp\n\r",q,sp)); DEBUG(qla1280_print(debug_buff)); sp->s_next = NULL; if (!q->q_first) /* If queue empty */ @@ -2157,28 +2160,33 @@ { uint8_t status = 1; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) + dma_addr_t dma_handle; +#endif #ifdef QL_DEBUG_LEVEL_3 ENTER("qla1280_mem_alloc"); #endif -#ifdef DYNAMIC_MEM_ALLOC - ha->request_ring = qla1280_alloc_phys(REQUEST_ENTRY_SIZE * REQUEST_ENTRY_CNT, - &ha->request_dma); - if(ha->request_ring) { - ha->response_ring = qla1280_alloc_phys(RESPONSE_ENTRY_SIZE * RESPONSE_ENTRY_CNT, - &ha->response_dma); - if(ha->response_ring) { - status = 0; - } - } -#else + /* 3.13 */ + /* get consistent memory allocated for request and response rings */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) ha->request_ring = &ha->req[0]; ha->request_dma = VIRT_TO_BUS(&ha->req[0]); ha->response_ring = &ha->res[0]; ha->response_dma = VIRT_TO_BUS(&ha->res[0]); status = 0; -#endif +#else + ha->request_ring = pci_alloc_consistent(ha->pdev, + ((REQUEST_ENTRY_CNT+1)*(sizeof(request_t))), + &dma_handle); + ha->request_dma = dma_handle; + ha->response_ring = pci_alloc_consistent(ha->pdev, + ((RESPONSE_ENTRY_CNT+1)*(sizeof(response_t))), + &dma_handle); + ha->response_dma = dma_handle; + status = 0; +#endif if(status) { #if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) @@ -2222,6 +2230,16 @@ ha->dev[b] = (scsi_lu_t *)NULL; } + /* 3.13 */ + /* free consistent memory allocated for request and response rings */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + pci_free_consistent(ha->pdev, ((REQUEST_ENTRY_CNT+1)*(sizeof(request_t))), + ha->request_ring, ha->request_dma); + + pci_free_consistent(ha->pdev,((RESPONSE_ENTRY_CNT+1)*(sizeof(response_t))), + ha->response_ring, ha->response_dma); +#endif + LEAVE("qlc1280_mem_free"); } @@ -2482,7 +2500,7 @@ /* Verify checksum of loaded RISC code. */ mb[0] = MBC_VERIFY_CHECKSUM; /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; + mb[1] = *QL1280BoardTbl[ha->devnum].fwstart; if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]))) { @@ -2492,7 +2510,7 @@ #endif mb[0] = MBC_EXECUTE_FIRMWARE; /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; + mb[1] = *QL1280BoardTbl[ha->devnum].fwstart; qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); } else @@ -2527,18 +2545,69 @@ qla1280_pci_config(scsi_qla_host_t *ha) { uint8_t status = 1; - uint32_t command; #if MEMORY_MAPPED_IO uint32_t page_offset, base; uint32_t mmapbase; #endif - config_reg_t *creg = 0; uint16_t buf_wd; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + uint32_t command; + config_reg_t *creg = 0; +#endif + ENTER("qla1280_pci_config"); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + /* + * Set Bus Master Enable, Memory Address Space Enable and + * reset any error bits, in the command register. + */ + pci_read_config_word(ha->pdev, PCI_COMMAND, &buf_wd); + buf_wd &= ~0x7; +#if MEMORY_MAPPED_IO + DEBUG(printk("qla1280: MEMORY MAPPED IO is enabled.\n")); + buf_wd |= BIT_2 + BIT_1 + BIT_0; +#else + buf_wd |= BIT_2 + BIT_0; +#endif + pci_write_config_word(ha->pdev, PCI_COMMAND, buf_wd); + /* + * Reset expansion ROM address decode enable. + */ + pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &buf_wd); + buf_wd &= ~PCI_ROM_ADDRESS_ENABLE; + pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, buf_wd); +#if MEMORY_MAPPED_IO + /* + * Get memory mapped I/O address. + */ + pci_read_config_word(ha->pdev, PCI_BASE_ADDRESS_1, &mmapbase); + mmapbase &= PCI_BASE_ADDRESS_MEM_MASK; + + /* + * Find proper memory chunk for memory map I/O reg. + */ + base = mmapbase & PAGE_MASK; + page_offset = mmapbase - base; + /* + * Get virtual address for I/O registers. + */ + ha->mmpbase = ioremap_nocache(base, page_offset + 256); + if( ha->mmpbase ) + { + ha->mmpbase += page_offset; + /* ha->iobase = ha->mmpbase; */ + status = 0; + } +#else /* MEMORY_MAPPED_IO */ + status = 0; +#endif /* MEMORY_MAPPED_IO */ + +#else /*LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) */ + /* Get command register. */ - if (pci_read_config_word(ha->pdev,OFFSET(creg->command), &buf_wd) == PCIBIOS_SUCCESSFUL) + if (pcibios_read_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->command), &buf_wd) == PCIBIOS_SUCCESSFUL) { command = buf_wd; /* @@ -2552,20 +2621,20 @@ #else buf_wd |= BIT_2 + BIT_0; #endif - if( pci_write_config_word(ha->pdev,OFFSET(creg->command), buf_wd) ) + if( pcibios_write_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->command), buf_wd) ) { printk(KERN_WARNING "qla1280: Could not write config word.\n"); } /* Get expansion ROM address. */ - if (pci_read_config_word(ha->pdev,OFFSET(creg->expansion_rom), &buf_wd) == PCIBIOS_SUCCESSFUL) + if (pcibios_read_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->expansion_rom), &buf_wd) == PCIBIOS_SUCCESSFUL) { /* Reset expansion ROM address decode enable. */ buf_wd &= ~BIT_0; - if (pci_write_config_word(ha->pdev,OFFSET(creg->expansion_rom), buf_wd) == PCIBIOS_SUCCESSFUL) + if (pcibios_write_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->expansion_rom), buf_wd) == PCIBIOS_SUCCESSFUL) { #if MEMORY_MAPPED_IO /* Get memory mapped I/O address. */ - pci_read_config_dword(ha->pdev,OFFSET(cfgp->mem_base_addr), &mmapbase); + pcibios_read_config_dword(ha->pci_bus, ha->pci_device_fn,OFFSET(cfgp->mem_base_addr), &mmapbase); mmapbase &= PCI_BASE_ADDRESS_MEM_MASK; /* Find proper memory chunk for memory map I/O reg. */ @@ -2589,6 +2658,7 @@ } } } +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) */ LEAVE("qla1280_pci_config"); return(status); @@ -2719,6 +2789,7 @@ * Returns: * 0 = success. */ +#define DUMP_IT_BACK 0 /* for debug of RISC loading */ STATIC uint8_t qla1280_setup_chip(scsi_qla_host_t *ha) { @@ -2727,37 +2798,52 @@ uint16_t *risc_code_address; long risc_code_size; uint16_t mb[MAILBOX_REGISTER_COUNT]; -#ifdef QLA1280_UNUSED - uint8_t *sp; - int i; -#endif uint16_t cnt; int num; +#if DUMP_IT_BACK + int i; + uint8_t *sp; uint8_t *tbuf; - u_long p_tbuf; +#if BITS_PER_LONG > 32 + dma_addr_t p_tbuf; +#else + uint32_t p_tbuf; +#endif +#endif #ifdef QL_DEBUG_LEVEL_3 ENTER("qla1280_setup_chip"); #endif - if( (tbuf = (uint8_t *)KMALLOC(8000) ) == NULL ) - { - printk("setup_chip: couldn't alloacte memory\n"); - return(1); - } - p_tbuf = VIRT_TO_BUS(tbuf); + /* 3.13 */ +#if DUMP_IT_BACK +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + if( (tbuf = (uint8_t *)KMALLOC(8000) ) == NULL ) + { + printk("setup_chip: couldn't alloacte memory\n"); + return(1); + } + p_tbuf = VIRT_TO_BUS(tbuf); +#else + /* get consistent memory allocated for setup_chip */ + tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf); +#endif +#endif + /* Load RISC code. */ /* risc_address = ql12_risc_code_addr01; risc_code_address = &ql12_risc_code01[0]; risc_code_size = ql12_risc_code_length01; */ - risc_address = *QLBoardTbl[ha->devnum].fwstart; - risc_code_address = QLBoardTbl[ha->devnum].fwcode; - risc_code_size = (long)(*QLBoardTbl[ha->devnum].fwlen & 0xffff); - - DEBUG(printk("qla1280: DMAing RISC code (%d) words.\n",(int)risc_code_size)); - DEBUG(sprintf(debug_buff,"qla1280_setup_chip: Loading RISC code size =(%ld).\n\r",risc_code_size);) + risc_address = *QL1280BoardTbl[ha->devnum].fwstart; + risc_code_address = QL1280BoardTbl[ha->devnum].fwcode; + risc_code_size = (long)(*QL1280BoardTbl[ha->devnum].fwlen & 0xffff); + + DEBUG(printk("qla1280_setup_chip: DMA RISC code (%d) words\n", + (int)risc_code_size)); + DEBUG(sprintf(debug_buff, + "qla1280_setup_chip: DMA RISC code (%d) words\n\r",risc_code_size);) DEBUG(qla1280_print(debug_buff)); num =0; while (risc_code_size > 0 && !status) @@ -2767,29 +2853,31 @@ if ( cnt > risc_code_size ) cnt = risc_code_size; - DEBUG(sprintf(debug_buff,"qla1280_setup_chip: loading risc @ =(0x%p),%d,%d(0x%x).\n\r",risc_code_address,cnt,num,risc_address);) + DEBUG(sprintf(debug_buff, + "qla1280_setup_chip: loading risc @ =(0x%p),%d,%d(0x%x).\n\r", + risc_code_address,cnt,num,risc_address);) DEBUG(qla1280_print(debug_buff)); - DEBUG(printk("qla1280_setup_chip: loading risc @ =code=(0x%p),cnt=%d,seg=%d,addr=0x%x\n\r",risc_code_address,cnt,num,risc_address)); - BCOPY((caddr_t) risc_code_address,(caddr_t) ha->request_ring, (cnt <<1)); + BCOPY((caddr_t) risc_code_address,(caddr_t) ha->request_ring, + (cnt <<1)); + + flush_cache_all(); + mb[0] = MBC_LOAD_RAM; - /* mb[0] = MBC_LOAD_RAM_A64; */ mb[1] = risc_address; mb[4] = cnt; mb[3] = (uint16_t) ha->request_dma & 0xffff; mb[2] = (uint16_t) (ha->request_dma >> 16) & 0xffff; mb[7] = (uint16_t) (MS_64BITS(ha->request_dma) & 0xffff); mb[6] = (uint16_t) (MS_64BITS(ha->request_dma) >> 16) & 0xffff; - DEBUG(printk("qla1280_setup_chip: op=%d 0x%lx = 0x%4x,0x%4x,0x%4x,0x%4x\n",mb[0],ha->request_dma,mb[6],mb[7],mb[2],mb[3])); + DEBUG(printk("qla1280_setup_chip: op=%d 0x%p = 0x%4x,0x%4x,0x%4x,0x%4x\n",mb[0],ha->request_dma,mb[6],mb[7],mb[2],mb[3])); if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, &mb[0])) ) { printk("Failed to load partial segment of f/w\n"); break; } - /* dump it back */ - -#if 0 - mb[0] = MBC_DUMP_RAM_A64; +#if DUMP_IT_BACK + mb[0] = MBC_READ_RAM_WORD; mb[1] = risc_address; mb[4] = cnt; mb[3] = (uint16_t) p_tbuf & 0xffff; @@ -2797,10 +2885,13 @@ mb[7] = (uint16_t) (p_tbuf >> 32) & 0xffff; mb[6] = (uint16_t) (p_tbuf >> 48) & 0xffff; - if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0, - &mb[0])) ) + if( (status = qla1280_mailbox_command(ha, + BIT_4|BIT_3|BIT_2|BIT_1|BIT_0,&mb[0])) ) { printk("Failed to dump partial segment of f/w\n"); + DEBUG(sprintf(debug_buff, + "setup_chip: Failed to dump partial segment of f/w\n\r");) + DEBUG(qla1280_print(debug_buff)); break; } sp = (uint8_t *)ha->request_ring; @@ -2808,51 +2899,20 @@ { if( tbuf[i] != sp[i] ) { - printk("qla1280 : firmware compare error @ byte (0x%x)\n",i); - break; + printk("qla1280_setup_chip: FW compare error @ byte(0x%x) loop#=%x\n",i,num); + printk("setup_chip: FWbyte=%x FWfromChip=%x\n",sp[i],tbuf[i]); + DEBUG(sprintf(debug_buff, + "qla1280_setup_chip: FW compare error @ byte(0x%x) loop#=%x\n\r",i);) + DEBUG(qla1280_print(debug_buff);) + /*break;*/ } } - #endif risc_address += cnt; risc_code_size = risc_code_size - cnt; risc_code_address = risc_code_address + cnt; num++; } -#ifdef QLA1280_UNUSED - DEBUG(ql_debug_print = 0;) - { - for (i = 0; i < ql12_risc_code_length01; i++) - { - mb[0] = 0x4; - mb[1] = ql12_risc_code_addr01 + i; - mb[2] = ql12_risc_code01[i]; - - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, - &mb[0]); - if (status) - { - printk("qla1280 : firmware load failure\n"); - break; - } - - mb[0] = 0x5; - mb[1] = ql12_risc_code_addr01 + i; - mb[2] = 0; - - status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, - &mb[0]); - if (status) - { - printk("qla1280 : firmware dump failure\n"); - break; - } - if( mb[2] != ql12_risc_code01[i] ) - printk("qla1280 : firmware compare error @ (0x%x)\n",ql12_risc_code_addr01+i); - } - } - DEBUG(ql_debug_print = 1;) -#endif /* Verify checksum of loaded RISC code. */ if (!status) @@ -2860,22 +2920,29 @@ DEBUG(printk("qla1280_setup_chip: Verifying checksum of loaded RISC code.\n");) mb[0] = MBC_VERIFY_CHECKSUM; /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; + mb[1] = *QL1280BoardTbl[ha->devnum].fwstart; if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]))) { /* Start firmware execution. */ DEBUG(qla1280_print("qla1280_setup_chip: start firmware running.\n\r");) mb[0] = MBC_EXECUTE_FIRMWARE; - /* mb[1] = ql12_risc_code_addr01; */ - mb[1] = *QLBoardTbl[ha->devnum].fwstart; + mb[1] = *QL1280BoardTbl[ha->devnum].fwstart; qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]); } else printk("qla1280_setup_chip: Failed checksum.\n"); } - KMFREE(tbuf,8000); + /* 3.13 */ +#if DUMP_IT_BACK +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + KMFREE(tbuf,8000); +#else + /* free consistent memory allocated for setup_chip */ + pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); +#endif +#endif #if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) if (status) @@ -3152,10 +3219,28 @@ /* Disable RISC load of firmware. */ ha->flags.disable_risc_code_load = nv->cntr_flags_1.disable_loading_risc_code; + /* Enable 64bit addressing. */ ha->flags.enable_64bit_addressing = nv->cntr_flags_1.enable_64bit_addressing; +#if FORCE_64BIT_PCI_DMA + ha->flags.enable_64bit_addressing = 1; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + if (ha->flags.enable_64bit_addressing) { + printk("[[[ qla1x160: 64 Bit PCI Addressing Enabled ]]]\n"); + +#if BITS_PER_LONG > 32 + /* Update our PCI device dma_mask for full 64 bit mask */ + //ha->pdev->dma_mask = (pci_dma_t) 0xffffffffffffffffull; + ha->pdev->dma_mask = 0xffffffffffffffff; + +#endif + } +#endif + /* Set ISP hardware DMA burst */ mb[0] = nv->isp_config.c; WRT_REG_WORD(®->cfg_1, mb[0]); @@ -3838,7 +3923,7 @@ #endif } -#if QLA1280_64BIT_SUPPORT +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,18) /* * qla1280_64bit_start_scsi * The start SCSI is responsible for building request packets on @@ -3863,10 +3948,13 @@ uint16_t seg_cnt; struct scatterlist *sg = (struct scatterlist *) NULL; uint32_t *dword_ptr; + dma_addr_t dma_handle; -#ifdef QL_DEBUG_LEVEL_3 ENTER("qla1280_64bit_start_scsi:"); -#endif + + DEBUG(sprintf(debug_buff, + "64bit_start: cmd=%x sp=%x CDB=%x\n\r",cmd,sp,cmd->cmnd[0]);) + DEBUG(qla1280_print(debug_buff)); if( qla1280_check_for_dead_scsi_bus(ha, sp) ) { @@ -3877,9 +3965,10 @@ seg_cnt = 0; req_cnt = 1; if (cmd->use_sg) - { - seg_cnt = cmd->use_sg; + { /* 3.13 64 bit */ sg = (struct scatterlist *) cmd->request_buffer; + seg_cnt = pci_map_sg(ha->pdev,sg,cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); if (seg_cnt > 2) { @@ -3890,7 +3979,7 @@ } else if (cmd->request_bufflen) /* If data transfer. */ { - DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen)); + DEBUG(printk("Single data transfer len=0x%x\n",cmd->request_bufflen)); seg_cnt = 1; } @@ -3951,7 +4040,7 @@ /* Load SCSI command packet. */ pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd); BCOPY(&(CMD_CDBP(cmd)), pkt->scsi_cdb, pkt->cdb_len); - DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); + //DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); /* * Load data segments. @@ -3977,12 +4066,17 @@ /* Load command entry data segments. */ for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) { - DEBUG(sprintf(debug_buff,"SG Segment ap=0x%p, len=0x%x\n\r",sg->address,sg->length)); - DEBUG(qla1280_print(debug_buff)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(sg->address)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address)); - *dword_ptr++ = sg->length; + /* 3.13 64 bit */ + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))); + *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); sg++; + DEBUG(sprintf(debug_buff, + "S/G Segment phys_addr=%x %x, len=0x%x\n\r", + cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))), + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), + cpu_to_le32(sg_dma_len(sg)));) + DEBUG(qla1280_print(debug_buff)); } #ifdef QL_DEBUG_LEVEL_5 qla1280_print( @@ -3999,6 +4093,10 @@ /* * Build continuation packets. */ + DEBUG(sprintf(debug_buff, + "S/G Building Continuation...seg_cnt=0x%x remains\n\r", + seg_cnt);) + DEBUG(qla1280_print(debug_buff)); while (seg_cnt > 0) { /* Adjust ring index. */ @@ -4032,10 +4130,17 @@ /* Load continuation entry data segments. */ for (cnt = 0; cnt < 5 && seg_cnt; cnt++, seg_cnt--) { - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(sg->address)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address)); - *dword_ptr++ = sg->length; - sg++; + /* 3.13 64 bit */ + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))); + *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); + DEBUG(sprintf(debug_buff, + "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n\r", + cpu_to_le32(pci_dma_hi32(sg_dma_address(sg))), + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), + cpu_to_le32(sg_dma_len(sg)));) + DEBUG(qla1280_print(debug_buff)); + sg++; } #ifdef QL_DEBUG_LEVEL_5 qla1280_print( @@ -4052,11 +4157,21 @@ #endif } } - else /* No scatter gather data transfer */ - { - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(cmd->request_buffer)); - *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(cmd->request_buffer)); - *dword_ptr = (uint32_t) cmd->request_bufflen; + else /* No scatter gather data transfer */ + { /* 3.13 64 bit */ + dma_handle = pci_map_single(ha->pdev, + cmd->request_buffer, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + /* save dma_handle for pci_unmap_single */ + sp->saved_dma_handle = dma_handle; + + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr++ = cpu_to_le32(pci_dma_hi32(dma_handle)); + *dword_ptr = (uint32_t) cmd->request_bufflen; + DEBUG(sprintf(debug_buff, + "No S/G map_single saved_dma_handle=%lx\n\r",dma_handle)); + DEBUG(qla1280_print(debug_buff)); #ifdef QL_DEBUG_LEVEL_5 qla1280_print( "qla1280_64bit_start_scsi: No scatter/gather command packet data - c"); @@ -4071,12 +4186,12 @@ #endif } } -#ifdef QL_DEBUG_LEVEL_5 - else /* No data transfer */ + else /* No data transfer */ { *dword_ptr++ = (uint32_t) 0; *dword_ptr++ = (uint32_t) 0; *dword_ptr = (uint32_t) 0; +#ifdef QL_DEBUG_LEVEL_5 qla1280_print( "qla1280_64bit_start_scsi: No data, command packet data - c"); qla1280_print(" b "); @@ -4087,8 +4202,8 @@ qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10); qla1280_print("\n\r"); qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE); - } #endif + } /* Adjust ring index. */ ha->req_ring_index++; if (ha->req_ring_index == REQUEST_ENTRY_CNT) @@ -4140,7 +4255,7 @@ #endif return(status); } -#endif /* QLA1280_64BIT_SUPPORT */ +#endif /* * qla1280_32bit_start_scsi @@ -4175,8 +4290,15 @@ uint8_t *data_ptr; uint32_t *dword_ptr; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + dma_addr_t dma_handle; +#endif + ENTER("qla1280_32bit_start_scsi"); + DEBUG(sprintf(debug_buff, + "32bit_start: cmd=%x sp=%x CDB=%x\n\r",cmd,sp,cmd->cmnd[0]);) + DEBUG(qla1280_print(debug_buff)); if( qla1280_check_for_dead_scsi_bus(ha, sp) ) { @@ -4193,8 +4315,15 @@ * differences and the kernel SG list uses virtual addresses where * we need physical addresses. */ - seg_cnt = cmd->use_sg; sg = (struct scatterlist *) cmd->request_buffer; + /* 3.13 32 bit */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + seg_cnt = cmd->use_sg; +#else + seg_cnt = pci_map_sg(ha->pdev,sg,cmd->use_sg, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); +#endif + /* * if greater than four sg entries then we need to allocate * continuation entries @@ -4205,17 +4334,22 @@ if ((uint16_t)(seg_cnt - 4) % 7) req_cnt++; } - DEBUG(sprintf(debug_buff,"S/G for data transfer -num segs(%d), req blk cnt(%d)\n\r",seg_cnt,req_cnt)); + DEBUG(sprintf(debug_buff, + "S/G Transfer cmd=%x seg_cnt=0x%x, req_cnt=%x\n\r", + cmd,seg_cnt,req_cnt)); DEBUG(qla1280_print(debug_buff)); } else if (cmd->request_bufflen) /* If data transfer. */ { - DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen)); + DEBUG(sprintf(debug_buff, + "No S/G transfer t=%x cmd=%x len=%x CDB=%x\n\r", + SCSI_TCN_32(cmd),cmd,cmd->request_bufflen,cmd->cmnd[0])); + DEBUG(qla1280_print(debug_buff)); seg_cnt = 1; } else { - DEBUG(printk("No data transfer \n")); + //DEBUG(printk("No data transfer \n")); seg_cnt = 0; } @@ -4232,7 +4366,8 @@ ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt); } - DEBUG(sprintf(debug_buff,"Number of free entries = (%d)\n\r",ha->req_q_cnt)); + DEBUG(sprintf(debug_buff,"Number of free entries=(%d) seg_cnt=0x%x\n\r", + ha->req_q_cnt,seg_cnt)); DEBUG(qla1280_print(debug_buff)); /* If room for request in request ring. */ if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt) @@ -4280,20 +4415,15 @@ data_ptr = (uint8_t *) &(CMD_CDBP(cmd)); for (cnt = 0; cnt < pkt->cdb_len; cnt++) pkt->scsi_cdb[cnt] = *data_ptr++; - DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); + //DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0])); /* * Load data segments. */ if (seg_cnt) { - DEBUG(printk("loading data segments..\n")); /* Set transfer direction (READ and WRITE) */ /* Linux doesn't tell us */ - /* - * 3/10 dg - Normally, we should need this check with our F/W - * but because of a small issue with it we do. - * * For block devices, cmd->request.cmd has the operation * For character devices, this isn't always set properly, so * we need to check data_cmnd[0]. This catches the conditions @@ -4319,15 +4449,32 @@ /* Load command entry data segments. */ for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) { + /* 3.13 32 bit */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(sg->address)); *dword_ptr++ = sg->length; - DEBUG(sprintf(debug_buff,"SG Segment ap=0x%p, len=0x%x\n\r",sg->address,sg->length)); + DEBUG(sprintf(debug_buff, + "S/G Segment phys_addr=0x%x, len=0x%x\n\r", + cpu_to_le32(VIRT_TO_BUS(sg->address)),sg->length)); + DEBUG(qla1280_print(debug_buff)); +#else + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); + DEBUG(sprintf(debug_buff, + "S/G Segment phys_addr=0x%x, len=0x%x\n\r", + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), + cpu_to_le32(sg_dma_len(sg)));) DEBUG(qla1280_print(debug_buff)); +#endif sg++; } /* * Build continuation packets. */ + DEBUG(sprintf(debug_buff, + "S/G Building Continuation...seg_cnt=0x%x remains\n\r", + seg_cnt);) + DEBUG(qla1280_print(debug_buff)); while (seg_cnt > 0) { /* Adjust ring index. */ @@ -4362,9 +4509,25 @@ /* Load continuation entry data segments. */ for (cnt = 0; cnt < 7 && seg_cnt; cnt++, seg_cnt--) { - *dword_ptr++ = (u_int) cpu_to_le32(VIRT_TO_BUS(sg->address)); - *dword_ptr++ = sg->length; - sg++; + /* 3.13 32 bit */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) + *dword_ptr++ = (u_int) cpu_to_le32(VIRT_TO_BUS(sg->address)); + *dword_ptr++ = sg->length; + DEBUG(sprintf(debug_buff, + "S/G Segment Cont. phys_addr=0x%x, len=0x%x\n\r", + cpu_to_le32(pci_dma_lo32(VIRT_TO_BUS(sg->address))), + sg->length);) + DEBUG(qla1280_print(debug_buff)); +#else + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); + *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); + DEBUG(sprintf(debug_buff, + "S/G Segment Cont. phys_addr=0x%x, len=0x%x\n\r", + cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), + cpu_to_le32(sg_dma_len(sg)));) + DEBUG(qla1280_print(debug_buff)); +#endif + sg++; } #ifdef QL_DEBUG_LEVEL_5 qla1280_print( @@ -4379,14 +4542,28 @@ #endif } } - else /* No scatter gather data transfer */ + else /* No S/G data transfer */ { + /* 3.13 32 bit */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer)); *dword_ptr = (uint32_t) cmd->request_bufflen; - DEBUG(printk("Single Segment ap=0x%p, len=0x%x\n",cmd->request_buffer,cmd->request_bufflen)); +#else + dma_handle = pci_map_single(ha->pdev, + cmd->request_buffer, + cmd->request_bufflen, + scsi_to_pci_dma_dir(cmd->sc_data_direction)); + sp->saved_dma_handle = dma_handle; + + *dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle)); + *dword_ptr = (uint32_t) cmd->request_bufflen; + DEBUG(sprintf(debug_buff, + "No S/G map_single saved_dma_handle=%lx\n\r",dma_handle)); + DEBUG(qla1280_print(debug_buff)); +#endif } } - else /* No data transfer */ + else /* No data transfer at all */ { *dword_ptr++ = (uint32_t) 0; *dword_ptr = (uint32_t) 0; @@ -4414,7 +4591,6 @@ /* Set chip new ring index. */ DEBUG(qla1280_print("qla1280_32bit_start_scsi: Wakeup RISC for pending command\n\r")); ha->qthreads--; - sp->u_start = jiffies; sp->flags |= SRB_SENT; ha->actthreads++; /* qla1280_output_number((uint32_t)ha->actthreads++, 16); */ @@ -4425,7 +4601,7 @@ status = 1; #ifdef QL_DEBUG_LEVEL_2 qla1280_print( - "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r"); + "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r"); qla1280_print(" req_q_cnt="); qla1280_output_number((uint32_t)ha->req_q_cnt, 16); qla1280_print("\n\r"); @@ -4459,6 +4635,7 @@ return(status); } + /* * qla1280_req_pkt * Function is responsible for locking ring and @@ -4889,7 +5066,7 @@ { device_reg_t *reg = ha->iobase; response_t *pkt; - srb_t *sp; + srb_t *sp = 0; uint16_t mailbox[MAILBOX_REGISTER_COUNT]; uint16_t *wptr; uint32_t index; @@ -4903,9 +5080,11 @@ /* Check for mailbox interrupt. */ mailbox[0] = RD_REG_WORD(®->semaphore); + if (mailbox[0] & BIT_0) { /* Get mailbox data. */ + //DEBUG(qla1280_print("qla1280_isr: In Get mailbox data \n\r");) wptr = &mailbox[0]; *wptr++ = RD_REG_WORD(®->mailbox0); @@ -4938,7 +5117,7 @@ { case MBA_SCSI_COMPLETION: /* Response completion */ #ifdef QL_DEBUG_LEVEL_5 - qla1280_print("qla1280_isr: mailbox response completion\n\r"); + qla1280_print("qla1280_isr: mailbox SCSI response completion\n\r"); #endif if (ha->flags.online) { @@ -4967,9 +5146,11 @@ else (*done_q_last)->s_next = sp; *done_q_last = sp; + } else { + #ifdef QL_DEBUG_LEVEL_2 qla1280_print("qla1280_isr: ISP invalid handle\n\r"); #endif @@ -5041,6 +5222,7 @@ #endif break; default: + //DEBUG(qla1280_print("qla1280_isr: default case of switch MB \n\r");) if (mailbox[0] < MBA_ASYNC_EVENT) { wptr = &mailbox[0]; @@ -5057,9 +5239,9 @@ break; } } - else + else { WRT_REG_WORD(®->host_cmd, HC_CLR_RISC_INT); - + } /* * Response ring */ @@ -5123,6 +5305,7 @@ qla1280_error_entry(ha, pkt, done_q_first, done_q_last); + /* Adjust ring index. */ ha->rsp_ring_index++; if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) @@ -5306,9 +5489,12 @@ } pkt->scsi_status = S_CKCON; pkt->option_flags |= (uint32_t)OF_SSTS | (uint32_t)OF_NO_DATA; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) if (ha->flags.enable_64bit_addressing) qla1280_64bit_continue_io(ha, pkt, 0, 0); else +#endif qla1280_32bit_continue_io(ha, pkt, 0, 0); break; case 0x16: /* Requested Capability Not Available */ @@ -5667,10 +5853,12 @@ (uint32_t)OF_NO_DATA; break; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) if (ha->flags.enable_64bit_addressing) - qla1280_64bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); + qla1280_64bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); else - qla1280_32bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); +#endif + qla1280_32bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr); break; default: break; @@ -5744,11 +5932,13 @@ ha->outstanding_cmds[pkt->handle] = 0; cp = sp->cmd; + /* Generate LU queue on cntrl, target, LUN */ b = SCSI_BUS_32(cp); t = SCSI_TCN_32(cp); l = SCSI_LUN_32(cp); q = LU_Q(ha, b, t, l); + if( pkt->comp_status || pkt->scsi_status ) { DEBUG(qla1280_print( "scsi: comp_status = ");) @@ -5879,7 +6069,7 @@ /* Place command on done queue. */ qla1280_done_q_put(sp, done_q_first, done_q_last); } -#if QLA1280_64BIT_SUPPORT +#if BITS_PER_LONG > 32 else if (pkt->entry_type == COMMAND_A64_TYPE) { #ifdef QL_DEBUG_LEVEL_2 @@ -5956,7 +6146,6 @@ sp->timeout += 2; */ /* Place request back on top of device queue. */ - /* sp->flags &= ~(SRB_SENT | SRB_TIMEOUT); */ sp->flags = 0; qla1280_putq_t(q, sp); } @@ -6074,7 +6263,7 @@ } } #ifdef QL_DEBUG_LEVEL_3 - qla1280_print("qla1280_restart_queues: exiting normally\n"); + qla1280_print("qla1280_restart_queues: exiting normally\n\r"); #endif } @@ -6160,13 +6349,15 @@ return(ret); } - -/* - * Declarations for load module - */ -static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +#ifdef MODULE +Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE; #include "scsi_module.c" +#endif +#else /* new kernel scsi initialization scheme */ +static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE; +#include "scsi_module.c" +#endif /************************************************************************ * qla1280_check_for_dead_scsi_bus * @@ -6277,13 +6468,13 @@ #if MEMORY_MAPPED_IO ret = *port; #else - ret = inb((int)port); + ret = inb((long)port); #endif if (ql_debug_print) { qla1280_print("qla1280_getbyte: address = "); - qla1280_output_number((uint32_t)port, 16); + qla1280_output_number((unsigned long)port, 16); qla1280_print(" data = 0x"); qla1280_output_number((uint32_t)ret, 16); qla1280_print("\n\r"); @@ -6303,13 +6494,13 @@ #if MEMORY_MAPPED_IO ret = *port; #else - ret = inw((int)port); + ret = inw((unsigned long)port); #endif if (ql_debug_print) { qla1280_print("qla1280_getword: address = "); - qla1280_output_number((uint32_t)port, 16); + qla1280_output_number((unsigned long)port, 16); qla1280_print(" data = 0x"); qla1280_output_number((uint32_t)ret, 16); qla1280_print("\n\r"); @@ -6329,13 +6520,13 @@ #if MEMORY_MAPPED_IO ret = *port; #else - ret = inl((int)port); + ret = inl((unsigned long)port); #endif if (ql_debug_print) { qla1280_print("qla1280_getdword: address = "); - qla1280_output_number((uint32_t)port, 16); + qla1280_output_number((unsigned long)port, 16); qla1280_print(" data = 0x"); qla1280_output_number((uint32_t)ret, 16); qla1280_print("\n\r"); @@ -6353,13 +6544,13 @@ #if MEMORY_MAPPED_IO *port = data; #else - outb(data, (int)port); + outb(data, (unsigned long)port); #endif if (ql_debug_print) { qla1280_print("qla1280_putbyte: address = "); - qla1280_output_number((uint32_t)port, 16); + qla1280_output_number((unsigned long)port, 16); qla1280_print(" data = 0x"); qla1280_output_number((uint32_t)data, 16); qla1280_print("\n\r"); @@ -6378,14 +6569,14 @@ #ifdef _LINUX_IOPORTS outw(data, (int)port); #else - outw((int)port, data); + outw((unsigned long)port, data); #endif #endif if (ql_debug_print) { qla1280_print("qla1280_putword: address = "); - qla1280_output_number((uint32_t)port, 16); + qla1280_output_number((unsigned long)port, 16); qla1280_print(" data = 0x"); qla1280_output_number((uint32_t)data, 16); qla1280_print("\n\r"); @@ -6404,14 +6595,14 @@ #ifdef _LINUX_IOPORTS outl(data,(int)port); #else - outl((int)port, data); + outl((unsigned long)port, data); #endif #endif if (ql_debug_print) { qla1280_print("qla1280_putdword: address = "); - qla1280_output_number((uint32_t)port, 16); + qla1280_output_number((unsigned long)port, 16); qla1280_print(" data = 0x"); qla1280_output_number((uint32_t)data, 16); qla1280_print("\n\r"); @@ -6435,8 +6626,7 @@ /* * Out character to COM2 port. - * PORT must be at standard address for COM2 = 0x2F8, - * or COM1 = 0x3F8 + * PORT must be at standard address for COM1 = 0x3f8 */ #define OUTB(addr,data) outb((data),(addr)) @@ -6446,7 +6636,7 @@ #ifdef QL_DEBUG_CONSOLE printk("%c", c); #else - int com_addr = 0x2f8; + int com_addr = 0x3f8; int hardware_flow_control = 1; int software_flow_control = 0; uint8_t data; @@ -6458,7 +6648,7 @@ }while (!(data & BIT_6)); /* - * Set BAUD rate for COM2 to 19200 (0x6) + * Set BAUD rate for COM2 to 9600 (0x6) */ /* Select rate divisor. */ @@ -6654,8 +6844,6 @@ qla1280_print(debug_buff); sprintf(debug_buff," Pid=%d, SP=0x%p\n\r", (int)cmd->pid, CMD_SP(cmd)); qla1280_print(debug_buff); - sprintf(debug_buff," r_start=0x%lx, u_start=0x%lx\n\r",sp->r_start,sp->u_start); - qla1280_print(debug_buff); sprintf(debug_buff," underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n\r", cmd->underflow, sp->dir,cmd->request.cmd); qla1280_print(debug_buff); } @@ -6683,23 +6871,6 @@ } #endif -#ifdef QLA1280_UNUSED -/************************************************************************** - * ql1280_dump_regs - * - **************************************************************************/ -static void qla1280_dump_regs(struct Scsi_Host *host) -{ - printk("Mailbox registers:\n"); - printk("qla1280 : mbox 0 0x%04x \n", inw(host->io_port + 0x70)); - printk("qla1280 : mbox 1 0x%04x \n", inw(host->io_port + 0x72)); - printk("qla1280 : mbox 2 0x%04x \n", inw(host->io_port + 0x74)); - printk("qla1280 : mbox 3 0x%04x \n", inw(host->io_port + 0x76)); - printk("qla1280 : mbox 4 0x%04x \n", inw(host->io_port + 0x78)); - printk("qla1280 : mbox 5 0x%04x \n", inw(host->io_port + 0x7a)); -} -#endif - #if STOP_ON_ERROR @@ -6726,9 +6897,6 @@ printk("HA flags =0x%lx\n", *fp); DEBUG2(ql_debug_print = 1;) /* DEBUG2(ql1280_dump_device((scsi_qla_host_t *) host->hostdata)); */ -#ifdef QLA1280_UNUSED - qla1280_dump_regs(host); -#endif sti(); panic("Ooops"); /* cli(); @@ -6741,11 +6909,6 @@ } #endif -#ifdef QLA1280_UNUSED -static void qla1280_set_flags(char * s) -{ -} -#endif /************************************************************************** * qla1280_setup @@ -6759,24 +6922,6 @@ { char *end, *str, *cp; -#ifdef QLA1280_UNUSED - static struct - { - const char *name; - int siz; - void (*func)(); - int arg; - } options[] = - { - { "dump_regs", 9, &qla1280_dump_regs, 0 - }, - { "verbose", 7, &qla1280_set_flags, 0x1 - }, - { "", 0, NULL, 0 - } - }; -#endif - printk("scsi: Processing Option str = %s\n", s); end = strchr(s, '\0'); /* locate command */ @@ -6825,4 +6970,3 @@ * tab-width: 8 * End: */ - diff -urN linux-2.4.0-test12/drivers/scsi/qla1280.h linux-2.4.0-test12-lia/drivers/scsi/qla1280.h --- linux-2.4.0-test12/drivers/scsi/qla1280.h Mon Sep 18 13:40:13 2000 +++ linux-2.4.0-test12-lia/drivers/scsi/qla1280.h Wed Dec 6 22:52:08 2000 @@ -1,169 +1,35 @@ -/************************************************************************* - * QLOGIC LINUX SOFTWARE - * - * QLogic ISP1x80/1x160 device driver for Linux 2.3.x (redhat 6.x). - * - * COPYRIGHT (C) 1996-2000 QLOGIC CORPORATION - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the Qlogic's Linux Software License. - * - * This program is WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistribution's or source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - *****************************************************************************/ - -/************************************************************************************* - QLOGIC CORPORATION SOFTWARE - "GNU" GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION - AND MODIFICATION - -This GNU General Public License ("License") applies solely to QLogic Linux -Software ("Software") and may be distributed under the terms of this License. - -1. You may copy and distribute verbatim copies of the Software's source code as -you receive it, in any medium, provided that you conspicuously and appropriately -publish on each copy an appropriate copyright notice and disclaimer of warranty; -keep intact all the notices that refer to this License and to the absence of any -warranty; and give any other recipients of the Software a copy of this License along -with the Software. - -You may charge a fee for the physical act of transferring a copy, and you may at your -option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Software or any portion of it, thus forming -a work based on the Software, and copy and distribute such modifications or work under -the terms of Section 1 above, provided that you also meet all of these conditions: - -* a) You must cause the modified files to carry prominent notices stating that you -changed the files and the date of any change. - -* b) You must cause any work that you distribute or publish that in whole or in part -contains or is derived from the Software or any part thereof, to be licensed as a -whole at no charge to all third parties under the terms of this License. - -* c) If the modified Software normally reads commands interactively when run, you -must cause it, when started running for such interactive use in the most ordinary way, -to print or display an announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide a warranty) and that -users may redistribute the Software under these conditions, and telling the user how to -view a copy of this License. (Exception:if the Software itself is interactive but does -not normally print such an announcement, your work based on the Software is not required -to print an announcement.) - -These requirements apply to the modified work as a whole. If identifiable sections of -that work are not derived from the Software, and can be reasonably considered independent -and separate works in themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you distribute the same -sections as part of a whole which is a work based on the Software, the distribution of the -whole must be on the terms of this License, whose permissions for other licensees extend -to the entire whole, and thus to each and every part regardless of who wrote it. - -3. You may copy and distribute the Software (or a work based on it, under Section 2) in -object code or executable form under the terms of Sections 1 and 2 above provided that -you also do one of the following: - -* a) Accompany it with the complete corresponding machine-readable source code, which must -be distributed under the terms of Sections 1 and 2 above on a medium customarily used for -software interchange; or, - -* b) Accompany it with a written offer, valid for at least three years, to give any third -party, for a charge no more than your cost of physically performing source distribution, -a complete machine-readable copy of the corresponding source code, to be distributed under -the terms of Sections 1 and 2 above on a medium customarily used for software interchange; -or, - -* c) Accompany it with the information you received as to the offer to distribute -corresponding source code. (This alternative is allowed only for noncommercial distribution -and only if you received the Software in object code or executable form with such an offer, -in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for making modifications -to it. For an executable work, complete source code means all the source code for all -modules it contains, plus any associated interface definition files, plus the scripts used -to control compilation and installation of the executable. - -If distribution of executable or object code is made by offering access to copy from a -designated place, then offering equivalent access to copy the source code from the same -place counts as distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -4. You may not copy, modify, sublicense, or distribute the Software except as expressly -provided under this License. Any attempt otherwise to copy, modify, sublicense or -distribute the Software is void, and will automatically terminate your rights under this -License. However, parties who have received copies, or rights, from you under this License -will not have their licenses terminated so long as such parties remain in full compliance. - -5. This license grants you world wide, royalty free non-exclusive rights to modify or -distribute the Software or its derivative works. These actions are prohibited by law -if you do not accept this License. Therefore, by modifying or distributing the Software -(or any work based on the Software), you indicate your acceptance of this License to do -so, and all its terms and conditions for copying, distributing or modifying the Software -or works based on it. - -6. Each time you redistribute the Software (or any work based on the Software), the -recipient automatically receives a license from the original licensor to copy, distribute -or modify the Software subject to these terms and conditions. You may not impose any -further restrictions on the recipients' exercise of the rights granted herein. You are -not responsible for enforcing compliance by third parties to this License. - -7. If, as a consequence of a court judgment or allegation of patent infringement or for -any other reason (not limited to patent issues), conditions are imposed on you -(whether by court order, agreement or otherwise) that contradict the conditions of this -License, they do not excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this License -and any other pertinent obligations, then as a consequence you may not distribute the -Software at all. - -If any portion of this section is held invalid or unenforceable under any particular -circumstance, the balance of the section is intended to apply and the section as a whole -is intended to apply in other circumstances. -NO WARRANTY - -11. THE SOFTWARE IS PROVIDED WITHOUT A WARRANTY OF ANY KIND. THERE IS NO -WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, -EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE -ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. -SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL -NECESSARY SERVICING, REPAIR OR CORRECTION. - -12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR -DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING -BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR -LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO -OPERATE WITH ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -END OF TERMS AND CONDITIONS +/******************************************************************************** +* QLOGIC LINUX SOFTWARE +* +* QLogic ISP1280 (Ultra2) /12160 (Ultra3) SCSI driver +* Copyright (C) 2000 Qlogic Corporation +* (www.qlogic.com) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2, or (at your option) any +* later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +** +******************************************************************************/ -*************************************************************************************/ - - #ifndef _IO_HBA_QLA1280_H /* wrapper symbol for kernel use */ #define _IO_HBA_QLA1280_H /* subject to change without notice */ + +#ifndef LINUX_VERSION_CODE +#include +#endif /* LINUX_VERSION_CODE not defined */ + #if defined(__cplusplus) extern "C" { #endif -#include - +#ifndef HOSTS_C /* included in hosts.c */ /* * Enable define statement to ignore Data Underrun Errors, * remove define statement to enable detection. @@ -173,15 +39,18 @@ /* * Driver debug definitions. */ -/* #define QL_DEBUG_LEVEL_1 */ /* Output register accesses to COM2. */ -/* #define QL_DEBUG_LEVEL_2 */ /* Output error msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_3 */ /* Output function trace msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_4 */ /* Output NVRAM trace msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_5 */ /* Output ring trace msgs to COM2. */ -/* #define QL_DEBUG_LEVEL_6 */ /* Output WATCHDOG timer trace to COM2. */ -/* #define QL_DEBUG_LEVEL_7 */ /* Output RISC load trace msgs to COM2. */ +/* #define QL_DEBUG_LEVEL_1 */ /* Output register accesses to COM1 */ +/* #define QL_DEBUG_LEVEL_2 */ /* Output error msgs to COM1 */ +/* #define QL_DEBUG_LEVEL_3 */ /* Output function trace msgs to COM1 */ +/* #define QL_DEBUG_LEVEL_4 */ /* Output NVRAM trace msgs to COM1 */ +/* #define QL_DEBUG_LEVEL_5 */ /* Output ring trace msgs to COM1 */ +/* #define QL_DEBUG_LEVEL_6 */ /* Output WATCHDOG timer trace to COM1 */ +/* #define QL_DEBUG_LEVEL_7 */ /* Output RISC load trace msgs to COM1 */ + + #define QL_DEBUG_CONSOLE /* Output to console instead of COM1 */ + /* comment this #define to get output of qla1280_print to COM1 */ + /* if COM1 is not connected to a host system, the driver hangs system! */ -#define QL_DEBUG_CONSOLE /* Output to console instead of COM2. */ #ifndef TRUE # define TRUE 1 @@ -206,7 +75,11 @@ * Locking */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) -# include +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18) +# include +# else +# include +# endif # include # define cpuid smp_processor_id() # if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) @@ -314,12 +187,12 @@ #define WRT_REG_DWORD(addr, data) qla1280_putdword((uint32_t *)addr, data) #else /* QL_DEBUG_LEVEL_1 */ #ifdef MEMORY_MAPPED_IO - #define RD_REG_BYTE(addr) readb((unsigned long) (addr) - #define RD_REG_WORD(addr) readw((unsigned long) (addr) - #define RD_REG_DWORD(addr) readl((unsigned long) (addr) - #define WRT_REG_BYTE(addr, data) writeb((data), (unsigned long) (addr)) - #define WRT_REG_WORD(addr, data) writew((data), (unsigned long) (addr)) - #define WRT_REG_DWORD(addr, data) writel((data), (unsigned long) (addr)) + #define RD_REG_BYTE(addr) (*((volatile uint8_t *)addr)) + #define RD_REG_WORD(addr) (*((volatile uint16_t *)addr)) + #define RD_REG_DWORD(addr) (*((volatile uint32_t *)addr)) + #define WRT_REG_BYTE(addr, data) (*((volatile uint8_t *)addr) = data) + #define WRT_REG_WORD(addr, data) (*((volatile uint16_t *)addr) = data) + #define WRT_REG_DWORD(addr, data) (*((volatile uint32_t *)addr) = data) #else /* MEMORY_MAPPED_IO */ #define RD_REG_BYTE(addr) (inb((unsigned long)addr)) #define RD_REG_WORD(addr) (inw((unsigned long)addr)) @@ -374,7 +247,8 @@ typedef struct timer_list timer_t; /* timer */ /* - * SCSI Request Block structure + * SCSI Request Block structure (sp) that is placed + * on cmd->SCp location of every I/O */ typedef struct srb { @@ -383,10 +257,11 @@ struct srb *s_prev; /* (4) Previous block on LU queue */ uint8_t flags; /* (1) Status flags. */ uint8_t dir; /* direction of transfer */ - uint8_t unused[2]; - u_long r_start; /* jiffies at start of request */ - u_long u_start; /* jiffies when sent to F/W */ -}srb_t; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18) + dma_addr_t saved_dma_handle; /* for unmap of single transfers */ +#endif + +} srb_t; /* * SRB flag definitions @@ -1564,22 +1439,35 @@ request_t req[REQUEST_ENTRY_CNT+1]; response_t res[RESPONSE_ENTRY_CNT+1]; - unsigned long request_dma; /* Physical address. */ +#if BITS_PER_LONG > 32 + dma_addr_t request_dma; /* Physical Address */ +#else + uint32_t request_dma; /* Physical address. */ +#endif request_t *request_ring; /* Base virtual address */ request_t *request_ring_ptr; /* Current address. */ uint16_t req_ring_index; /* Current index. */ uint16_t req_q_cnt; /* Number of available entries. */ - unsigned long response_dma; /* Physical address. */ +#if BITS_PER_LONG > 32 + dma_addr_t response_dma; /* Physical address. */ +#else + uint32_t response_dma; /* Physical address. */ +#endif response_t *response_ring; /* Base virtual address */ response_t *response_ring_ptr; /* Current address. */ uint16_t rsp_ring_index; /* Current index. */ #if QL1280_TARGET_MODE_SUPPORT /* Target buffer and sense data. */ +#if BITS_PER_LONG > 32 + dma_addr_t tbuf_dma; /* Physical address. */ + dma_addr_t tsense_dma; /* Physical address. */ +#else uint32_t tbuf_dma; /* Physical address. */ - tgt_t *tbuf; uint32_t tsense_dma; /* Physical address. */ +#endif + tgt_t *tbuf; uint8_t *tsense; #endif @@ -1616,8 +1504,13 @@ uint32_t dpc :1; /* 15 */ uint32_t dpc_sched :1; /* 16 */ uint32_t interrupts_on :1; /* 17 */ + uint32_t bios_enabled :1; /* 18 */ }flags; + /* needed holders for PCI ordered list of hosts */ + unsigned long io_port; + uint32_t irq; + }scsi_qla_host_t; /* @@ -1646,6 +1539,8 @@ #define QLA1280_RING_LOCK(ha) #define QLA1280_RING_UNLOCK(ha) +#endif /* HOSTS_C */ + #if defined(__cplusplus) } #endif @@ -1663,49 +1558,20 @@ int qla1280_biosparam(Disk *, kdev_t, int[]); void qla1280_intr_handler(int, void *, struct pt_regs *); void qla1280_setup(char *s, int *dummy); -#if defined(__386__) + # define QLA1280_BIOSPARAM qla1280_biosparam -#else -# define QLA1280_BIOSPARAM NULL -#endif /* * Scsi_Host_template (see hosts.h) * Device driver Interfaces to mid-level SCSI driver. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) -/* This interface is now obsolete !!! */ -#define QLA1280_LINUX_TEMPLATE { \ - next: NULL, \ - usage_count: NULL, \ - proc_dir: NULL, \ - proc_info: NULL, \ - name: "Qlogic ISP 1280", \ - detect: qla1280_detect, \ - release: qla1280_release, \ - info: qla1280_info, \ - command: NULL, \ - queuecommand: qla1280_queuecommand, \ - abort: qla1280_abort, \ - reset: qla1280_reset, \ - slave_attach: NULL, \ - bios_param: QLA1280_BIOSPARAM, \ - can_queue: 255, /* MAX_OUTSTANDING_COMMANDS */ \ - this_id: -1, /* scsi id of host adapter */ \ - sg_tablesize: SG_ALL, \ - cmd_per_lun: 3, /* max commands per lun */ \ - present: 0, /* number of 1280s present */ \ - unchecked_isa_dma: 0, /* no memeory DMA restrictions */ \ - use_clustering: ENABLE_CLUSTERING \ -} -#else -#define QLA1280_LINUX_TEMPLATE { \ +#define QLA1280_LINUX_TEMPLATE { \ next: NULL, \ module: NULL, \ proc_dir: NULL, \ proc_info: qla1280_proc_info, \ - name: "Qlogic ISP 1280\1080", \ + name: "Qlogic ISP 1280\12160", \ detect: qla1280_detect, \ release: qla1280_release, \ info: qla1280_info, \ @@ -1725,13 +1591,14 @@ this_id: -1, /* scsi id of host adapter */\ sg_tablesize: SG_ALL, /* max scatter-gather cmds */\ cmd_per_lun: 3, /* cmds per lun (linked cmds) */\ - present: 0, /* number of 7xxx's present */\ + present: 0, /* number of 1280's present */\ unchecked_isa_dma: 0, /* no memory DMA restrictions */\ use_clustering: ENABLE_CLUSTERING, \ use_new_eh_code: 0, \ emulated: 0 \ } -#endif + #endif /* _IO_HBA_QLA1280_H */ + diff -urN linux-2.4.0-test12/drivers/scsi/simscsi.c linux-2.4.0-test12-lia/drivers/scsi/simscsi.c --- linux-2.4.0-test12/drivers/scsi/simscsi.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/scsi/simscsi.c Mon Oct 30 22:17:11 2000 @@ -0,0 +1,364 @@ +/* + * Simulated SCSI driver. + * + * Copyright (C) 1999 Hewlett-Packard Co + * Copyright (C) 1999 David Mosberger-Tang + * Copyright (C) 1999 Stephane Eranian + * + * 99/12/18 David Mosberger Added support for READ10/WRITE10 needed by linux v2.3.33 + */ +#include +#include +#include +#include +#include + +#include + +#include + +#include "scsi.h" +#include "sd.h" +#include "hosts.h" +#include "simscsi.h" + +#define DEBUG_SIMSCSI 0 + +/* Simulator system calls: */ + +#define SSC_OPEN 50 +#define SSC_CLOSE 51 +#define SSC_READ 52 +#define SSC_WRITE 53 +#define SSC_GET_COMPLETION 54 +#define SSC_WAIT_COMPLETION 55 + +#define SSC_WRITE_ACCESS 2 +#define SSC_READ_ACCESS 1 + +struct timer_list disk_timer; + +struct disk_req { + unsigned long addr; + unsigned len; +}; + +struct disk_stat { + int fd; + unsigned count; +}; + +extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr); + +static int desc[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; + +static struct queue_entry { + Scsi_Cmnd *sc; +} queue[SIMSCSI_REQ_QUEUE_LEN]; + +static int rd, wr; +static atomic_t num_reqs = ATOMIC_INIT(0); + +/* base name for default disks */ +static char *simscsi_root = DEFAULT_SIMSCSI_ROOT; + +#define MAX_ROOT_LEN 128 + +/* + * used to setup a new base for disk images + * to use /foo/bar/disk[a-z] as disk images + * you have to specify simscsi=/foo/bar/disk on the command line + */ +static int __init +simscsi_setup (char *s) +{ + /* XXX Fix me we may need to strcpy() ? */ + if (strlen(s) > MAX_ROOT_LEN) { + printk("simscsi_setup: prefix too long---using default %s\n", simscsi_root); + } + simscsi_root = s; + return 1; +} + +__setup("simscsi=", simscsi_setup); + +static void +simscsi_interrupt (unsigned long val) +{ + unsigned long flags; + Scsi_Cmnd *sc; + + spin_lock_irqsave(&io_request_lock, flags); + { + while ((sc = queue[rd].sc) != 0) { + atomic_dec(&num_reqs); + queue[rd].sc = 0; +#if DEBUG_SIMSCSI + printk("simscsi_interrupt: done with %ld\n", sc->serial_number); +#endif + (*sc->scsi_done)(sc); + rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN; + } + } + spin_unlock_irqrestore(&io_request_lock, flags); +} + +int +simscsi_detect (Scsi_Host_Template *templ) +{ + templ->proc_name = "simscsi"; + init_timer(&disk_timer); + disk_timer.function = simscsi_interrupt; + return 1; /* fake one SCSI host adapter */ +} + +int +simscsi_release (struct Scsi_Host *host) +{ + return 0; /* this is easy... */ +} + +const char * +simscsi_info (struct Scsi_Host *host) +{ + return "simulated SCSI host adapter"; +} + +int +simscsi_abort (Scsi_Cmnd *cmd) +{ + printk ("simscsi_abort: unimplemented\n"); + return SCSI_ABORT_SUCCESS; +} + +int +simscsi_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) +{ + printk ("simscsi_reset: unimplemented\n"); + return SCSI_RESET_SUCCESS; +} + +int +simscsi_biosparam (Disk *disk, kdev_t n, int ip[]) +{ + int size = disk->capacity; + + ip[0] = 64; + ip[1] = 32; + ip[2] = size >> 11; + return 0; +} + +static void +simscsi_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset, unsigned long len) +{ + struct disk_stat stat; + struct disk_req req; + + req.addr = __pa(sc->request_buffer); + req.len = len; /* # of bytes to transfer */ + + if (sc->request_bufflen < req.len) + return; + + stat.fd = desc[sc->target]; +#if DEBUG_SIMSCSI + printk("simscsi_%s @ %lx (off %lx)\n", + mode == SSC_READ ? "read":"write", req.addr, offset); +#endif + ia64_ssc(stat.fd, 1, __pa(&req), offset, mode); + ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION); + + if (stat.count == req.len) { + sc->result = GOOD; + } else { + sc->result = DID_ERROR << 16; + } +} + +static void +simscsi_sg_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset) +{ + int list_len = sc->use_sg; + struct scatterlist *sl = (struct scatterlist *)sc->buffer; + struct disk_stat stat; + struct disk_req req; + + stat.fd = desc[sc->target]; + + while (list_len) { + req.addr = __pa(sl->address); + req.len = sl->length; +#if DEBUG_SIMSCSI + printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n", + mode == SSC_READ ? "read":"write", req.addr, offset, list_len, sl->length); +#endif + ia64_ssc(stat.fd, 1, __pa(&req), offset, mode); + ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION); + + /* should not happen in our case */ + if (stat.count != req.len) { + sc->result = DID_ERROR << 16; + return; + } + offset += sl->length; + sl++; + list_len--; + } + sc->result = GOOD; +} + +/* + * function handling both READ_6/WRITE_6 (non-scatter/gather mode) + * commands. + * Added 02/26/99 S.Eranian + */ +static void +simscsi_readwrite6 (Scsi_Cmnd *sc, int mode) +{ + unsigned long offset; + + offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512; + if (sc->use_sg > 0) + simscsi_sg_readwrite(sc, mode, offset); + else + simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512); +} + + +static void +simscsi_readwrite10 (Scsi_Cmnd *sc, int mode) +{ + unsigned long offset; + + offset = ( (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16) + | (sc->cmnd[4] << 8) | (sc->cmnd[5] << 0))*512; + if (sc->use_sg > 0) + simscsi_sg_readwrite(sc, mode, offset); + else + simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512); +} + +int +simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *)) +{ + char fname[MAX_ROOT_LEN+16]; + char *buf; + +#if DEBUG_SIMSCSI + register long sp asm ("sp"); + printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n", + sc->target, sc->cmnd[0], sc->serial_number, sp, done); +#endif + + sc->result = DID_BAD_TARGET << 16; + sc->scsi_done = done; + if (sc->target <= 7 && sc->lun == 0) { + switch (sc->cmnd[0]) { + case INQUIRY: + if (sc->request_bufflen < 35) { + break; + } + sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target); + desc[sc->target] = ia64_ssc (__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS, + 0, 0, SSC_OPEN); + if (desc[sc->target] < 0) { + /* disk doesn't exist... */ + break; + } + buf = sc->request_buffer; + buf[0] = 0; /* magnetic disk */ + buf[1] = 0; /* not a removable medium */ + buf[2] = 2; /* SCSI-2 compliant device */ + buf[3] = 2; /* SCSI-2 response data format */ + buf[4] = 31; /* additional length (bytes) */ + buf[5] = 0; /* reserved */ + buf[6] = 0; /* reserved */ + buf[7] = 0; /* various flags */ + memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); + sc->result = GOOD; + break; + + case TEST_UNIT_READY: + sc->result = GOOD; + break; + + case READ_6: + if (desc[sc->target] < 0 ) + break; + simscsi_readwrite6(sc, SSC_READ); + break; + + case READ_10: + if (desc[sc->target] < 0 ) + break; + simscsi_readwrite10(sc, SSC_READ); + break; + + case WRITE_6: + if (desc[sc->target] < 0) + break; + simscsi_readwrite6(sc, SSC_WRITE); + break; + + case WRITE_10: + if (desc[sc->target] < 0) + break; + simscsi_readwrite10(sc, SSC_WRITE); + break; + + + case READ_CAPACITY: + if (desc[sc->target] < 0 || sc->request_bufflen < 8) { + break; + } + buf = sc->request_buffer; + + /* pretend to be a 1GB disk (partition table contains real stuff): */ + buf[0] = 0x00; + buf[1] = 0x1f; + buf[2] = 0xff; + buf[3] = 0xff; + /* set block size of 512 bytes: */ + buf[4] = 0; + buf[5] = 0; + buf[6] = 2; + buf[7] = 0; + sc->result = GOOD; + break; + + case MODE_SENSE: + printk("MODE_SENSE\n"); + break; + + case START_STOP: + printk("START_STOP\n"); + break; + + default: + panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]); + } + } + if (sc->result == DID_BAD_TARGET) { + sc->result |= DRIVER_SENSE << 24; + sc->sense_buffer[0] = 0x70; + sc->sense_buffer[2] = 0x00; + } + if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) { + panic("Attempt to queue command while command is pending!!"); + } + atomic_inc(&num_reqs); + queue[wr].sc = sc; + wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN; + + if (!timer_pending(&disk_timer)) { + disk_timer.expires = jiffies + HZ/20; + add_timer(&disk_timer); + } + return 0; +} + + +static Scsi_Host_Template driver_template = SIMSCSI; + +#include "scsi_module.c" diff -urN linux-2.4.0-test12/drivers/scsi/simscsi.h linux-2.4.0-test12-lia/drivers/scsi/simscsi.h --- linux-2.4.0-test12/drivers/scsi/simscsi.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/drivers/scsi/simscsi.h Mon Oct 30 22:17:11 2000 @@ -0,0 +1,39 @@ +/* + * Simulated SCSI driver. + * + * Copyright (C) 1999 Hewlett-Packard Co + * Copyright (C) 1999 David Mosberger-Tang + */ +#ifndef SIMSCSI_H +#define SIMSCSI_H + +#define SIMSCSI_REQ_QUEUE_LEN 64 + +#define DEFAULT_SIMSCSI_ROOT "/var/ski-disks/sd" + +extern int simscsi_detect (Scsi_Host_Template *); +extern int simscsi_release (struct Scsi_Host *); +extern const char *simscsi_info (struct Scsi_Host *); +extern int simscsi_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +extern int simscsi_abort (Scsi_Cmnd *); +extern int simscsi_reset (Scsi_Cmnd *, unsigned int); +extern int simscsi_biosparam (Disk *, kdev_t, int[]); + +#define SIMSCSI { \ + detect: simscsi_detect, \ + release: simscsi_release, \ + info: simscsi_info, \ + queuecommand: simscsi_queuecommand, \ + abort: simscsi_abort, \ + reset: simscsi_reset, \ + bios_param: simscsi_biosparam, \ + can_queue: SIMSCSI_REQ_QUEUE_LEN, \ + this_id: -1, \ + sg_tablesize: 32, \ + cmd_per_lun: SIMSCSI_REQ_QUEUE_LEN, \ + present: 0, \ + unchecked_isa_dma: 0, \ + use_clustering: DISABLE_CLUSTERING \ +} + +#endif /* SIMSCSI_H */ diff -urN linux-2.4.0-test12/drivers/usb/uhci.c linux-2.4.0-test12-lia/drivers/usb/uhci.c --- linux-2.4.0-test12/drivers/usb/uhci.c Wed Dec 13 17:30:18 2000 +++ linux-2.4.0-test12-lia/drivers/usb/uhci.c Thu Dec 14 14:43:23 2000 @@ -39,7 +39,7 @@ #include #include #include -#define DEBUG +#undef DEBUG #include #include diff -urN linux-2.4.0-test12/fs/binfmt_elf.c linux-2.4.0-test12-lia/fs/binfmt_elf.c --- linux-2.4.0-test12/fs/binfmt_elf.c Wed Dec 13 17:30:20 2000 +++ linux-2.4.0-test12-lia/fs/binfmt_elf.c Wed Dec 13 17:31:57 2000 @@ -484,6 +484,20 @@ if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) ibcs2_interpreter = 1; +#if defined(__ia64__) && !defined(CONFIG_BINFMT_ELF32) + /* + * XXX temporary gross hack until all IA-64 Linux binaries + * use /lib/ld-linux-ia64.so.1 as the linker name. + */ +#define INTRP64 "/lib/ld-linux-ia64.so.1" + if (strcmp(elf_interpreter,"/lib/ld-linux.so.2") == 0) { + kfree(elf_interpreter); + elf_interpreter=(char *)kmalloc(sizeof(INTRP64), GFP_KERNEL); + if (!elf_interpreter) + goto out_free_file; + strcpy(elf_interpreter, INTRP64); + } +#endif /* defined(__ia64__) && !defined(CONFIG_BINFMT_ELF32) */ #if 0 printk("Using ELF interpreter %s\n", elf_interpreter); #endif diff -urN linux-2.4.0-test12/fs/fcntl.c linux-2.4.0-test12-lia/fs/fcntl.c --- linux-2.4.0-test12/fs/fcntl.c Wed Dec 6 18:33:28 2000 +++ linux-2.4.0-test12-lia/fs/fcntl.c Wed Dec 6 22:36:29 2000 @@ -269,6 +269,7 @@ * to fix this will be in libc. */ err = filp->f_owner.pid; + force_successful_syscall_return(); break; case F_SETOWN: lock_kernel(); diff -urN linux-2.4.0-test12/fs/nfsd/nfsfh.c linux-2.4.0-test12-lia/fs/nfsd/nfsfh.c --- linux-2.4.0-test12/fs/nfsd/nfsfh.c Mon Oct 16 12:58:51 2000 +++ linux-2.4.0-test12-lia/fs/nfsd/nfsfh.c Wed Nov 1 14:58:08 2000 @@ -379,7 +379,7 @@ /* It's a directory, or we are required to confirm the file's * location in the tree. */ - dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,ino); + dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,(long) ino); down(&sb->s_nfsd_free_path_sem); /* claiming the semaphore might have allowed things to get fixed up */ diff -urN linux-2.4.0-test12/fs/partitions/Config.in linux-2.4.0-test12-lia/fs/partitions/Config.in --- linux-2.4.0-test12/fs/partitions/Config.in Sun Jul 9 22:21:41 2000 +++ linux-2.4.0-test12-lia/fs/partitions/Config.in Wed Nov 1 23:20:37 2000 @@ -23,6 +23,7 @@ bool ' BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL bool ' Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION bool ' Unixware slices support' CONFIG_UNIXWARE_DISKLABEL + bool ' EFI GUID Partition support' CONFIG_EFI_PARTITION fi bool ' SGI partition support' CONFIG_SGI_PARTITION bool ' Ultrix partition table support' CONFIG_ULTRIX_PARTITION diff -urN linux-2.4.0-test12/fs/partitions/Makefile linux-2.4.0-test12-lia/fs/partitions/Makefile --- linux-2.4.0-test12/fs/partitions/Makefile Tue Jul 18 22:49:47 2000 +++ linux-2.4.0-test12-lia/fs/partitions/Makefile Wed Nov 1 23:20:52 2000 @@ -20,6 +20,7 @@ obj-$(CONFIG_SUN_PARTITION) += sun.o obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o obj-$(CONFIG_IBM_PARTITION) += ibm.o +obj-$(CONFIG_EFI_PARTITION) += efi.o O_OBJS += $(obj-y) M_OBJS += $(obj-m) diff -urN linux-2.4.0-test12/fs/partitions/check.c linux-2.4.0-test12-lia/fs/partitions/check.c --- linux-2.4.0-test12/fs/partitions/check.c Mon Oct 16 12:58:51 2000 +++ linux-2.4.0-test12-lia/fs/partitions/check.c Thu Dec 14 14:43:39 2000 @@ -33,6 +33,10 @@ #include "ibm.h" #include "ultrix.h" +#ifdef CONFIG_EFI_PARTITION +# include "efi.h" +#endif + extern void device_init(void); extern int *blk_size[]; extern void rd_load(void); @@ -71,6 +75,9 @@ #endif #ifdef CONFIG_IBM_PARTITION ibm_partition, +#endif +#ifdef CONFIG_EFI_PARTITION + efi_partition, #endif NULL }; diff -urN linux-2.4.0-test12/fs/partitions/efi.c linux-2.4.0-test12-lia/fs/partitions/efi.c --- linux-2.4.0-test12/fs/partitions/efi.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/fs/partitions/efi.c Wed Dec 6 22:36:43 2000 @@ -0,0 +1,607 @@ +/************************************************************ + * EFI GUID Partition Table handling + * Per Intel EFI Specification v0.99 + * http://developer.intel.com/technology/efi/efi.htm + * efi.[ch] by Matt Domsch + * Copyright 2000 Dell Computer Corporation + * + * Note, the EFI Specification, v0.99, has a reference to + * Dr. Dobbs Journal, May 1994 (actually it's in May 1992) + * but that isn't the CRC function being used by EFI. Intel's + * EFI Sample Implementation shows that they use the same function + * as was COPYRIGHT (C) 1986 Gary S. Brown. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * TODO: + * + * Changelog: + * Tue Dec 5 2000 Matt Domsch + * - Moved crc32() to linux/lib, added efi_crc32(). + * + * Thu Nov 30 2000 Matt Domsch + * - Replaced Intel's CRC32 function with an equivalent + * non-license-restricted version. + * + * Wed Oct 25 2000 Matt Domsch + * - Fixed the LastLBA() call to return the proper last block + * + * Thu Oct 12 2000 Matt Domsch + * - Thanks to Andries Brouwer for his debugging assistance. + * - Code works, detects all the partitions. + * + ************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "check.h" +#include "efi.h" + +#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID +extern void md_autodetect_dev(kdev_t dev); +#endif + + +#undef EFI_DEBUG +#ifdef EFI_DEBUG +static char *efi_printk_level = KERN_DEBUG; +#define debug_printk printk +#else +#define debug_printk(...) +#endif + +/************************************************************ + * efi_crc32() + * Requires: + * - a buffer of length len + * Modifies: nothing + * Returns: + * EFI-style CRC32 value for buf + * + * This function uses the crc32 function by Gary S. Brown, + * but seeds the function with ~0, and xor's with ~0 at the end. + ************************************************************/ + +u32 static inline +efi_crc32(const void *buf, unsigned long len) +{ + return (crc32(buf, len, ~0L) ^ ~0L); +} + + + + +/************************************************************ + * IsLegacyMBRValid() + * Requires: + * - mbr is a pointer to a legacy mbr structure + * Modifies: nothing + * Returns: + * 1 on true + * 0 on false + ************************************************************/ +static inline int +IsLegacyMBRValid(LegacyMBR_t *mbr) +{ + return (mbr ? (mbr->Signature == MSDOS_MBR_SIGNATURE) : 0); +} + + + +/************************************************************ + * LastLBA() + * Requires: + * - struct gendisk hd + * - kdev_t dev + * Modifies: nothing + * Returns: + * Last LBA value on success. This is stored (by sd and + * ide-geometry) in + * the part[0] entry for this disk, and is the number of + * physical sectors available on the disk. + * 0 on error + ************************************************************/ +u64 +LastLBA(struct gendisk *hd, kdev_t dev) +{ + if (!hd || !hd->part) return 0; + return hd->part[MINOR(dev)].nr_sects - 1; +} + + +/************************************************************ + * ReadLBA() + * Requires: + * - hd is our disk device. + * - dev is our device major number + * - lba is the logical block address desired (disk hardsector number) + * - buffer is a buffer of size size into which data copied + * - size_t count is size of the read (in bytes) + * Modifies: + * - buffer + * Returns: + * - count of bytes read + * - 0 on error + * Bugs: + * - bread() takes second argument as a signed int, not a u64. + * This is because getblk() takes the block number as a signed int. + * This overflow is known on l-k. We overflow at about 1TB. + * + ************************************************************/ + +static size_t +ReadLBA(struct gendisk *hd, kdev_t dev, u64 _lba, u8 *buffer, size_t count) +{ + struct buffer_head *bh; + size_t totalreadcount = 0, bytesread; + int lba = (_lba & 0x7FFFFFFF), i, blockstoread, blocksize; + debug_printk(efi_printk_level "ReadLBA(%p,%s,%x,%p,%x)\n", + hd, kdevname(dev), lba, buffer, count); + + if (!hd || !buffer || !count) return 0; + + + blocksize = get_hardblocksize(dev); + if (!blocksize) blocksize = 512; + blockstoread = count / blocksize; + if (count % blocksize) blockstoread += 1; + debug_printk(efi_printk_level "about to read %d blocks\n", + blockstoread); + + + for (i=0; i bh->b_size ? bh->b_size : count); + memcpy(buffer, bh->b_data, bytesread); + + buffer += bytesread; /* Advance the buffer pointer */ + totalreadcount += bytesread; /* Advance the total read count */ + count -= bytesread; /* Subtract bytesread from count */ + + brelse(bh); + } + + return totalreadcount; +} + +void +PrintGuidPartitionTableHeader(GuidPartitionTableHeader_t *gpt) +{ + debug_printk(efi_printk_level "GUID Partition Table Header\n"); + if (!gpt) return; + debug_printk(efi_printk_level "Signature : %lx\n", + gpt->Signature); + debug_printk(efi_printk_level "Revision : %x\n", + gpt->Revision); + debug_printk(efi_printk_level "HeaderSize : %x\n", + gpt->HeaderSize); + debug_printk(efi_printk_level "HeaderCRC32 : %x\n", + gpt->HeaderCRC32); + debug_printk(efi_printk_level "MyLBA : %lx\n", + gpt->MyLBA); + debug_printk(efi_printk_level "AlternateLBA : %lx\n", + gpt->AlternateLBA); + debug_printk(efi_printk_level "FirstUsableLBA : %lx\n", + gpt->FirstUsableLBA); + debug_printk(efi_printk_level "LastUsableLBA : %lx\n", + gpt->LastUsableLBA); + + debug_printk(efi_printk_level "PartitionEntryLBA : %lx\n", + gpt->PartitionEntryLBA); + debug_printk(efi_printk_level "NumberOfPartitionEntries : %x\n", + gpt->NumberOfPartitionEntries); + debug_printk(efi_printk_level "SizeOfPartitionEntry : %x\n", + gpt->SizeOfPartitionEntry); + debug_printk(efi_printk_level "PartitionEntryArrayCRC32 : %x\n", + gpt->PartitionEntryArrayCRC32); + + return; +} + + + +/************************************************************ + * ReadGuidPartitionEntries() + * Requires: + * - filedes is an open file descriptor, suitable for reading + * - lba is the Logical Block Address of the partition table + * - gpt is a buffer into which the GPT will be put + * Modifies: + * - filedes file and pointer + * - gpt + * Returns: + * pte on success + * NULL on error + * Notes: remember to free pte when you're done! + ************************************************************/ +GuidPartitionEntry_t * +ReadGuidPartitionEntries(struct gendisk *hd, kdev_t dev, + GuidPartitionTableHeader_t *gpt) +{ + size_t count; + GuidPartitionEntry_t *pte; + if (!hd || !gpt) return NULL; + + count = gpt->NumberOfPartitionEntries * gpt->SizeOfPartitionEntry; + debug_printk(efi_printk_level "ReadGPTEs() kmallocing %x bytes\n", + count); + if (!count) return NULL; + pte = kmalloc(count, GFP_KERNEL); + if (!pte) return NULL; + memset(pte, 0, count); + + if (ReadLBA(hd, dev, gpt->PartitionEntryLBA, (u8 *)pte, + count) < count) { + kfree(pte); + return NULL; + } + return pte; +} + + + +/************************************************************ + * ReadGuidPartitionTableHeader() + * Requires: + * - hd is our struct gendisk + * - dev is our device major number + * - lba is the Logical Block Address of the partition table + * - gpt is a buffer into which the GPT will be put + * - pte is a buffer into which the PTEs will be put + * Modifies: + * - gpt and pte + * Returns: + * 1 on success + * 0 on error + ************************************************************/ + +GuidPartitionTableHeader_t * +ReadGuidPartitionTableHeader(struct gendisk *hd, kdev_t dev, u64 lba) + +{ + GuidPartitionTableHeader_t *gpt; + if (!hd) return NULL; + + gpt = kmalloc(sizeof(GuidPartitionTableHeader_t), GFP_KERNEL); + if (!gpt) return NULL; + memset(gpt, 0, sizeof(GuidPartitionTableHeader_t)); + + debug_printk(efi_printk_level "GPTH() calling ReadLBA().\n"); + if (ReadLBA(hd, dev, lba, (u8 *)gpt, + sizeof(GuidPartitionTableHeader_t)) < + sizeof(GuidPartitionTableHeader_t)) { + debug_printk(efi_printk_level "ReadGPTH(%lx) read failed.\n", + lba); + kfree(gpt); + return NULL; + } + PrintGuidPartitionTableHeader(gpt); + + return gpt; +} + + + +/************************************************************ + * IsGuidPartitionTableValid() + * Requires: + * - gd points to our struct gendisk + * - dev is our device major number + * - lba is the logical block address of the GPTH to test + * - gpt is a GPTH if it's valid + * - ptes is a PTEs if it's valid + * Modifies: + * - gpt and ptes + * Returns: + * 1 if valid + * 0 on error + ************************************************************/ +static int +IsGuidPartitionTableValid(struct gendisk *hd, kdev_t dev, u64 lba, + GuidPartitionTableHeader_t **gpt, + GuidPartitionEntry_t **ptes) +{ + u32 crc, origcrc; + + if (!hd || !gpt || !ptes) return 0; + if (!(*gpt = ReadGuidPartitionTableHeader(hd, dev, lba))) return 0; + + /* Check the GUID Partition Table Signature */ + if ((*gpt)->Signature != GUID_PT_HEADER_SIGNATURE) { + debug_printk(efi_printk_level "GUID Partition Table Header Signature is wrong: %x != %x\n", (*gpt)->Signature, GUID_PT_HEADER_SIGNATURE); + kfree(*gpt); + *gpt = NULL; + return 0; + } + + /* Check the GUID Partition Table CRC */ + origcrc = (*gpt)->HeaderCRC32; + (*gpt)->HeaderCRC32 = 0; + crc = efi_crc32((const unsigned char *)(*gpt), (*gpt)->HeaderSize); + + + if (crc != origcrc) { + debug_printk(efi_printk_level "GUID Partition Table Header CRC is wrong: %x != %x\n", (*gpt)->HeaderCRC32, origcrc); + kfree(*gpt); + *gpt = NULL; + return 0; + } + (*gpt)->HeaderCRC32 = origcrc; + + /* Check that the MyLBA entry points to the LBA that contains + * the GUID Partition Table */ + if ((*gpt)->MyLBA != lba) { + debug_printk(efi_printk_level "GPT MyLBA incorrect: %lx != %lx\n", (*gpt)->MyLBA, lba); + kfree(*gpt); + *gpt = NULL; + return 0; + } + + if (!(*ptes = ReadGuidPartitionEntries(hd, dev, *gpt))) { + debug_printk(efi_printk_level "read PTEs failed.\n"); + kfree(*gpt); + *gpt = NULL; + return 0; + } + + /* Check the GUID Partition Entry Array CRC */ + crc = efi_crc32((const unsigned char *)(*ptes), + (*gpt)->NumberOfPartitionEntries * + (*gpt)->SizeOfPartitionEntry); + + if (crc != (*gpt)->PartitionEntryArrayCRC32) { + debug_printk(efi_printk_level "GUID Partitition Entry Array CRC check failed.\n"); + kfree(*gpt); + *gpt = NULL; + kfree(*ptes); + *ptes = NULL; + return 0; + } + + + /* We're done, all's well */ + return 1; +} + + + +/************************************************************ + * FindValidGPT() + * Requires: + * - gd points to our struct gendisk + * - dev is our device major number + * - gpt is a GPTH if it's valid + * - ptes is a PTE + * Modifies: + * - gpt & ptes + * Returns: + * 1 if valid + * 0 on error + ************************************************************/ +static int +FindValidGPT(struct gendisk *hd, kdev_t dev, + GuidPartitionTableHeader_t **gpt, + GuidPartitionEntry_t **ptes) +{ + int rc = 0; + GuidPartitionTableHeader_t *pgpt = NULL, *agpt = NULL; + GuidPartitionEntry_t *pptes = NULL, *aptes = NULL; + u64 lastlba; + if (!hd || !gpt || !ptes) return 0; + + lastlba = LastLBA(hd, dev); + /* Check the Primary GPT */ + rc = IsGuidPartitionTableValid(hd, dev, 1, &pgpt, &pptes); + if (rc) { + /* Primary GPT is OK, check the alternate and warn if bad */ + rc = IsGuidPartitionTableValid(hd, dev, pgpt->AlternateLBA, + &agpt, &aptes); + if (!rc){ + printk(KERN_WARNING "Alternate GPT is invalid, using primary GPT.\n"); + } + + *gpt = pgpt; + *ptes = pptes; + if (agpt) kfree(agpt); + if (aptes) kfree(aptes); + return 1; + } /* if primary is valid */ + else { + /* Primary GPT is bad, check the Alternate GPT */ + rc = IsGuidPartitionTableValid(hd, dev, lastlba, + &agpt, &aptes); + if (rc) { + /* Primary is bad, alternate is good. + Return values from the alternate and warn. + */ + printk(KERN_WARNING "Primary GPT is invalid, using alternate GPT.\n"); + *gpt = agpt; + *ptes = aptes; + return 1; + } + else { + /* Primary is bad, alternate is bad, try "other" + * alternate. This is necessary because if we + * have an odd-sized disk, user-space might + * have put the alternate in block lastlba-1. + */ + if (!(lastlba & 1)) { + lastlba--; + rc = IsGuidPartitionTableValid(hd, dev, + lastlba, + &agpt, &aptes); + if (rc) { + /* Primary is bad, alternate is good. + * Return values from the alternate + * and warn. + */ + printk("Primary GPT is invalid, using alternate GPT.\n"); + *gpt = agpt; + *ptes = aptes; + return 1; + } + } + } + } + /* Both primary and alternate GPTs are bad. + * This isn't our disk, return 0. + */ + return 0; +} + + + +/* + * Create devices for each entry in the GUID Partition Table Entries. + * The first block of each partition is a Legacy MBR. + * + * We do not create a Linux partition for GPT, but + * only for the actual data partitions. + * Returns: + * -1 if unable to read the partition table + * 0 if this isn't our partition table + * 1 if successful + * + */ + +static int +add_gpt_partitions(struct gendisk *hd, kdev_t dev, int nextminor) +{ + GuidPartitionTableHeader_t *gpt = NULL; + GuidPartitionEntry_t *ptes = NULL; + u32 i, nummade=0; + + efi_guid_t unusedGuid = UNUSED_ENTRY_GUID; +#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID + efi_guid_t raidGuid = PARTITION_LINUX_RAID_GUID; +#endif + + if (!hd) return -1; + + if (!FindValidGPT(hd, dev, &gpt, &ptes) || + !gpt || !ptes) { + if (gpt) kfree(gpt); + if (ptes) kfree(ptes); + return 0; + } + + debug_printk(efi_printk_level "GUID Partition Table is valid! Yea!\n"); + for (i = 0; i < gpt->NumberOfPartitionEntries && + nummade < (hd->max_p - 1); i++) { + if (!efi_guidcmp(unusedGuid, ptes[i].PartitionTypeGuid)) + continue; + + add_gd_partition(hd, nextminor, ptes[i].StartingLBA, + (ptes[i].EndingLBA-ptes[i].StartingLBA + 1)); + + /* If there's this is a RAID volume, tell md */ +#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID + if (!efi_guidcmp(raidGuid, ptes[i].PartitionTypeGuid)) { + md_autodetect_dev(MKDEV(MAJOR(dev),nextminor)); + } +#endif + nummade++; + nextminor++; + + } + kfree(ptes); + kfree(gpt); + printk("\n"); + return 1; + +} + + +/* + * efi_partition() + * + * If the first block on the disk is a legacy MBR, + * it got handled already by msdos_partition(). + * If it's a Protective MBR, we'll handle it here. + * + * Returns: + * -1 if unable to read the partition table + * 0 if this isn't our partitoin table + * 1 if successful + * + */ + +int +efi_partition(struct gendisk *hd, kdev_t dev, + unsigned long first_sector, int first_part_minor) { + int hardblocksize = get_hardblocksize(dev); + int orig_blksize_size = BLOCK_SIZE; + int rc = 0; + + /* not good, but choose something! */ + if (!hardblocksize) hardblocksize = 512; + + /* Need to change the block size that the block layer uses */ + if (blksize_size[MAJOR(dev)]){ + orig_blksize_size = blksize_size[MAJOR(dev)][MINOR(dev)]; + } + + if (orig_blksize_size != hardblocksize) + set_blocksize(dev, hardblocksize); + + rc = add_gpt_partitions(hd, dev, first_part_minor); + + /* change back */ + if (orig_blksize_size != hardblocksize) + set_blocksize(dev, orig_blksize_size); + + return rc; +} + + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-indent-level: 4 + * c-brace-imaginary-offset: 0 + * c-brace-offset: -4 + * c-argdecl-indent: 4 + * c-label-offset: -4 + * c-continued-statement-offset: 4 + * c-continued-brace-offset: 0 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ + + + diff -urN linux-2.4.0-test12/fs/partitions/efi.h linux-2.4.0-test12-lia/fs/partitions/efi.h --- linux-2.4.0-test12/fs/partitions/efi.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/fs/partitions/efi.h Wed Dec 6 23:24:02 2000 @@ -0,0 +1,154 @@ +/************************************************************ + * EFI GUID Partition Table + * Per Intel EFI Specification v0.99 + * http://developer.intel.com/technology/efi/efi.htm + * + * By Matt Domsch Fri Sep 22 22:15:56 CDT 2000 + * Copyright 2000 Dell Computer Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + ************************************************************/ + +#ifndef FS_PART_EFI_H_INCLUDED +#define FS_PART_EFI_H_INCLUDED + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MSDOS_MBR_SIGNATURE 0xaa55 +#define EFI_PMBR_OSTYPE_EFI 0xEF +#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE + +#define GUID_PT_BLOCK_SIZE 512 + +#define GUID_PT_HEADER_SIGNATURE 0x5452415020494645L +#define GUID_PT_HEADER_REVISION_V1 0x00010000 +#define GUID_PT_HEADER_REVISION_V0_99 0x00000099 +#define UNUSED_ENTRY_GUID \ + ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}) +#define PARTITION_SYSTEM_GUID \ +((efi_guid_t) { 0xC12A7328, 0xF81F, 0x11d2, { 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B }}) +#define LEGACY_MBR_PARTITION_GUID \ + ((efi_guid_t) { 0x024DEE41, 0x33E7, 0x11d3, { 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F }}) +#define PARTITION_MSFT_RESERVED_GUID \ + ((efi_guid_t) { 0xE3C9E316, 0x0B5C, 0x4DB8, { 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE }}) +#define PARTITION_BASIC_DATA_GUID \ + ((efi_guid_t) { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }}) +#define PARTITION_LINUX_RAID_GUID \ + ((efi_guid_t) { 0xa19d880f, 0x05fc, 0x4d3b, { 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }}) +#define PARTITION_LINUX_SWAP_GUID \ + ((efi_guid_t) { 0x0657fd6d, 0xa4ab, 0x43c4, { 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f }}) + +typedef struct _GuidPartitionTableHeader_t { + u64 Signature; + u32 Revision; + u32 HeaderSize; + u32 HeaderCRC32; + u32 Reserved1; + u64 MyLBA; + u64 AlternateLBA; + u64 FirstUsableLBA; + u64 LastUsableLBA; + efi_guid_t DiskGUID; + u64 PartitionEntryLBA; + u32 NumberOfPartitionEntries; + u32 SizeOfPartitionEntry; + u32 PartitionEntryArrayCRC32; + u8 Reserved2[GUID_PT_BLOCK_SIZE - 92]; +} GuidPartitionTableHeader_t; + +typedef struct _GuidPartitionEntryAttributes_t { + __u64 RequiredToFunction:1; + __u64 Reserved:63; +} GuidPartitionEntryAttributes_t; + +typedef struct _GuidPartitionEntry_t { + efi_guid_t PartitionTypeGuid; + efi_guid_t UniquePartitionGuid; + u64 StartingLBA; + u64 EndingLBA; + GuidPartitionEntryAttributes_t Attributes; + efi_char16_t PartitionName[72/sizeof(efi_char16_t)]; +} GuidPartitionEntry_t; + + + +typedef struct _PartitionRecord_t { + u8 BootIndicator; /* Not used by EFI firmware. Set to 0x80 to indicate that this + is the bootable legacy partition. */ + u8 StartHead; /* Start of partition in CHS address, not used by EFI firmware. */ + u8 StartSector; /* Start of partition in CHS address, not used by EFI firmware. */ + u8 StartTrack; /* Start of partition in CHS address, not used by EFI firmware. */ + u8 OSType; /* OS type. A value of 0xEF defines an EFI system partition. + Other values are reserved for legacy operating systems, and + allocated independently of the EFI specification. */ + u8 EndHead; /* End of partition in CHS address, not used by EFI firmware. */ + u8 EndSector; /* End of partition in CHS address, not used by EFI firmware. */ + u8 EndTrack; /* End of partition in CHS address, not used by EFI firmware. */ + u32 StartingLBA; /* Starting LBA address of the partition on the disk. Used by + EFI firmware to define the start of the partition. */ + u32 SizeInLBA; /* Size of partition in LBA. Used by EFI firmware to determine + the size of the partition. */ +} PartitionRecord_t; + +typedef struct _LegacyMBR_t { + u8 BootCode[440]; + u32 UniqueMBRSignature; + u16 Unknown; + PartitionRecord_t PartitionRecord[4]; + u16 Signature; +} __attribute__ ((packed)) LegacyMBR_t; + + + +#define EFI_GPT_PRIMARY_PARTITION_TABLE_LBA 1 + +/* Functions */ +extern int +efi_partition(struct gendisk *hd, kdev_t dev, + unsigned long first_sector, int first_part_minor); + + + + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * -------------------------------------------------------------------------- + * Local variables: + * c-indent-level: 4 + * c-brace-imaginary-offset: 0 + * c-brace-offset: -4 + * c-argdecl-indent: 4 + * c-label-offset: -4 + * c-continued-statement-offset: 4 + * c-continued-brace-offset: 0 + * indent-tabs-mode: nil + * tab-width: 8 + * End: + */ diff -urN linux-2.4.0-test12/fs/partitions/msdos.c linux-2.4.0-test12-lia/fs/partitions/msdos.c --- linux-2.4.0-test12/fs/partitions/msdos.c Tue Jul 18 23:29:16 2000 +++ linux-2.4.0-test12-lia/fs/partitions/msdos.c Thu Nov 2 00:10:33 2000 @@ -36,6 +36,10 @@ #include "check.h" #include "msdos.h" +#ifdef CONFIG_EFI_PARTITION +#include "efi.h" +#endif + #if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID extern void md_autodetect_dev(kdev_t dev); #endif @@ -378,6 +382,16 @@ bforget(bh); return 0; } +#ifdef CONFIG_EFI_PARTITION + p = (struct partition *) (0x1be + data); + for (i=1 ; i<=4 ; i++,p++) { + /* If this is an EFI GPT disk, msdos should ignore it. */ + if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) { + bforget(bh); + return 0; + } + } +#endif p = (struct partition *) (0x1be + data); #ifdef CONFIG_BLK_DEV_IDE diff -urN linux-2.4.0-test12/include/asm-ia64/a.out.h linux-2.4.0-test12-lia/include/asm-ia64/a.out.h --- linux-2.4.0-test12/include/asm-ia64/a.out.h Sun Feb 6 18:42:40 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/a.out.h Wed Dec 6 22:36:55 2000 @@ -7,14 +7,13 @@ * probably would be better to clean up binfmt_elf.c so it does not * necessarily depend on there being a.out support. * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998-2000 Hewlett-Packard Co + * Copyright (C) 1998-2000 David Mosberger-Tang */ #include -struct exec -{ +struct exec { unsigned long a_info; unsigned long a_text; unsigned long a_data; @@ -31,7 +30,7 @@ #define N_TXTOFF(x) 0 #ifdef __KERNEL__ -# define STACK_TOP 0xa000000000000000UL +# define STACK_TOP (0x8000000000000000UL + (1UL << (4*PAGE_SHIFT - 12))) # define IA64_RBS_BOT (STACK_TOP - 0x80000000L) /* bottom of register backing store */ #endif diff -urN linux-2.4.0-test12/include/asm-ia64/acpi-ext.h linux-2.4.0-test12-lia/include/asm-ia64/acpi-ext.h --- linux-2.4.0-test12/include/asm-ia64/acpi-ext.h Mon Oct 9 17:54:57 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/acpi-ext.h Wed Dec 6 22:37:07 2000 @@ -8,19 +8,27 @@ * * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + * ACPI 2.0 specification */ #include +#pragma pack(1) #define ACPI_RSDP_SIG "RSD PTR " /* Trailing space required */ #define ACPI_RSDP_SIG_LEN 8 typedef struct { char signature[8]; u8 checksum; char oem_id[6]; - char reserved; /* Must be 0 */ - struct acpi_rsdt *rsdt; -} acpi_rsdp_t; + u8 revision; + u32 rsdt; + u32 lenth; + struct acpi_xsdt *xsdt; + u8 ext_checksum; + u8 reserved[3]; +} acpi20_rsdp_t; typedef struct { char signature[4]; @@ -32,20 +40,73 @@ u32 oem_revision; u32 creator_id; u32 creator_revision; - char reserved[4]; } acpi_desc_table_hdr_t; #define ACPI_RSDT_SIG "RSDT" #define ACPI_RSDT_SIG_LEN 4 -typedef struct acpi_rsdt { +typedef struct { + acpi_desc_table_hdr_t header; + u8 reserved[4]; + u32 entry_ptrs[1]; /* Not really . . . */ +} acpi20_rsdt_t; + +#define ACPI_XSDT_SIG "XSDT" +#define ACPI_XSDT_SIG_LEN 4 +typedef struct acpi_xsdt { acpi_desc_table_hdr_t header; unsigned long entry_ptrs[1]; /* Not really . . . */ +} acpi_xsdt_t; + +/* Common structures for ACPI 2.0 and 0.71 */ + +typedef struct acpi_entry_iosapic { + u8 type; + u8 length; + u8 id; + u8 reserved; + u32 irq_base; /* start of IRQ's this IOSAPIC is responsible for. */ + unsigned long address; /* Address of this IOSAPIC */ +} acpi_entry_iosapic_t; + +/* Local SAPIC flags */ +#define LSAPIC_ENABLED (1<<0) +#define LSAPIC_PERFORMANCE_RESTRICTED (1<<1) +#define LSAPIC_PRESENT (1<<2) + +/* Defines legacy IRQ->pin mapping */ +typedef struct { + u8 type; + u8 length; + u8 bus; /* Constant 0 == ISA */ + u8 isa_irq; /* ISA IRQ # */ + u32 pin; /* called vector in spec; really IOSAPIC pin number */ + u16 flags; /* Edge/Level trigger & High/Low active */ +} acpi_entry_int_override_t; + +#define INT_OVERRIDE_ACTIVE_LOW 0x03 +#define INT_OVERRIDE_LEVEL_TRIGGER 0x0d + +/* IA64 ext 0.71 */ + +typedef struct { + char signature[8]; + u8 checksum; + char oem_id[6]; + char reserved; /* Must be 0 */ + struct acpi_rsdt *rsdt; +} acpi_rsdp_t; + +typedef struct { + acpi_desc_table_hdr_t header; + u8 reserved[4]; + unsigned long entry_ptrs[1]; /* Not really . . . */ } acpi_rsdt_t; #define ACPI_SAPIC_SIG "SPIC" #define ACPI_SAPIC_SIG_LEN 4 typedef struct { acpi_desc_table_hdr_t header; + u8 reserved[4]; unsigned long interrupt_block; } acpi_sapic_t; @@ -55,11 +116,6 @@ #define ACPI_ENTRY_INT_SRC_OVERRIDE 2 #define ACPI_ENTRY_PLATFORM_INT_SOURCE 3 /* Unimplemented */ -/* Local SAPIC flags */ -#define LSAPIC_ENABLED (1<<0) -#define LSAPIC_PERFORMANCE_RESTRICTED (1<<1) -#define LSAPIC_PRESENT (1<<2) - typedef struct acpi_entry_lsapic { u8 type; u8 length; @@ -69,42 +125,71 @@ u8 eid; } acpi_entry_lsapic_t; -typedef struct acpi_entry_iosapic { +typedef struct { u8 type; u8 length; - u16 reserved; - u32 irq_base; /* start of IRQ's this IOSAPIC is responsible for. */ - unsigned long address; /* Address of this IOSAPIC */ -} acpi_entry_iosapic_t; + u16 flags; + u8 int_type; + u8 id; + u8 eid; + u8 iosapic_vector; + u8 reserved[4]; + u32 global_vector; +} acpi_entry_platform_src_t; -/* Defines legacy IRQ->pin mapping */ +/* ACPI 2.0 with 1.3 errata specific structures */ + +#define ACPI_MADT_SIG "APIC" +#define ACPI_MADT_SIG_LEN 4 typedef struct { + acpi_desc_table_hdr_t header; + u32 lapic_address; + u32 flags; +} acpi_madt_t; + +/* acpi 2.0 MADT structure types */ +#define ACPI20_ENTRY_LOCAL_APIC 0 +#define ACPI20_ENTRY_IO_APIC 1 +#define ACPI20_ENTRY_INT_SRC_OVERRIDE 2 +#define ACPI20_ENTRY_NMI_SOURCE 3 +#define ACPI20_ENTRY_LOCAL_APIC_NMI 4 +#define ACPI20_ENTRY_LOCAL_APIC_ADDR_OVERRIDE 5 +#define ACPI20_ENTRY_IO_SAPIC 6 +#define ACPI20_ENTRY_LOCAL_SAPIC 7 +#define ACPI20_ENTRY_PLATFORM_INT_SOURCE 8 + +typedef struct acpi20_entry_lsapic { u8 type; u8 length; - u8 bus; /* Constant 0 == ISA */ - u8 isa_irq; /* ISA IRQ # */ - u8 pin; /* called vector in spec; really IOSAPIC pin number */ - u32 flags; /* Edge/Level trigger & High/Low active */ - u8 reserved[6]; -} acpi_entry_int_override_t; -#define INT_OVERRIDE_ACTIVE_LOW 0x03 -#define INT_OVERRIDE_LEVEL_TRIGGER 0x0d + u8 acpi_processor_id; + u8 id; + u8 eid; + u8 reserved[3]; + u32 flags; +} acpi20_entry_lsapic_t; + +typedef struct acpi20_entry_lapic_addr_override { + u8 type; + u8 length; + u8 reserved[2]; + unsigned long lapic_address; +} acpi20_entry_lapic_addr_override_t; typedef struct { u8 type; u8 length; - u32 flags; + u16 flags; u8 int_type; u8 id; u8 eid; u8 iosapic_vector; - unsigned long reserved; - unsigned long global_vector; -} acpi_entry_platform_src_t; + u32 global_vector; +} acpi20_entry_platform_src_t; +extern int acpi20_parse(acpi20_rsdp_t *); extern int acpi_parse(acpi_rsdp_t *); extern const char *acpi_get_sysname (void); extern void (*acpi_idle) (void); /* power-management idle function, if any */ - +#pragma pack() #endif /* _ASM_IA64_ACPI_EXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/acpikcfg.h linux-2.4.0-test12-lia/include/asm-ia64/acpikcfg.h --- linux-2.4.0-test12/include/asm-ia64/acpikcfg.h Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/acpikcfg.h Wed Dec 6 22:46:31 2000 @@ -1,3 +1,4 @@ +#ifdef CONFIG_ACPI_KERNEL_CONFIG /* * acpikcfg.h - ACPI based Kernel Configuration Manager External Interfaces * @@ -5,9 +6,6 @@ * Copyright (C) 2000 J.I. Lee */ -#include - -#ifdef CONFIG_ACPI_KERNEL_CONFIG u32 __init acpi_cf_init (void * rsdp); u32 __init acpi_cf_terminate (void ); diff -urN linux-2.4.0-test12/include/asm-ia64/cache.h linux-2.4.0-test12-lia/include/asm-ia64/cache.h --- linux-2.4.0-test12/include/asm-ia64/cache.h Fri Apr 21 15:21:24 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/cache.h Wed Dec 6 23:13:08 2000 @@ -9,11 +9,11 @@ */ /* Bytes per L1 (data) cache line. */ -#define LOG_L1_CACHE_BYTES 6 -#define L1_CACHE_BYTES (1 << LOG_L1_CACHE_BYTES) +#define L1_CACHE_SHIFT 6 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #ifdef CONFIG_SMP -# define SMP_LOG_CACHE_BYTES LOG_L1_CACHE_BYTES +# define SMP_CACHE_SHIFT L1_CACHE_SHIFT # define SMP_CACHE_BYTES L1_CACHE_BYTES #else /* @@ -21,7 +21,7 @@ * safe and provides an easy way to avoid wasting space on a * uni-processor: */ -# define SMP_LOG_CACHE_BYTES 3 +# define SMP_CACHE_SHIFT 3 # define SMP_CACHE_BYTES (1 << 3) #endif diff -urN linux-2.4.0-test12/include/asm-ia64/delay.h linux-2.4.0-test12-lia/include/asm-ia64/delay.h --- linux-2.4.0-test12/include/asm-ia64/delay.h Mon Oct 9 17:54:57 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/delay.h Wed Dec 6 23:13:25 2000 @@ -55,6 +55,10 @@ unsigned long result; __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); +#ifdef CONFIG_ITANIUM + while (__builtin_expect ((__s32) result == -1, 0)) + __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); +#endif return result; } diff -urN linux-2.4.0-test12/include/asm-ia64/efi.h linux-2.4.0-test12-lia/include/asm-ia64/efi.h --- linux-2.4.0-test12/include/asm-ia64/efi.h Mon Oct 9 17:54:58 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/efi.h Wed Dec 6 23:13:14 2000 @@ -168,6 +168,9 @@ #define ACPI_TABLE_GUID \ ((efi_guid_t) { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }}) +#define ACPI_20_TABLE_GUID \ + ((efi_guid_t) { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 }}) + #define SMBIOS_TABLE_GUID \ ((efi_guid_t) { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }}) @@ -204,7 +207,8 @@ extern struct efi { efi_system_table_t *systab; /* EFI system table */ void *mps; /* MPS table */ - void *acpi; /* ACPI table */ + void *acpi; /* ACPI table (IA64 ext 0.71) */ + void *acpi20; /* ACPI table (ACPI 2.0) */ void *smbios; /* SM BIOS table */ void *sal_systab; /* SAL system table */ void *boot_info; /* boot info table */ diff -urN linux-2.4.0-test12/include/asm-ia64/hw_irq.h linux-2.4.0-test12-lia/include/asm-ia64/hw_irq.h --- linux-2.4.0-test12/include/asm-ia64/hw_irq.h Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/hw_irq.h Thu Dec 14 14:43:48 2000 @@ -6,8 +6,12 @@ * Copyright (C) 2000 David Mosberger-Tang */ +#include + +#include #include +#include #include #include @@ -29,13 +33,22 @@ #define IA64_SPURIOUS_INT 0x0f -#define IA64_MIN_VECTORED_IRQ 16 -#define IA64_MAX_VECTORED_IRQ 255 +/* + * Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI. + */ +#define PCE_IRQ 0x1e /* platform corrected error interrupt vector */ +#define CMC_IRQ 0x1f /* correctable machine-check interrupt vector */ +/* + * Vectors 0x20-0x2f are reserved for legacy ISA IRQs. + */ +#define FIRST_DEVICE_IRQ 0x30 +#define LAST_DEVICE_IRQ 0xe7 -#define PERFMON_IRQ 0x28 /* performanc monitor interrupt vector */ +#define MCA_RENDEZ_IRQ 0xe8 /* MCA rendez interrupt */ +#define PERFMON_IRQ 0xee /* performanc monitor interrupt vector */ #define TIMER_IRQ 0xef /* use highest-prio group 15 interrupt for timer */ +#define MCA_WAKEUP_IRQ 0xf0 /* MCA wakeup interrupt (must be higher than MCA_RENDEZ_IRQ) */ #define IPI_IRQ 0xfe /* inter-processor interrupt vector */ -#define CMC_IRQ 0xff /* correctable machine-check interrupt vector */ /* IA64 inter-cpu interrupt related definitions */ @@ -60,12 +73,13 @@ extern struct hw_interrupt_type irq_type_ia64_sapic; /* CPU-internal interrupt controller */ -extern void ipi_send (int cpu, int vector, int delivery_mode, int redirect); +extern int ia64_alloc_irq (void); /* allocate a free irq */ +extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector) { - ipi_send(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); + platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); } #endif /* _ASM_IA64_HW_IRQ_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/ia32.h linux-2.4.0-test12-lia/include/asm-ia64/ia32.h --- linux-2.4.0-test12/include/asm-ia64/ia32.h Mon Oct 9 17:54:58 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/ia32.h Wed Dec 6 23:14:18 2000 @@ -5,6 +5,8 @@ #ifdef CONFIG_IA32_SUPPORT +#include + /* * 32 bit structures for IA32 support. */ @@ -32,6 +34,8 @@ #define IA32_PAGE_SHIFT 12 /* 4KB pages */ #define IA32_PAGE_SIZE (1ULL << IA32_PAGE_SHIFT) +#define IA32_CLOCKS_PER_SEC 100 /* Cast in stone for IA32 Linux */ +#define IA32_TICK(tick) ((unsigned long long)(tick) * IA32_CLOCKS_PER_SEC / CLOCKS_PER_SEC) /* fcntl.h */ struct flock32 { diff -urN linux-2.4.0-test12/include/asm-ia64/io.h linux-2.4.0-test12-lia/include/asm-ia64/io.h --- linux-2.4.0-test12/include/asm-ia64/io.h Mon Oct 9 17:54:58 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/io.h Wed Dec 6 23:13:07 2000 @@ -29,6 +29,7 @@ # ifdef __KERNEL__ +#include #include #include @@ -54,8 +55,7 @@ #define bus_to_virt phys_to_virt #define virt_to_bus virt_to_phys -# else /* !KERNEL */ -# endif /* !KERNEL */ +# endif /* KERNEL */ /* * Memory fence w/accept. This should never be used in code that is @@ -100,7 +100,7 @@ */ static inline unsigned int -__inb (unsigned long port) +__ia64_inb (unsigned long port) { volatile unsigned char *addr = __ia64_mk_io_addr(port); unsigned char ret; @@ -111,7 +111,7 @@ } static inline unsigned int -__inw (unsigned long port) +__ia64_inw (unsigned long port) { volatile unsigned short *addr = __ia64_mk_io_addr(port); unsigned short ret; @@ -122,7 +122,7 @@ } static inline unsigned int -__inl (unsigned long port) +__ia64_inl (unsigned long port) { volatile unsigned int *addr = __ia64_mk_io_addr(port); unsigned int ret; @@ -133,112 +133,148 @@ } static inline void -__insb (unsigned long port, void *dst, unsigned long count) +__ia64_outb (unsigned char val, unsigned long port) { volatile unsigned char *addr = __ia64_mk_io_addr(port); - unsigned char *dp = dst; + *addr = val; __ia64_mf_a(); - while (count--) { - *dp++ = *addr; - } - __ia64_mf_a(); - return; } static inline void -__insw (unsigned long port, void *dst, unsigned long count) +__ia64_outw (unsigned short val, unsigned long port) { volatile unsigned short *addr = __ia64_mk_io_addr(port); - unsigned short *dp = dst; + *addr = val; __ia64_mf_a(); - while (count--) { - *dp++ = *addr; - } - __ia64_mf_a(); - return; } static inline void -__insl (unsigned long port, void *dst, unsigned long count) +__ia64_outl (unsigned int val, unsigned long port) { volatile unsigned int *addr = __ia64_mk_io_addr(port); - unsigned int *dp = dst; + *addr = val; __ia64_mf_a(); - while (count--) { - *dp++ = *addr; - } - __ia64_mf_a(); - return; } static inline void -__outb (unsigned char val, unsigned long port) +__insb (unsigned long port, void *dst, unsigned long count) { - volatile unsigned char *addr = __ia64_mk_io_addr(port); + unsigned char *dp = dst; - *addr = val; - __ia64_mf_a(); + if (platform_inb == __ia64_inb) { + volatile unsigned char *addr = __ia64_mk_io_addr(port); + + __ia64_mf_a(); + while (count--) + *dp++ = *addr; + __ia64_mf_a(); + } else + while (count--) + *dp++ = platform_inb(port); + return; } static inline void -__outw (unsigned short val, unsigned long port) +__insw (unsigned long port, void *dst, unsigned long count) { - volatile unsigned short *addr = __ia64_mk_io_addr(port); + unsigned short *dp = dst; - *addr = val; - __ia64_mf_a(); + if (platform_inw == __ia64_inw) { + volatile unsigned short *addr = __ia64_mk_io_addr(port); + + __ia64_mf_a(); + while (count--) + *dp++ = *addr; + __ia64_mf_a(); + } else + while (count--) + *dp++ = platform_inw(port); + return; } static inline void -__outl (unsigned int val, unsigned long port) +__insl (unsigned long port, void *dst, unsigned long count) { - volatile unsigned int *addr = __ia64_mk_io_addr(port); + unsigned int *dp = dst; - *addr = val; - __ia64_mf_a(); + if (platform_inl == __ia64_inl) { + volatile unsigned int *addr = __ia64_mk_io_addr(port); + + __ia64_mf_a(); + while (count--) + *dp++ = *addr; + __ia64_mf_a(); + } else + while (count--) + *dp++ = platform_inl(port); + return; } static inline void __outsb (unsigned long port, const void *src, unsigned long count) { - volatile unsigned char *addr = __ia64_mk_io_addr(port); const unsigned char *sp = src; - while (count--) { - *addr = *sp++; - } - __ia64_mf_a(); + if (platform_outb == __ia64_outb) { + volatile unsigned char *addr = __ia64_mk_io_addr(port); + + while (count--) + *addr = *sp++; + __ia64_mf_a(); + } else + while (count--) + platform_outb(*sp++, port); return; } static inline void __outsw (unsigned long port, const void *src, unsigned long count) { - volatile unsigned short *addr = __ia64_mk_io_addr(port); const unsigned short *sp = src; - while (count--) { - *addr = *sp++; - } - __ia64_mf_a(); + if (platform_outw == __ia64_outw) { + volatile unsigned short *addr = __ia64_mk_io_addr(port); + + while (count--) + *addr = *sp++; + __ia64_mf_a(); + } else + while (count--) + platform_outw(*sp++, port); return; } static inline void __outsl (unsigned long port, void *src, unsigned long count) { - volatile unsigned int *addr = __ia64_mk_io_addr(port); const unsigned int *sp = src; - while (count--) { - *addr = *sp++; - } - __ia64_mf_a(); + if (platform_outl == __ia64_outl) { + volatile unsigned int *addr = __ia64_mk_io_addr(port); + + while (count--) + *addr = *sp++; + __ia64_mf_a(); + } else + while (count--) + platform_outl(*sp++, port); return; } + +/* + * Unfortunately, some platforms are broken and do not follow the + * IA-64 architecture specification regarding legacy I/O support. + * Thus, we have to make these operations platform dependent... + */ +#define __inb platform_inb +#define __inw platform_inw +#define __inl platform_inl +#define __outb platform_outb +#define __outw platform_outw +#define __outl platform_outl #define inb __inb #define inw __inw diff -urN linux-2.4.0-test12/include/asm-ia64/iosapic.h linux-2.4.0-test12-lia/include/asm-ia64/iosapic.h --- linux-2.4.0-test12/include/asm-ia64/iosapic.h Thu Jun 22 07:09:45 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/iosapic.h Wed Dec 6 22:37:31 2000 @@ -3,121 +3,60 @@ #include -#define IO_SAPIC_DEFAULT_ADDR 0xFEC00000 +#define IOSAPIC_DEFAULT_ADDR 0xFEC00000 -#define IO_SAPIC_REG_SELECT 0x0 -#define IO_SAPIC_WINDOW 0x10 -#define IO_SAPIC_EOI 0x40 +#define IOSAPIC_REG_SELECT 0x0 +#define IOSAPIC_WINDOW 0x10 +#define IOSAPIC_EOI 0x40 -#define IO_SAPIC_VERSION 0x1 +#define IOSAPIC_VERSION 0x1 /* * Redirection table entry */ +#define IOSAPIC_RTE_LOW(i) (0x10+i*2) +#define IOSAPIC_RTE_HIGH(i) (0x11+i*2) -#define IO_SAPIC_RTE_LOW(i) (0x10+i*2) -#define IO_SAPIC_RTE_HIGH(i) (0x11+i*2) - - -#define IO_SAPIC_DEST_SHIFT 16 +#define IOSAPIC_DEST_SHIFT 16 /* * Delivery mode */ - -#define IO_SAPIC_DELIVERY_SHIFT 8 -#define IO_SAPIC_FIXED 0x0 -#define IO_SAPIC_LOWEST_PRIORITY 0x1 -#define IO_SAPIC_PMI 0x2 -#define IO_SAPIC_NMI 0x4 -#define IO_SAPIC_INIT 0x5 -#define IO_SAPIC_EXTINT 0x7 +#define IOSAPIC_DELIVERY_SHIFT 8 +#define IOSAPIC_FIXED 0x0 +#define IOSAPIC_LOWEST_PRIORITY 0x1 +#define IOSAPIC_PMI 0x2 +#define IOSAPIC_NMI 0x4 +#define IOSAPIC_INIT 0x5 +#define IOSAPIC_EXTINT 0x7 /* * Interrupt polarity */ - -#define IO_SAPIC_POLARITY_SHIFT 13 -#define IO_SAPIC_POL_HIGH 0 -#define IO_SAPIC_POL_LOW 1 +#define IOSAPIC_POLARITY_SHIFT 13 +#define IOSAPIC_POL_HIGH 0 +#define IOSAPIC_POL_LOW 1 /* * Trigger mode */ - -#define IO_SAPIC_TRIGGER_SHIFT 15 -#define IO_SAPIC_EDGE 0 -#define IO_SAPIC_LEVEL 1 +#define IOSAPIC_TRIGGER_SHIFT 15 +#define IOSAPIC_EDGE 0 +#define IOSAPIC_LEVEL 1 /* * Mask bit */ - -#define IO_SAPIC_MASK_SHIFT 16 -#define IO_SAPIC_UNMASK 0 -#define IO_SAPIC_MSAK 1 - -/* - * Bus types - */ -#define BUS_ISA 0 /* ISA Bus */ -#define BUS_PCI 1 /* PCI Bus */ - -#ifndef CONFIG_IA64_PCI_FIRMWARE_IRQ -struct intr_routing_entry { - unsigned char srcbus; - unsigned char srcbusno; - unsigned char srcbusirq; - unsigned char iosapic_pin; - unsigned char dstiosapic; - unsigned char mode; - unsigned char trigger; - unsigned char polarity; -}; - -extern struct intr_routing_entry intr_routing[]; -#endif +#define IOSAPIC_MASK_SHIFT 16 +#define IOSAPIC_UNMASK 0 +#define IOSAPIC_MSAK 1 #ifndef __ASSEMBLY__ -#include - -/* - * IOSAPIC Version Register return 32 bit structure like: - * { - * unsigned int version : 8; - * unsigned int reserved1 : 8; - * unsigned int pins : 8; - * unsigned int reserved2 : 8; - * } - */ -extern unsigned int iosapic_version(unsigned long); -extern void iosapic_init(unsigned long, int); - -struct iosapic_vector { - unsigned long iosapic_base; /* IOSAPIC Base address */ - char pin; /* IOSAPIC pin (-1 == No data) */ - unsigned char bus; /* Bus number */ - unsigned char baseirq; /* Base IRQ handled by this IOSAPIC */ - unsigned char bustype; /* Bus type (ISA, PCI, etc) */ - unsigned int busdata; /* Bus specific ID */ - /* These bitfields use the values defined above */ - unsigned char dmode : 3; - unsigned char polarity : 1; - unsigned char trigger : 1; - unsigned char UNUSED : 3; -}; -extern struct iosapic_vector iosapic_vector[NR_IRQS]; - -#define iosapic_addr(v) iosapic_vector[v].iosapic_base -#define iosapic_pin(v) iosapic_vector[v].pin -#define iosapic_bus(v) iosapic_vector[v].bus -#define iosapic_baseirq(v) iosapic_vector[v].baseirq -#define iosapic_bustype(v) iosapic_vector[v].bustype -#define iosapic_busdata(v) iosapic_vector[v].busdata -#define iosapic_dmode(v) iosapic_vector[v].dmode -#define iosapic_trigger(v) iosapic_vector[v].trigger -#define iosapic_polarity(v) iosapic_vector[v].polarity +extern void __init iosapic_init (unsigned long address, unsigned int base_irq); +extern void iosapic_register_legacy_irq (unsigned long irq, unsigned long pin, + unsigned long polarity, unsigned long trigger); +extern void iosapic_pci_fixup (int); # endif /* !__ASSEMBLY__ */ #endif /* __ASM_IA64_IOSAPIC_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/machvec.h linux-2.4.0-test12-lia/include/asm-ia64/machvec.h --- linux-2.4.0-test12/include/asm-ia64/machvec.h Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/machvec.h Thu Dec 14 14:44:03 2000 @@ -14,24 +14,46 @@ #include /* forward declarations: */ -struct hw_interrupt_type; -struct irq_desc; -struct mm_struct; +struct pci_dev; struct pt_regs; -struct task_struct; -struct timeval; -struct vm_area_struct; -struct acpi_entry_iosapic; +struct scatterlist; typedef void ia64_mv_setup_t (char **); typedef void ia64_mv_irq_init_t (void); -typedef void ia64_mv_pci_fixup_t (void); +typedef void ia64_mv_pci_fixup_t (int); typedef unsigned long ia64_mv_map_nr_t (unsigned long); typedef void ia64_mv_mca_init_t (void); typedef void ia64_mv_mca_handler_t (void); typedef void ia64_mv_cmci_handler_t (int, void *, struct pt_regs *); typedef void ia64_mv_log_print_t (void); -typedef void ia64_mv_register_iosapic_t (struct acpi_entry_iosapic *); +typedef void ia64_mv_send_ipi_t (int, int, int, int); + +/* PCI-DMA interface: */ +typedef void ia64_mv_pci_dma_init (void); +typedef void *ia64_mv_pci_alloc_consistent (struct pci_dev *, size_t, dma_addr_t *); +typedef void ia64_mv_pci_free_consistent (struct pci_dev *, size_t, void *, dma_addr_t); +typedef dma_addr_t ia64_mv_pci_map_single (struct pci_dev *, void *, size_t, int); +typedef void ia64_mv_pci_unmap_single (struct pci_dev *, dma_addr_t, size_t, int); +typedef int ia64_mv_pci_map_sg (struct pci_dev *, struct scatterlist *, int, int); +typedef void ia64_mv_pci_unmap_sg (struct pci_dev *, struct scatterlist *, int, int); +typedef void ia64_mv_pci_dma_sync_single (struct pci_dev *, dma_addr_t, size_t, int); +typedef void ia64_mv_pci_dma_sync_sg (struct pci_dev *, struct scatterlist *, int, int); +typedef unsigned long ia64_mv_pci_dma_address (struct scatterlist *); +/* + * WARNING: The legacy I/O space is _architected_. Platforms are + * expected to follow this architected model (see Section 10.7 in the + * IA-64 Architecture Software Developer's Manual). Unfortunately, + * some broken machines do not follow that model, which is why we have + * to make the inX/outX operations part of the machine vector. + * Platform designers should follow the architected model whenever + * possible. + */ +typedef unsigned int ia64_mv_inb_t (unsigned long); +typedef unsigned int ia64_mv_inw_t (unsigned long); +typedef unsigned int ia64_mv_inl_t (unsigned long); +typedef void ia64_mv_outb_t (unsigned char, unsigned long); +typedef void ia64_mv_outw_t (unsigned short, unsigned long); +typedef void ia64_mv_outl_t (unsigned int, unsigned long); extern void machvec_noop (void); @@ -39,7 +61,7 @@ # include # elif defined (CONFIG_IA64_DIG) # include -# elif defined (CONFIG_IA64_SGI_SN1_SIM) +# elif defined (CONFIG_IA64_SGI_SN1) # include # elif defined (CONFIG_IA64_GENERIC) @@ -55,7 +77,23 @@ # define platform_cmci_handler ia64_mv.cmci_handler # define platform_log_print ia64_mv.log_print # define platform_pci_fixup ia64_mv.pci_fixup -# define platform_register_iosapic ia64_mv.register_iosapic +# define platform_send_ipi ia64_mv.send_ipi +# define platform_pci_dma_init ia64_mv.dma_init +# define platform_pci_alloc_consistent ia64_mv.alloc_consistent +# define platform_pci_free_consistent ia64_mv.free_consistent +# define platform_pci_map_single ia64_mv.map_single +# define platform_pci_unmap_single ia64_mv.unmap_single +# define platform_pci_map_sg ia64_mv.map_sg +# define platform_pci_unmap_sg ia64_mv.unmap_sg +# define platform_pci_dma_sync_single ia64_mv.sync_single +# define platform_pci_dma_sync_sg ia64_mv.sync_sg +# define platform_pci_dma_address ia64_mv.dma_address +# define platform_inb ia64_mv.inb +# define platform_inw ia64_mv.inw +# define platform_inl ia64_mv.inl +# define platform_outb ia64_mv.outb +# define platform_outw ia64_mv.outw +# define platform_outl ia64_mv.outl # endif struct ia64_machine_vector { @@ -68,7 +106,23 @@ ia64_mv_mca_handler_t *mca_handler; ia64_mv_cmci_handler_t *cmci_handler; ia64_mv_log_print_t *log_print; - ia64_mv_register_iosapic_t *register_iosapic; + ia64_mv_send_ipi_t *send_ipi; + ia64_mv_pci_dma_init *dma_init; + ia64_mv_pci_alloc_consistent *alloc_consistent; + ia64_mv_pci_free_consistent *free_consistent; + ia64_mv_pci_map_single *map_single; + ia64_mv_pci_unmap_single *unmap_single; + ia64_mv_pci_map_sg *map_sg; + ia64_mv_pci_unmap_sg *unmap_sg; + ia64_mv_pci_dma_sync_single *sync_single; + ia64_mv_pci_dma_sync_sg *sync_sg; + ia64_mv_pci_dma_address *dma_address; + ia64_mv_inb_t *inb; + ia64_mv_inw_t *inw; + ia64_mv_inl_t *inl; + ia64_mv_outb_t *outb; + ia64_mv_outw_t *outw; + ia64_mv_outl_t *outl; }; #define MACHVEC_INIT(name) \ @@ -82,7 +136,23 @@ platform_mca_handler, \ platform_cmci_handler, \ platform_log_print, \ - platform_register_iosapic \ + platform_send_ipi, \ + platform_pci_dma_init, \ + platform_pci_alloc_consistent, \ + platform_pci_free_consistent, \ + platform_pci_map_single, \ + platform_pci_unmap_single, \ + platform_pci_map_sg, \ + platform_pci_unmap_sg, \ + platform_pci_dma_sync_single, \ + platform_pci_dma_sync_sg, \ + platform_pci_dma_address, \ + platform_inb, \ + platform_inw, \ + platform_inl, \ + platform_outb, \ + platform_outw, \ + platform_outl \ } extern struct ia64_machine_vector ia64_mv; @@ -93,6 +163,20 @@ # endif /* CONFIG_IA64_GENERIC */ /* + * Declare default routines which aren't declared anywhere else: + */ +extern ia64_mv_pci_dma_init swiotlb_init; +extern ia64_mv_pci_alloc_consistent swiotlb_alloc_consistent; +extern ia64_mv_pci_free_consistent swiotlb_free_consistent; +extern ia64_mv_pci_map_single swiotlb_map_single; +extern ia64_mv_pci_unmap_single swiotlb_unmap_single; +extern ia64_mv_pci_map_sg swiotlb_map_sg; +extern ia64_mv_pci_unmap_sg swiotlb_unmap_sg; +extern ia64_mv_pci_dma_sync_single swiotlb_sync_single; +extern ia64_mv_pci_dma_sync_sg swiotlb_sync_sg; +extern ia64_mv_pci_dma_address swiotlb_dma_address; + +/* * Define default versions so we can extend machvec for new platforms without having * to update the machvec files for all existing platforms. */ @@ -117,8 +201,56 @@ #ifndef platform_pci_fixup # define platform_pci_fixup ((ia64_mv_pci_fixup_t *) machvec_noop) #endif -#ifndef platform_register_iosapic -# define platform_register_iosapic ((ia64_mv_register_iosapic_t *) machvec_noop) +#ifndef platform_send_ipi +# define platform_send_ipi ia64_send_ipi /* default to architected version */ +#endif +#ifndef platform_pci_dma_init +# define platform_pci_dma_init swiotlb_init +#endif +#ifndef platform_pci_alloc_consistent +# define platform_pci_alloc_consistent swiotlb_alloc_consistent +#endif +#ifndef platform_pci_free_consistent +# define platform_pci_free_consistent swiotlb_free_consistent +#endif +#ifndef platform_pci_map_single +# define platform_pci_map_single swiotlb_map_single +#endif +#ifndef platform_pci_unmap_single +# define platform_pci_unmap_single swiotlb_unmap_single +#endif +#ifndef platform_pci_map_sg +# define platform_pci_map_sg swiotlb_map_sg +#endif +#ifndef platform_pci_unmap_sg +# define platform_pci_unmap_sg swiotlb_unmap_sg +#endif +#ifndef platform_pci_dma_sync_single +# define platform_pci_dma_sync_single swiotlb_sync_single +#endif +#ifndef platform_pci_dma_sync_sg +# define platform_pci_dma_sync_sg swiotlb_sync_sg +#endif +#ifndef platform_pci_dma_address +# define platform_pci_dma_address swiotlb_dma_address +#endif +#ifndef platform_inb +# define platform_inb __ia64_inb +#endif +#ifndef platform_inw +# define platform_inw __ia64_inw +#endif +#ifndef platform_inl +# define platform_inl __ia64_inl +#endif +#ifndef platform_outb +# define platform_outb __ia64_outb +#endif +#ifndef platform_outw +# define platform_outw __ia64_outw +#endif +#ifndef platform_outl +# define platform_outl __ia64_outl #endif #endif /* _ASM_IA64_MACHVEC_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/machvec_dig.h linux-2.4.0-test12-lia/include/asm-ia64/machvec_dig.h --- linux-2.4.0-test12/include/asm-ia64/machvec_dig.h Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/machvec_dig.h Wed Nov 15 18:15:39 2000 @@ -3,9 +3,8 @@ extern ia64_mv_setup_t dig_setup; extern ia64_mv_irq_init_t dig_irq_init; -extern ia64_mv_pci_fixup_t dig_pci_fixup; +extern ia64_mv_pci_fixup_t iosapic_pci_fixup; extern ia64_mv_map_nr_t map_nr_dense; -extern ia64_mv_register_iosapic_t dig_register_iosapic; /* * This stuff has dual use! @@ -17,8 +16,7 @@ #define platform_name "dig" #define platform_setup dig_setup #define platform_irq_init dig_irq_init -#define platform_pci_fixup dig_pci_fixup +#define platform_pci_fixup iosapic_pci_fixup #define platform_map_nr map_nr_dense -#define platform_register_iosapic dig_register_iosapic #endif /* _ASM_IA64_MACHVEC_DIG_h */ diff -urN linux-2.4.0-test12/include/asm-ia64/machvec_hpsim.h linux-2.4.0-test12-lia/include/asm-ia64/machvec_hpsim.h --- linux-2.4.0-test12/include/asm-ia64/machvec_hpsim.h Fri Jul 14 16:08:12 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/machvec_hpsim.h Wed Nov 15 18:15:49 2000 @@ -15,7 +15,6 @@ #define platform_name "hpsim" #define platform_setup hpsim_setup #define platform_irq_init hpsim_irq_init -#define platform_pci_fixup hpsim_pci_fixup #define platform_map_nr map_nr_dense #endif /* _ASM_IA64_MACHVEC_HPSIM_h */ diff -urN linux-2.4.0-test12/include/asm-ia64/machvec_init.h linux-2.4.0-test12-lia/include/asm-ia64/machvec_init.h --- linux-2.4.0-test12/include/asm-ia64/machvec_init.h Fri Aug 11 19:09:06 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/machvec_init.h Wed Nov 15 22:08:12 2000 @@ -4,6 +4,14 @@ #include +extern ia64_mv_send_ipi_t ia64_send_ipi; +extern ia64_mv_inb_t __ia64_inb; +extern ia64_mv_inw_t __ia64_inw; +extern ia64_mv_inl_t __ia64_inl; +extern ia64_mv_outb_t __ia64_outb; +extern ia64_mv_outw_t __ia64_outw; +extern ia64_mv_outl_t __ia64_outl; + #define MACHVEC_HELPER(name) \ struct ia64_machine_vector machvec_##name __attribute__ ((unused, __section__ (".machvec"))) \ = MACHVEC_INIT(name); diff -urN linux-2.4.0-test12/include/asm-ia64/machvec_sn1.h linux-2.4.0-test12-lia/include/asm-ia64/machvec_sn1.h --- linux-2.4.0-test12/include/asm-ia64/machvec_sn1.h Sun Feb 6 18:42:40 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/machvec_sn1.h Wed Dec 6 22:37:56 2000 @@ -4,6 +4,14 @@ extern ia64_mv_setup_t sn1_setup; extern ia64_mv_irq_init_t sn1_irq_init; extern ia64_mv_map_nr_t sn1_map_nr; +extern ia64_mv_send_ipi_t sn1_send_IPI; +extern ia64_mv_pci_fixup_t sn1_pci_fixup; +extern ia64_mv_inb_t sn1_inb; +extern ia64_mv_inw_t sn1_inw; +extern ia64_mv_inl_t sn1_inl; +extern ia64_mv_outb_t sn1_outb; +extern ia64_mv_outw_t sn1_outw; +extern ia64_mv_outl_t sn1_outl; /* * This stuff has dual use! @@ -16,5 +24,13 @@ #define platform_setup sn1_setup #define platform_irq_init sn1_irq_init #define platform_map_nr sn1_map_nr +#define platform_send_ipi sn1_send_IPI +#define platform_pci_fixup sn1_pci_fixup +#define platform_inb sn1_inb +#define platform_inw sn1_inw +#define platform_inl sn1_inl +#define platform_outb sn1_outb +#define platform_outw sn1_outw +#define platform_outl sn1_outl #endif /* _ASM_IA64_MACHVEC_SN1_h */ diff -urN linux-2.4.0-test12/include/asm-ia64/mca.h linux-2.4.0-test12-lia/include/asm-ia64/mca.h --- linux-2.4.0-test12/include/asm-ia64/mca.h Fri Apr 21 15:21:24 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/mca.h Wed Dec 6 23:14:18 2000 @@ -18,6 +18,7 @@ #include #include #include +#include /* These are the return codes from all the IA64_MCA specific interfaces */ typedef int ia64_mca_return_code_t; @@ -30,9 +31,9 @@ #define IA64_MCA_RENDEZ_TIMEOUT (100 * HZ) /* 1000 milliseconds */ /* Interrupt vectors reserved for MC handling. */ -#define IA64_MCA_RENDEZ_INT_VECTOR 0xF3 /* Rendez interrupt */ -#define IA64_MCA_WAKEUP_INT_VECTOR 0x12 /* Wakeup interrupt */ -#define IA64_MCA_CMC_INT_VECTOR 0xF2 /* Correctable machine check interrupt */ +#define IA64_MCA_RENDEZ_INT_VECTOR MCA_RENDEZ_IRQ /* Rendez interrupt */ +#define IA64_MCA_WAKEUP_INT_VECTOR MCA_WAKEUP_IRQ /* Wakeup interrupt */ +#define IA64_MCA_CMC_INT_VECTOR CMC_IRQ /* Correctable machine check interrupt */ #define IA64_CMC_INT_DISABLE 0 #define IA64_CMC_INT_ENABLE 1 @@ -45,11 +46,11 @@ u64 cmcv_regval; struct { u64 cmcr_vector : 8; - u64 cmcr_ignored1 : 47; + u64 cmcr_reserved1 : 4; + u64 cmcr_ignored1 : 1; + u64 cmcr_reserved2 : 3; u64 cmcr_mask : 1; - u64 cmcr_reserved1 : 3; - u64 cmcr_ignored2 : 1; - u64 cmcr_reserved2 : 4; + u64 cmcr_ignored2 : 47; } cmcv_reg_s; } cmcv_reg_t; diff -urN linux-2.4.0-test12/include/asm-ia64/mman.h linux-2.4.0-test12-lia/include/asm-ia64/mman.h --- linux-2.4.0-test12/include/asm-ia64/mman.h Fri Apr 21 15:21:24 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/mman.h Mon Oct 30 22:54:48 2000 @@ -23,6 +23,8 @@ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_WRITECOMBINED 0x10000 /* write-combine the area */ +#define MAP_NONCACHED 0x20000 /* don't cache the memory */ #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ diff -urN linux-2.4.0-test12/include/asm-ia64/mmu_context.h linux-2.4.0-test12-lia/include/asm-ia64/mmu_context.h --- linux-2.4.0-test12/include/asm-ia64/mmu_context.h Mon Oct 9 17:54:59 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/mmu_context.h Wed Dec 6 23:13:10 2000 @@ -32,20 +32,11 @@ #define IA64_REGION_ID_KERNEL 0 /* the kernel's region id (tlb.c depends on this being 0) */ -#define IA64_REGION_ID_BITS 18 - -#ifdef CONFIG_IA64_TLB_CHECKS_REGION_NUMBER -# define IA64_HW_CONTEXT_BITS IA64_REGION_ID_BITS -#else -# define IA64_HW_CONTEXT_BITS (IA64_REGION_ID_BITS - 3) -#endif - -#define IA64_HW_CONTEXT_MASK ((1UL << IA64_HW_CONTEXT_BITS) - 1) - struct ia64_ctx { spinlock_t lock; unsigned int next; /* next context number to use */ unsigned int limit; /* next >= limit => must call wrap_mmu_context() */ + unsigned int max_ctx; /* max. context value supported by all CPUs */ }; extern struct ia64_ctx ia64_ctx; @@ -60,11 +51,7 @@ static inline unsigned long ia64_rid (unsigned long context, unsigned long region_addr) { -# ifdef CONFIG_IA64_TLB_CHECKS_REGION_NUMBER - return context; -# else return context << 3 | (region_addr >> 61); -# endif } static inline void @@ -108,12 +95,8 @@ unsigned long rid_incr = 0; unsigned long rr0, rr1, rr2, rr3, rr4; - rid = mm->context; - -#ifndef CONFIG_IA64_TLB_CHECKS_REGION_NUMBER - rid <<= 3; /* make space for encoding the region number */ + rid = mm->context << 3; /* make space for encoding the region number */ rid_incr = 1 << 8; -#endif /* encode the region id, preferred page size, and VHPT enable bit: */ rr0 = (rid << 8) | (PAGE_SHIFT << 2) | 1; @@ -132,11 +115,10 @@ } /* - * Switch from address space PREV to address space NEXT. Note that - * TSK may be NULL. + * Switch from address space PREV to address space NEXT. */ static inline void -switch_mm (struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) +activate_mm (struct mm_struct *prev, struct mm_struct *next) { /* * We may get interrupts here, but that's OK because interrupt @@ -147,7 +129,6 @@ reload_context(next); } -#define activate_mm(prev,next) \ - switch_mm((prev), (next), NULL, smp_processor_id()) +#define switch_mm(prev_mm,next_mm,next_task,cpu) activate_mm(prev_mm, next_mm) #endif /* _ASM_IA64_MMU_CONTEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/module.h linux-2.4.0-test12-lia/include/asm-ia64/module.h --- linux-2.4.0-test12/include/asm-ia64/module.h Mon Oct 9 17:54:59 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/module.h Wed Dec 6 23:17:44 2000 @@ -75,10 +75,10 @@ /* * Pointers are reasonable, add the module unwind table */ - archdata->unw_table = unw_add_unwind_table(mod->name, archdata->segment_base, + archdata->unw_table = unw_add_unwind_table(mod->name, + (unsigned long) archdata->segment_base, (unsigned long) archdata->gp, - (unsigned long) archdata->unw_start, - (unsigned long) archdata->unw_end); + archdata->unw_start, archdata->unw_end); #endif /* CONFIG_IA64_NEW_UNWIND */ return 0; } @@ -98,7 +98,7 @@ archdata = (struct archdata *)(mod->archdata_start); if (archdata->unw_table != NULL) - unw_remove_unwind_table(archdata->unw_table); + unw_remove_unwind_table((void *) archdata->unw_table); } #endif /* CONFIG_IA64_NEW_UNWIND */ diff -urN linux-2.4.0-test12/include/asm-ia64/offsets.h linux-2.4.0-test12-lia/include/asm-ia64/offsets.h --- linux-2.4.0-test12/include/asm-ia64/offsets.h Mon Oct 9 17:54:59 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/offsets.h Thu Dec 14 14:44:18 2000 @@ -1,17 +1,14 @@ #ifndef _ASM_IA64_OFFSETS_H #define _ASM_IA64_OFFSETS_H - /* * DO NOT MODIFY * - * This file was generated by arch/ia64/tools/print_offsets. + * This file was generated by arch/ia64/tools/print_offsets.awk. * */ - -#define PT_PTRACED_BIT 0 -#define PT_TRACESYS_BIT 1 - -#define IA64_TASK_SIZE 3328 /* 0xd00 */ +#define PT_PTRACED_BIT 0 +#define PT_TRACESYS_BIT 1 +#define IA64_TASK_SIZE 3360 /* 0xd20 */ #define IA64_PT_REGS_SIZE 400 /* 0x190 */ #define IA64_SWITCH_STACK_SIZE 560 /* 0x230 */ #define IA64_SIGINFO_SIZE 128 /* 0x80 */ @@ -21,10 +18,10 @@ #define IA64_TASK_SIGPENDING_OFFSET 16 /* 0x10 */ #define IA64_TASK_NEED_RESCHED_OFFSET 40 /* 0x28 */ #define IA64_TASK_PROCESSOR_OFFSET 100 /* 0x64 */ -#define IA64_TASK_THREAD_OFFSET 1424 /* 0x590 */ -#define IA64_TASK_THREAD_KSP_OFFSET 1424 /* 0x590 */ -#define IA64_TASK_THREAD_SIGMASK_OFFSET 3184 /* 0xc70 */ -#define IA64_TASK_PID_OFFSET 188 /* 0xbc */ +#define IA64_TASK_THREAD_OFFSET 1456 /* 0x5b0 */ +#define IA64_TASK_THREAD_KSP_OFFSET 1456 /* 0x5b0 */ +#define IA64_TASK_THREAD_SIGMASK_OFFSET 3216 /* 0xc90 */ +#define IA64_TASK_PID_OFFSET 196 /* 0xc4 */ #define IA64_TASK_MM_OFFSET 88 /* 0x58 */ #define IA64_PT_REGS_CR_IPSR_OFFSET 0 /* 0x0 */ #define IA64_PT_REGS_CR_IIP_OFFSET 8 /* 0x8 */ @@ -73,7 +70,7 @@ #define IA64_PT_REGS_F8_OFFSET 368 /* 0x170 */ #define IA64_PT_REGS_F9_OFFSET 384 /* 0x180 */ #define IA64_SWITCH_STACK_CALLER_UNAT_OFFSET 0 /* 0x0 */ -#define IA64_SWITCH_STACK_AR_FPSR_OFFSET 8 /* 0x8 */ +#define IA64_SWITCH_STACK_AR_FPSR_OFFSET 8 /* 0x8 */ #define IA64_SWITCH_STACK_F2_OFFSET 16 /* 0x10 */ #define IA64_SWITCH_STACK_F3_OFFSET 32 /* 0x20 */ #define IA64_SWITCH_STACK_F4_OFFSET 48 /* 0x30 */ @@ -112,16 +109,16 @@ #define IA64_SWITCH_STACK_B5_OFFSET 504 /* 0x1f8 */ #define IA64_SWITCH_STACK_AR_PFS_OFFSET 512 /* 0x200 */ #define IA64_SWITCH_STACK_AR_LC_OFFSET 520 /* 0x208 */ -#define IA64_SWITCH_STACK_AR_UNAT_OFFSET 528 /* 0x210 */ -#define IA64_SWITCH_STACK_AR_RNAT_OFFSET 536 /* 0x218 */ +#define IA64_SWITCH_STACK_AR_UNAT_OFFSET 528 /* 0x210 */ +#define IA64_SWITCH_STACK_AR_RNAT_OFFSET 536 /* 0x218 */ #define IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET 544 /* 0x220 */ -#define IA64_SWITCH_STACK_PR_OFFSET 464 /* 0x1d0 */ +#define IA64_SWITCH_STACK_PR_OFFSET 552 /* 0x228 */ #define IA64_SIGCONTEXT_AR_BSP_OFFSET 72 /* 0x48 */ #define IA64_SIGCONTEXT_AR_RNAT_OFFSET 80 /* 0x50 */ #define IA64_SIGCONTEXT_FLAGS_OFFSET 0 /* 0x0 */ #define IA64_SIGCONTEXT_CFM_OFFSET 48 /* 0x30 */ #define IA64_SIGCONTEXT_FR6_OFFSET 560 /* 0x230 */ -#define IA64_CLONE_VFORK 16384 /* 0x4000 */ +#define IA64_CLONE_VFORK 16384 /* 0x4000 */ #define IA64_CLONE_VM 256 /* 0x100 */ #endif /* _ASM_IA64_OFFSETS_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/page.h linux-2.4.0-test12-lia/include/asm-ia64/page.h --- linux-2.4.0-test12/include/asm-ia64/page.h Mon Oct 9 17:54:59 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/page.h Thu Dec 14 14:44:29 2000 @@ -40,9 +40,6 @@ extern void clear_page (void *page); extern void copy_page (void *to, void *from); -#define clear_user_page(page, vaddr) clear_page(page) -#define copy_user_page(to, from, vaddr) copy_page(to, from) - # ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. @@ -58,7 +55,6 @@ #define pgprot_val(x) ((x).pgprot) #define __pte(x) ((pte_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) # else /* !STRICT_MM_TYPECHECKS */ @@ -93,21 +89,17 @@ */ #define MAP_NR_DENSE(addr) (((unsigned long) (addr) - PAGE_OFFSET) >> PAGE_SHIFT) -/* - * This variant works well for the SGI SN1 architecture (which does have huge - * holes in the memory address space). - */ -#define MAP_NR_SN1(addr) (((unsigned long) (addr) - PAGE_OFFSET) >> PAGE_SHIFT) - #ifdef CONFIG_IA64_GENERIC # include -# define virt_to_page(kaddr) (mem_map + platform_map_nr(kaddr)) -#elif defined (CONFIG_IA64_SN_SN1) -# define virt_to_page(kaddr) (mem_map + MAP_NR_SN1(kaddr)) +# define virt_to_page(kaddr) (mem_map + platform_map_nr(kaddr)) +#elif defined (CONFIG_IA64_SGI_SN1) +# ifndef CONFIG_DISCONTIGMEM +# define virt_to_page(kaddr) (mem_map + MAP_NR_DENSE(kaddr)) +# endif #else -# define virt_to_page(kaddr) (mem_map + MAP_NR_DENSE(kaddr)) +# define virt_to_page(kaddr) (mem_map + MAP_NR_DENSE(kaddr)) #endif -#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) +#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) typedef union ia64_va { struct { diff -urN linux-2.4.0-test12/include/asm-ia64/pci.h linux-2.4.0-test12-lia/include/asm-ia64/pci.h --- linux-2.4.0-test12/include/asm-ia64/pci.h Fri Oct 13 12:05:29 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/pci.h Thu Dec 14 14:44:39 2000 @@ -1,6 +1,7 @@ #ifndef _ASM_IA64_PCI_H #define _ASM_IA64_PCI_H +#include #include #include #include @@ -21,125 +22,42 @@ struct pci_dev; -static inline void pcibios_set_master(struct pci_dev *dev) +static inline void +pcibios_set_master (struct pci_dev *dev) { /* No special bus mastering setup handling */ } -static inline void pcibios_penalize_isa_irq(int irq) +static inline void +pcibios_penalize_isa_irq (int irq) { /* We don't do dynamic PCI IRQ allocation */ } /* - * Dynamic DMA mapping API. + * Dynamic DMA mapping API. See Documentation/DMA-mapping.txt for details. */ +#define pci_alloc_consistent platform_pci_alloc_consistent +#define pci_free_consistent platform_pci_free_consistent +#define pci_map_single platform_pci_map_single +#define pci_unmap_single platform_pci_unmap_single +#define pci_map_sg platform_pci_map_sg +#define pci_unmap_sg platform_pci_unmap_sg +#define pci_dma_sync_single platform_pci_dma_sync_single +#define pci_dma_sync_sg platform_pci_dma_sync_sg +#define sg_dma_address platform_pci_dma_address /* - * Allocate and map kernel buffer using consistent mode DMA for a device. - * hwdev should be valid struct pci_dev pointer for PCI devices, - * NULL for PCI-like buses (ISA, EISA). - * Returns non-NULL cpu-view pointer to the buffer if successful and - * sets *dma_addrp to the pci side dma address as well, else *dma_addrp - * is undefined. - */ -extern void *pci_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle); - -/* - * Free and unmap a consistent DMA buffer. - * cpu_addr is what was returned from pci_alloc_consistent, - * size must be the same as what as passed into pci_alloc_consistent, - * and likewise dma_addr must be the same as what *dma_addrp was set to. - * - * References to the memory and mappings associated with cpu_addr/dma_addr - * past this call are illegal. - */ -extern void pci_free_consistent (struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle); - -/* - * Map a single buffer of the indicated size for DMA in streaming mode. - * The 32-bit bus address to use is returned. - * - * Once the device is given the dma address, the device owns this memory - * until either pci_unmap_single or pci_dma_sync_single is performed. - */ -extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction); - -/* - * Unmap a single streaming mode DMA translation. The dma_addr and size - * must match what was provided for in a previous pci_map_single call. All - * other usages are undefined. - * - * After this call, reads by the cpu to the buffer are guarenteed to see - * whatever the device wrote there. - */ -extern void pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction); - -/* - * Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scather-gather version of the - * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). - * - * NOTE: An implementation may be able to use a smaller number of - * DMA address/length pairs than there are SG table elements. - * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. - * - * Device ownership issues as mentioned above for pci_map_single are - * the same here. - */ -extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction); - -/* - * Unmap a set of streaming mode DMA translations. - * Again, cpu read rules concerning calls here are the same as for - * pci_unmap_single() above. - */ -extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction); - -/* - * Make physical memory consistent for a single - * streaming mode DMA translation after a transfer. - * - * If you perform a pci_map_single() but wish to interrogate the - * buffer using the cpu, yet do not wish to teardown the PCI dma - * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, the - * device again owns the buffer. - */ -extern void pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction); - -/* - * Make physical memory consistent for a set of streaming mode DMA - * translations after a transfer. - * - * The same as pci_dma_sync_single but for a scatter-gather list, - * same rules and usage. - */ -extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction); - -/* Return whether the given PCI device DMA address mask can - * be supported properly. For example, if your device can - * only drive the low 24-bits during PCI bus mastering, then + * Return whether the given PCI device DMA address mask can be supported properly. For + * example, if your device can only drive the low 24-bits during PCI bus mastering, then * you would pass 0x00ffffff as the mask to this function. */ static inline int -pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) +pci_dma_supported (struct pci_dev *hwdev, dma_addr_t mask) { return 1; } -/* These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns, or alternatively stop on the first sg_dma_len(sg) which - * is 0. - */ -#define sg_dma_address(sg) (virt_to_bus((sg)->address)) #define sg_dma_len(sg) ((sg)->length) #endif /* _ASM_IA64_PCI_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/pgalloc.h linux-2.4.0-test12-lia/include/asm-ia64/pgalloc.h --- linux-2.4.0-test12/include/asm-ia64/pgalloc.h Mon Oct 9 17:54:59 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/pgalloc.h Thu Dec 14 14:44:49 2000 @@ -15,6 +15,7 @@ #include +#include #include #include @@ -196,13 +197,6 @@ extern int do_check_pgt_cache (int, int); /* - * This establishes kernel virtual mappings (e.g., as a result of a - * vmalloc call). Since ia-64 uses a separate kernel page table, - * there is nothing to do here... :) - */ -#define set_pgdir(vmaddr, entry) do { } while(0) - -/* * Now for some TLB flushing routines. This is the kind of stuff that * can be very expensive, so try to avoid them whenever possible. */ @@ -267,6 +261,73 @@ printk("flush_tlb_pgtables: can't flush across regions!!\n"); } flush_tlb_range(mm, ia64_thash(start), ia64_thash(end)); +} + +/* + * Now for some cache flushing routines. This is the kind of stuff + * that can be very expensive, so try to avoid them whenever possible. + */ + +/* Caches aren't brain-dead on the IA-64. */ +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_range(mm, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) + +extern void flush_icache_range (unsigned long start, unsigned long end); + +static inline void +flush_dcache_page (struct page *page) +{ + clear_bit(PG_arch_1, &page->flags); +} + +static inline void +clear_user_page (void *addr, unsigned long vaddr, struct page *page) +{ + clear_page(addr); + flush_dcache_page(page); +} + +static inline void +copy_user_page (void *to, void *from, unsigned long vaddr, struct page *page) +{ + copy_page(to, from); + flush_dcache_page(page); +} + +/* + * IA-64 doesn't have any external MMU info: the page tables contain + * all the necessary information. However, we can use this macro + * to pre-install (override) a PTE that we know is needed anyhow. + */ +static inline void +update_mmu_cache (struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + struct page *page; + + if ((vma->vm_flags & PROT_EXEC) == 0) + return; /* not an executable page... */ + + page = pte_page(pte); + address &= PAGE_MASK; + + /* + * Avoid flushing pages that can't possibly contain code. All newly created + * anonymous pages are such pages. However, once the page gets swapped out and + * then read back in, the page may contain code (since the user may have written + * code into that page). Fortunately, page->mapping tells us which case applies: + * it's non-NULL if and only if the page is in the page cache (whether due to + * regular mappings or due to swap-cache pages). + */ + if (!page->mapping) + return; + + if (test_and_set_bit(PG_arch_1, &page->flags)) + return; + + flush_icache_range(address, address + PAGE_SIZE); } #endif /* _ASM_IA64_PGALLOC_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/pgtable.h linux-2.4.0-test12-lia/include/asm-ia64/pgtable.h --- linux-2.4.0-test12/include/asm-ia64/pgtable.h Wed Oct 18 14:25:46 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/pgtable.h Thu Dec 14 14:50:34 2000 @@ -24,6 +24,9 @@ * matches the VHPT short format, the firt doubleword of the VHPD long * format, and the first doubleword of the TLB insertion format. */ +#define _PAGE_A_BIT 5 +#define _PAGE_D_BIT 6 + #define _PAGE_P (1 << 0) /* page present bit */ #define _PAGE_MA_WB (0x0 << 2) /* write back memory attribute */ #define _PAGE_MA_UC (0x4 << 2) /* uncacheable memory attribute */ @@ -46,8 +49,8 @@ #define _PAGE_AR_X_RX (7 << 9) /* exec & promote / read & exec */ #define _PAGE_AR_MASK (7 << 9) #define _PAGE_AR_SHIFT 9 -#define _PAGE_A (1 << 5) /* page accessed bit */ -#define _PAGE_D (1 << 6) /* page dirty bit */ +#define _PAGE_A (1 << _PAGE_A_BIT) /* page accessed bit */ +#define _PAGE_D (1 << _PAGE_D_BIT) /* page dirty bit */ #define _PAGE_PPN_MASK (((__IA64_UL(1) << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL) #define _PAGE_ED (__IA64_UL(1) << 52) /* exception deferral */ #define _PAGE_PROTNONE (__IA64_UL(1) << 63) @@ -79,7 +82,7 @@ #define PGDIR_SIZE (__IA64_UL(1) << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) #define PTRS_PER_PGD (__IA64_UL(1) << (PAGE_SHIFT-3)) -#define USER_PTRS_PER_PGD PTRS_PER_PGD +#define USER_PTRS_PER_PGD (5*PTRS_PER_PGD/8) /* regions 0-4 are user regions */ #define FIRST_USER_PGD_NR 0 /* @@ -98,13 +101,11 @@ */ #define PTRS_PER_PTE (__IA64_UL(1) << (PAGE_SHIFT-3)) -/* Number of pointers that fit on a page: this will go away. */ -#define PTRS_PER_PAGE (__IA64_UL(1) << (PAGE_SHIFT-3)) - # ifndef __ASSEMBLY__ #include #include +#include #include /* @@ -132,19 +133,19 @@ #define __P001 PAGE_READONLY #define __P010 PAGE_READONLY /* write to priv pg -> copy & make writable */ #define __P011 PAGE_READONLY /* ditto */ -#define __P100 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_X_RX) -#define __P101 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX) -#define __P110 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX) -#define __P111 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX) +#define __P100 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX) +#define __P101 PAGE_COPY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY #define __S000 PAGE_NONE #define __S001 PAGE_READONLY #define __S010 PAGE_SHARED /* we don't have (and don't need) write-only */ #define __S011 PAGE_SHARED -#define __S100 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_X_RX) -#define __S101 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX) -#define __S110 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_RWX) -#define __S111 __pgprot(_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_PL_3 | _PAGE_AR_RWX) +#define __S100 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX) +#define __S101 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX) +#define __S110 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX) +#define __S111 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX) #define pgd_ERROR(e) printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) #define pmd_ERROR(e) printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e)) @@ -162,30 +163,8 @@ */ #define page_address(page) ((page)->virtual) -/* - * Now for some cache flushing routines. This is the kind of stuff - * that can be very expensive, so try to avoid them whenever possible. - */ - -/* Caches aren't brain-dead on the ia-64. */ -#define flush_cache_all() do { } while (0) -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_range(mm, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr) do { } while (0) -#define flush_page_to_ram(page) do { } while (0) -#define flush_dcache_page(page) do { } while (0) -#define flush_icache_range(start, end) do { } while (0) - -extern void ia64_flush_icache_page (unsigned long addr); - -#define flush_icache_page(vma,pg) \ -do { \ - if ((vma)->vm_flags & PROT_EXEC) \ - ia64_flush_icache_page((unsigned long) page_address(pg)); \ -} while (0) - /* Quick test to see if ADDR is a (potentially) valid physical address. */ -static __inline__ long +static inline long ia64_phys_addr_valid (unsigned long addr) { return (addr & (my_cpu_data.unimpl_pa_mask)) == 0; @@ -213,13 +192,13 @@ /* * On some architectures, special things need to be done when setting - * the PTE in a page table. Nothing special needs to be on ia-64. + * the PTE in a page table. Nothing special needs to be on IA-64. */ #define set_pte(ptep, pteval) (*(ptep) = (pteval)) -#define VMALLOC_START (0xa000000000000000+2*PAGE_SIZE) +#define VMALLOC_START (0xa000000000000000 + 2*PAGE_SIZE) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END 0xbfffffffffffffff +#define VMALLOC_END (0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 12))) /* * BAD_PAGETABLE is used when we need a bogus page-table, while @@ -281,8 +260,8 @@ */ #define pte_read(pte) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) < 6) #define pte_write(pte) ((unsigned) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) - 2) < 4) -#define pte_dirty(pte) (pte_val(pte) & _PAGE_D) -#define pte_young(pte) (pte_val(pte) & _PAGE_A) +#define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0) +#define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0) /* * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the * 2nd bit in the access rights: @@ -317,7 +296,7 @@ /* * Return the region index for virtual address ADDRESS. */ -static __inline__ unsigned long +static inline unsigned long rgn_index (unsigned long address) { ia64_va a; @@ -329,7 +308,7 @@ /* * Return the region offset for virtual address ADDRESS. */ -static __inline__ unsigned long +static inline unsigned long rgn_offset (unsigned long address) { ia64_va a; @@ -341,7 +320,7 @@ #define RGN_SIZE (1UL << 61) #define RGN_KERNEL 7 -static __inline__ unsigned long +static inline unsigned long pgd_index (unsigned long address) { unsigned long region = address >> 61; @@ -352,7 +331,7 @@ /* The offset in the 1-level directory is given by the 3 region bits (61..63) and the seven level-1 bits (33-39). */ -static __inline__ pgd_t* +static inline pgd_t* pgd_offset (struct mm_struct *mm, unsigned long address) { return mm->pgd + pgd_index(address); @@ -371,56 +350,86 @@ #define pte_offset(dir,addr) \ ((pte_t *) pmd_page(*(dir)) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) +/* atomic versions of the some PTE manipulations: */ -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern void paging_init (void); +static inline int +ptep_test_and_clear_young (pte_t *ptep) +{ +#ifdef CONFIG_SMP + return test_and_clear_bit(_PAGE_A_BIT, ptep); +#else + pte_t pte = *ptep; + if (!pte_young(pte)) + return 0; + set_pte(ptep, pte_mkold(pte)); + return 1; +#endif +} -/* - * IA-64 doesn't have any external MMU info: the page tables contain - * all the necessary information. However, we can use this macro - * to pre-install (override) a PTE that we know is needed anyhow. - * - * Asit says that on Itanium, it is generally faster to let the VHPT - * walker pick up a newly installed PTE (and VHPT misses should be - * extremely rare compared to normal misses). Also, since - * pre-installing the PTE has the problem that we may evict another - * TLB entry needlessly because we don't know for sure whether we need - * to update the iTLB or dTLB, I tend to prefer this solution, too. - * Also, this avoids nasty issues with forward progress (what if the - * newly installed PTE gets replaced before we return to the previous - * execution context?). - * - */ -#if 1 -# define update_mmu_cache(vma,address,pte) +static inline int +ptep_test_and_clear_dirty (pte_t *ptep) +{ +#ifdef CONFIG_SMP + return test_and_clear_bit(_PAGE_D_BIT, ptep); #else -# define update_mmu_cache(vma,address,pte) \ -do { \ - /* \ - * XXX fix me!! \ - * \ - * It's not clear this is a win. We may end up pollute the \ - * dtlb with itlb entries and vice versa (e.g., consider stack \ - * pages that are normally marked executable). It would be \ - * better to insert the TLB entry for the TLB cache that we \ - * know needs the new entry. However, the update_mmu_cache() \ - * arguments don't tell us whether we got here through a data \ - * access or through an instruction fetch. Talk to Linus to \ - * fix this. \ - * \ - * If you re-enable this code, you must disable the ptc code in \ - * Entry 20 of the ivt. \ - */ \ - unsigned long flags; \ - \ - ia64_clear_ic(flags); \ - ia64_itc((vma->vm_flags & PROT_EXEC) ? 0x3 : 0x2, address, pte_val(pte), PAGE_SHIFT); \ - __restore_flags(flags); \ -} while (0) + pte_t pte = *ptep; + if (!pte_dirty(pte)) + return 0; + set_pte(ptep, pte_mkclean(pte)); + return 1; #endif +} + +static inline pte_t +ptep_get_and_clear (pte_t *ptep) +{ +#ifdef CONFIG_SMP + return __pte(xchg((long *) ptep, 0)); +#else + pte_t pte = *ptep; + pte_clear(ptep); + return pte; +#endif +} + +static inline void +ptep_set_wrprotect (pte_t *ptep) +{ +#ifdef CONFIG_SMP + unsigned long new, old; + + do { + old = pte_val(*ptep); + new = pte_val(pte_wrprotect(__pte (old))); + } while (cmpxchg((unsigned long *) ptep, old, new) != old); +#else + pte_t old_pte = *ptep; + set_pte(ptep, pte_wrprotect(old_pte)); +#endif +} + +static inline void +ptep_mkdirty (pte_t *ptep) +{ +#ifdef CONFIG_SMP + set_bit(_PAGE_D_BIT, ptep); +#else + pte_t old_pte = *ptep; + set_pte(ptep, pte_mkdirty(old_pte)); +#endif +} + +static inline int +pte_same (pte_t a, pte_t b) +{ + return pte_val(a) == pte_val(b); +} + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern void paging_init (void); #define SWP_TYPE(entry) (((entry).val >> 1) & 0xff) -#define SWP_OFFSET(entry) ((entry).val >> 9) +#define SWP_OFFSET(entry) (((entry).val << 1) >> 10) #define SWP_ENTRY(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 9) }) #define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define swp_entry_to_pte(x) ((pte_t) { (x).val }) @@ -436,8 +445,6 @@ */ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) - -#include # endif /* !__ASSEMBLY__ */ diff -urN linux-2.4.0-test12/include/asm-ia64/processor.h linux-2.4.0-test12-lia/include/asm-ia64/processor.h --- linux-2.4.0-test12/include/asm-ia64/processor.h Mon Oct 9 17:54:59 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/processor.h Wed Dec 6 23:13:07 2000 @@ -4,7 +4,7 @@ /* * Copyright (C) 1998-2000 Hewlett-Packard Co * Copyright (C) 1998-2000 David Mosberger-Tang - * Copyright (C) 1998, 1999 Stephane Eranian + * Copyright (C) 1998-2000 Stephane Eranian * Copyright (C) 1999 Asit Mallick * Copyright (C) 1999 Don Dugger * @@ -19,7 +19,13 @@ #include #define IA64_NUM_DBG_REGS 8 -#define IA64_NUM_PM_REGS 4 +/* + * Limits for PMC and PMD are set to less than maximum architected values + * but should be sufficient for a while + */ +#define IA64_NUM_PMC_REGS 32 +#define IA64_NUM_PMD_REGS 32 +#define IA64_NUM_PMD_COUNTERS 4 /* * TASK_SIZE really is a mis-named. It really is the maximum user @@ -242,6 +248,9 @@ __u64 usec_per_cyc; /* 2^IA64_USEC_PER_CYC_SHIFT*1000000/itc_freq */ __u64 unimpl_va_mask; /* mask of unimplemented virtual address bits (from PAL) */ __u64 unimpl_pa_mask; /* mask of unimplemented physical address bits (from PAL) */ + __u64 ptce_base; + __u32 ptce_count[2]; + __u32 ptce_stride[2]; #ifdef CONFIG_SMP __u64 loops_per_sec; __u64 ipi_count; @@ -288,10 +297,15 @@ __u64 dbr[IA64_NUM_DBG_REGS]; __u64 ibr[IA64_NUM_DBG_REGS]; #ifdef CONFIG_PERFMON - __u64 pmc[IA64_NUM_PM_REGS]; - __u64 pmd[IA64_NUM_PM_REGS]; - __u64 pmod[IA64_NUM_PM_REGS]; -# define INIT_THREAD_PM {0, }, {0, }, {0, }, + __u64 pmc[IA64_NUM_PMC_REGS]; + __u64 pmd[IA64_NUM_PMD_REGS]; + struct { + __u64 val; /* virtual 64bit counter */ + __u64 rval; /* reset value on overflow */ + int sig; /* signal used to notify */ + int pid; /* process to notify */ + } pmu_counters[IA64_NUM_PMD_COUNTERS]; +# define INIT_THREAD_PM {0, }, {0, }, {{ 0, 0, 0, 0}, }, #else # define INIT_THREAD_PM #endif @@ -423,8 +437,8 @@ #endif #ifdef CONFIG_PERFMON -extern void ia64_save_pm_regs (struct thread_struct *thread); -extern void ia64_load_pm_regs (struct thread_struct *thread); +extern void ia64_save_pm_regs (struct task_struct *task); +extern void ia64_load_pm_regs (struct task_struct *task); #endif #define ia64_fph_enable() __asm__ __volatile__ (";; rsm psr.dfh;; srlz.d;;" ::: "memory"); diff -urN linux-2.4.0-test12/include/asm-ia64/ptrace.h linux-2.4.0-test12-lia/include/asm-ia64/ptrace.h --- linux-2.4.0-test12/include/asm-ia64/ptrace.h Mon Oct 9 17:55:00 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/ptrace.h Wed Dec 6 23:13:06 2000 @@ -2,8 +2,8 @@ #define _ASM_IA64_PTRACE_H /* - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998-2000 Hewlett-Packard Co + * Copyright (C) 1998-2000 David Mosberger-Tang * Copyright (C) 1998, 1999 Stephane Eranian * * 12/07/98 S. Eranian added pt_regs & switch_stack @@ -74,6 +74,9 @@ #ifndef __ASSEMBLY__ +#include +#include + /* * This struct defines the way the registers are saved on system * calls. @@ -236,7 +239,14 @@ extern void ia64_increment_ip (struct pt_regs *pt); extern void ia64_decrement_ip (struct pt_regs *pt); -#endif + +static inline void +force_successful_syscall_return (void) +{ + ia64_task_regs(current)->r8 = 0; +} + +#endif /* !__KERNEL__ */ #endif /* !__ASSEMBLY__ */ diff -urN linux-2.4.0-test12/include/asm-ia64/sal.h linux-2.4.0-test12-lia/include/asm-ia64/sal.h --- linux-2.4.0-test12/include/asm-ia64/sal.h Mon Oct 9 17:55:00 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/sal.h Thu Dec 14 14:50:49 2000 @@ -24,7 +24,9 @@ extern spinlock_t sal_lock; -#define __SAL_CALL(result,args...) result = (*ia64_sal)(args) +/* SAL spec _requires_ eight args for each call. */ +#define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7) \ + result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7) #ifdef CONFIG_SMP # define SAL_CALL(result,args...) do { \ @@ -60,10 +62,10 @@ * informational value should be printed (e.g., "reboot for * change to take effect"). */ - s64 status; - u64 v0; - u64 v1; - u64 v2; + s64 status; + u64 v0; + u64 v1; + u64 v2; }; typedef struct ia64_sal_retval (*ia64_sal_handler) (u64, ...); @@ -78,24 +80,27 @@ * The SAL system table is followed by a variable number of variable * length descriptors. The structure of these descriptors follows * below. + * The defininition follows SAL specs from July 2000 */ struct ia64_sal_systab { - char signature[4]; /* should be "SST_" */ - int size; /* size of this table in bytes */ - unsigned char sal_rev_minor; - unsigned char sal_rev_major; - unsigned short entry_count; /* # of entries in variable portion */ - unsigned char checksum; - char ia32_bios_present; - unsigned short reserved1; - char oem_id[32]; /* ASCII NUL terminated OEM id - (terminating NUL is missing if - string is exactly 32 bytes long). */ - char product_id[32]; /* ASCII product id */ - char reserved2[16]; + u8 signature[4]; /* should be "SST_" */ + u32 size; /* size of this table in bytes */ + u8 sal_rev_minor; + u8 sal_rev_major; + u16 entry_count; /* # of entries in variable portion */ + u8 checksum; + u8 reserved1[7]; + u8 sal_a_rev_minor; + u8 sal_a_rev_major; + u8 sal_b_rev_minor; + u8 sal_b_rev_major; + /* oem_id & product_id: terminating NUL is missing if string is exactly 32 bytes long. */ + u8 oem_id[32]; + u8 product_id[32]; /* ASCII product id */ + u8 reserved2[8]; }; -enum SAL_Systab_Entry_Type { +enum sal_systab_entry_type { SAL_DESC_ENTRY_POINT = 0, SAL_DESC_MEMORY = 1, SAL_DESC_PLATFORM_FEATURE = 2, @@ -115,75 +120,78 @@ */ #define SAL_DESC_SIZE(type) "\060\040\020\040\020\020"[(unsigned) type] -struct ia64_sal_desc_entry_point { - char type; - char reserved1[7]; - s64 pal_proc; - s64 sal_proc; - s64 gp; - char reserved2[16]; -}; - -struct ia64_sal_desc_memory { - char type; - char used_by_sal; /* needs to be mapped for SAL? */ - char mem_attr; /* current memory attribute setting */ - char access_rights; /* access rights set up by SAL */ - char mem_attr_mask; /* mask of supported memory attributes */ - char reserved1; - char mem_type; /* memory type */ - char mem_usage; /* memory usage */ - s64 addr; /* physical address of memory */ - unsigned int length; /* length (multiple of 4KB pages) */ - unsigned int reserved2; - char oem_reserved[8]; -}; +typedef struct ia64_sal_desc_entry_point { + u8 type; + u8 reserved1[7]; + u64 pal_proc; + u64 sal_proc; + u64 gp; + u8 reserved2[16]; +}ia64_sal_desc_entry_point_t; + +typedef struct ia64_sal_desc_memory { + u8 type; + u8 used_by_sal; /* needs to be mapped for SAL? */ + u8 mem_attr; /* current memory attribute setting */ + u8 access_rights; /* access rights set up by SAL */ + u8 mem_attr_mask; /* mask of supported memory attributes */ + u8 reserved1; + u8 mem_type; /* memory type */ + u8 mem_usage; /* memory usage */ + u64 addr; /* physical address of memory */ + u32 length; /* length (multiple of 4KB pages) */ + u32 reserved2; + u8 oem_reserved[8]; +} ia64_sal_desc_memory_t; #define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK (1 << 0) #define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT (1 << 1) #define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT (1 << 2) -struct ia64_sal_desc_platform_feature { - char type; - unsigned char feature_mask; - char reserved1[14]; -}; - -struct ia64_sal_desc_tr { - char type; - char tr_type; /* 0 == instruction, 1 == data */ - char regnum; /* translation register number */ - char reserved1[5]; - s64 addr; /* virtual address of area covered */ - s64 page_size; /* encoded page size */ - char reserved2[8]; -}; +typedef struct ia64_sal_desc_platform_feature { + u8 type; + u8 feature_mask; + u8 reserved1[14]; +} ia64_sal_desc_platform_feature_t; + +typedef struct ia64_sal_desc_tr { + u8 type; + u8 tr_type; /* 0 == instruction, 1 == data */ + u8 regnum; /* translation register number */ + u8 reserved1[5]; + u64 addr; /* virtual address of area covered */ + u64 page_size; /* encoded page size */ + u8 reserved2[8]; +} ia64_sal_desc_tr_t; typedef struct ia64_sal_desc_ptc { - char type; - char reserved1[3]; - unsigned int num_domains; /* # of coherence domains */ - s64 domain_info; /* physical address of domain info table */ + u8 type; + u8 reserved1[3]; + u32 num_domains; /* # of coherence domains */ + u64 domain_info; /* physical address of domain info table */ } ia64_sal_desc_ptc_t; typedef struct ia64_sal_ptc_domain_info { - unsigned long proc_count; /* number of processors in domain */ - long proc_list; /* physical address of LID array */ + u64 proc_count; /* number of processors in domain */ + u64 proc_list; /* physical address of LID array */ } ia64_sal_ptc_domain_info_t; typedef struct ia64_sal_ptc_domain_proc_entry { - unsigned char id; /* id of processor */ - unsigned char eid; /* eid of processor */ + u64 reserved : 16; + u64 eid : 8; /* eid of processor */ + u64 id : 8; /* id of processor */ + u64 ignored : 32; } ia64_sal_ptc_domain_proc_entry_t; + #define IA64_SAL_AP_EXTERNAL_INT 0 -struct ia64_sal_desc_ap_wakeup { - char type; - char mechanism; /* 0 == external interrupt */ - char reserved1[6]; - long vector; /* interrupt vector in range 0x10-0xff */ -}; +typedef struct ia64_sal_desc_ap_wakeup { + u8 type; + u8 mechanism; /* 0 == external interrupt */ + u8 reserved1[6]; + u64 vector; /* interrupt vector in range 0x10-0xff */ +} ia64_sal_desc_ap_wakeup_t ; extern ia64_sal_handler ia64_sal; extern struct ia64_sal_desc_ptc *ia64_ptc_domain_info; @@ -218,24 +226,24 @@ /* Encodings for vectors which can be registered by the OS with SAL */ enum { - SAL_VECTOR_OS_MCA = 0, - SAL_VECTOR_OS_INIT = 1, - SAL_VECTOR_OS_BOOT_RENDEZ = 2 + SAL_VECTOR_OS_MCA = 0, + SAL_VECTOR_OS_INIT = 1, + SAL_VECTOR_OS_BOOT_RENDEZ = 2 }; /* Definition of the SAL Error Log from the SAL spec */ /* Definition of timestamp according to SAL spec for logging purposes */ -typedef struct sal_log_timestamp_s { - u8 slh_century; /* Century (19, 20, 21, ...) */ - u8 slh_year; /* Year (00..99) */ - u8 slh_month; /* Month (1..12) */ - u8 slh_day; /* Day (1..31) */ - u8 slh_reserved; - u8 slh_hour; /* Hour (0..23) */ - u8 slh_minute; /* Minute (0..59) */ - u8 slh_second; /* Second (0..59) */ +typedef struct sal_log_timestamp { + u8 slh_century; /* Century (19, 20, 21, ...) */ + u8 slh_year; /* Year (00..99) */ + u8 slh_month; /* Month (1..12) */ + u8 slh_day; /* Day (1..31) */ + u8 slh_reserved; + u8 slh_hour; /* Hour (0..23) */ + u8 slh_minute; /* Minute (0..59) */ + u8 slh_second; /* Second (0..59) */ } sal_log_timestamp_t; @@ -243,126 +251,126 @@ #define MAX_TLB_ERRORS 6 #define MAX_BUS_ERRORS 1 -typedef struct sal_log_processor_info_s { +typedef struct sal_log_processor_info { struct { - u64 slpi_psi : 1, - slpi_cache_check: MAX_CACHE_ERRORS, - slpi_tlb_check : MAX_TLB_ERRORS, - slpi_bus_check : MAX_BUS_ERRORS, - slpi_reserved2 : (31 - (MAX_TLB_ERRORS + MAX_CACHE_ERRORS - + MAX_BUS_ERRORS)), - slpi_minstate : 1, - slpi_bank1_gr : 1, - slpi_br : 1, - slpi_cr : 1, - slpi_ar : 1, - slpi_rr : 1, - slpi_fr : 1, - slpi_reserved1 : 25; + u64 slpi_psi : 1, + slpi_cache_check: MAX_CACHE_ERRORS, + slpi_tlb_check : MAX_TLB_ERRORS, + slpi_bus_check : MAX_BUS_ERRORS, + slpi_reserved2 : (31 - (MAX_TLB_ERRORS + MAX_CACHE_ERRORS + + MAX_BUS_ERRORS)), + slpi_minstate : 1, + slpi_bank1_gr : 1, + slpi_br : 1, + slpi_cr : 1, + slpi_ar : 1, + slpi_rr : 1, + slpi_fr : 1, + slpi_reserved1 : 25; } slpi_valid; - pal_processor_state_info_t slpi_processor_state_info; + pal_processor_state_info_t slpi_processor_state_info; struct { - pal_cache_check_info_t slpi_cache_check; - u64 slpi_target_address; + pal_cache_check_info_t slpi_cache_check; + u64 slpi_target_address; } slpi_cache_check_info[MAX_CACHE_ERRORS]; - pal_tlb_check_info_t slpi_tlb_check_info[MAX_TLB_ERRORS]; + pal_tlb_check_info_t slpi_tlb_check_info[MAX_TLB_ERRORS]; struct { - pal_bus_check_info_t slpi_bus_check; - u64 slpi_requestor_addr; - u64 slpi_responder_addr; - u64 slpi_target_addr; + pal_bus_check_info_t slpi_bus_check; + u64 slpi_requestor_addr; + u64 slpi_responder_addr; + u64 slpi_target_addr; } slpi_bus_check_info[MAX_BUS_ERRORS]; - pal_min_state_area_t slpi_min_state_area; - u64 slpi_br[8]; - u64 slpi_cr[128]; - u64 slpi_ar[128]; - u64 slpi_rr[8]; - u64 slpi_fr[128]; + pal_min_state_area_t slpi_min_state_area; + u64 slpi_br[8]; + u64 slpi_cr[128]; + u64 slpi_ar[128]; + u64 slpi_rr[8]; + u64 slpi_fr[128]; } sal_log_processor_info_t; /* platform error log structures */ typedef struct platerr_logheader { - u64 nextlog; /* next log offset if present */ - u64 loglength; /* log length */ - u64 logsubtype; /* log subtype memory/bus/component */ - u64 eseverity; /* error severity */ + u64 nextlog; /* next log offset if present */ + u64 loglength; /* log length */ + u64 logsubtype; /* log subtype memory/bus/component */ + u64 eseverity; /* error severity */ } ehdr_t; typedef struct sysmem_errlog { - ehdr_t lhdr; /* header */ - u64 vflag; /* valid bits for each field in the log */ - u64 addr; /* memory address */ - u64 data; /* memory data */ - u64 cmd; /* command bus value if any */ - u64 ctrl; /* control bus value if any */ - u64 addrsyndrome; /* memory address ecc/parity syndrome bits */ - u64 datasyndrome; /* data ecc/parity syndrome */ - u64 cacheinfo; /* platform cache info as defined in pal spec. table 7-34 */ + ehdr_t lhdr; /* header */ + u64 vflag; /* valid bits for each field in the log */ + u64 addr; /* memory address */ + u64 data; /* memory data */ + u64 cmd; /* command bus value if any */ + u64 ctrl; /* control bus value if any */ + u64 addrsyndrome; /* memory address ecc/parity syndrome bits */ + u64 datasyndrome; /* data ecc/parity syndrome */ + u64 cacheinfo; /* platform cache info as defined in pal spec. table 7-34 */ } merrlog_t; typedef struct sysbus_errlog { - ehdr_t lhdr; /* linkded list header */ - u64 vflag; /* valid bits for each field in the log */ - u64 busnum; /* bus number in error */ - u64 reqaddr; /* requestor address */ - u64 resaddr; /* responder address */ - u64 taraddr; /* target address */ - u64 data; /* requester r/w data */ - u64 cmd; /* bus commands */ - u64 ctrl; /* bus controls (be# &-0) */ - u64 addrsyndrome; /* addr bus ecc/parity bits */ - u64 datasyndrome; /* data bus ecc/parity bits */ - u64 cmdsyndrome; /* command bus ecc/parity bits */ - u64 ctrlsyndrome; /* control bus ecc/parity bits */ + ehdr_t lhdr; /* linkded list header */ + u64 vflag; /* valid bits for each field in the log */ + u64 busnum; /* bus number in error */ + u64 reqaddr; /* requestor address */ + u64 resaddr; /* responder address */ + u64 taraddr; /* target address */ + u64 data; /* requester r/w data */ + u64 cmd; /* bus commands */ + u64 ctrl; /* bus controls (be# &-0) */ + u64 addrsyndrome; /* addr bus ecc/parity bits */ + u64 datasyndrome; /* data bus ecc/parity bits */ + u64 cmdsyndrome; /* command bus ecc/parity bits */ + u64 ctrlsyndrome; /* control bus ecc/parity bits */ } berrlog_t; /* platform error log structures */ typedef struct syserr_chdr { /* one header per component */ - u64 busnum; /* bus number on which the component resides */ - u64 devnum; /* same as device select */ - u64 funcid; /* function id of the device */ - u64 devid; /* pci device id */ - u64 classcode; /* pci class code for the device */ - u64 cmdreg; /* pci command reg value */ - u64 statreg; /* pci status reg value */ + u64 busnum; /* bus number on which the component resides */ + u64 devnum; /* same as device select */ + u64 funcid; /* function id of the device */ + u64 devid; /* pci device id */ + u64 classcode; /* pci class code for the device */ + u64 cmdreg; /* pci command reg value */ + u64 statreg; /* pci status reg value */ } chdr_t; typedef struct cfginfo { - u64 cfgaddr; - u64 cfgval; + u64 cfgaddr; + u64 cfgval; } cfginfo_t; typedef struct sys_comperr { /* per component */ - ehdr_t lhdr; /* linked list header */ - u64 vflag; /* valid bits for each field in the log */ - chdr_t scomphdr; - u64 numregpair; /* number of reg addr/value pairs */ + ehdr_t lhdr; /* linked list header */ + u64 vflag; /* valid bits for each field in the log */ + chdr_t scomphdr; + u64 numregpair; /* number of reg addr/value pairs */ cfginfo_t cfginfo; } cerrlog_t; typedef struct sel_records { - ehdr_t lhdr; - u64 seldata; + ehdr_t lhdr; + u64 seldata; } isel_t; typedef struct plat_errlog { - u64 mbcsvalid; /* valid bits for each type of log */ - merrlog_t smemerrlog; /* platform memory error logs */ - berrlog_t sbuserrlog; /* platform bus error logs */ - cerrlog_t scomperrlog; /* platform chipset error logs */ - isel_t selrecord; /* ipmi sel record */ + u64 mbcsvalid; /* valid bits for each type of log */ + merrlog_t smemerrlog; /* platform memory error logs */ + berrlog_t sbuserrlog; /* platform bus error logs */ + cerrlog_t scomperrlog; /* platform chipset error logs */ + isel_t selrecord; /* ipmi sel record */ } platforminfo_t; /* over all log structure (processor+platform) */ typedef union udev_specific_log { - sal_log_processor_info_t proclog; - platforminfo_t platlog; + sal_log_processor_info_t proclog; + platforminfo_t platlog; } devicelog_t; @@ -378,21 +386,18 @@ #define sal_log_processor_info_rr_valid slpi_valid.slpi_rr #define sal_log_processor_info_fr_valid slpi_valid.slpi_fr -typedef struct sal_log_header_s { - u64 slh_next_log; /* Offset of the next log from the - * beginning of this structure. - */ - uint slh_log_len; /* Length of this error log in bytes */ - ushort slh_log_type; /* Type of log (0 - cpu ,1 - platform) */ - ushort slh_log_sub_type; /* SGI specific sub type */ - sal_log_timestamp_t slh_log_timestamp; /* Timestamp */ +typedef struct sal_log_header { + u64 slh_next_log; /* Offset of the next log from the beginning of this structure */ + u32 slh_log_len; /* Length of this error log in bytes */ + u16 slh_log_type; /* Type of log (0 - cpu ,1 - platform) */ + u16 slh_log_sub_type; /* SGI specific sub type */ + sal_log_timestamp_t slh_log_timestamp; /* Timestamp */ } sal_log_header_t; /* SAL PSI log structure */ -typedef struct psilog -{ - sal_log_header_t sal_elog_header; - devicelog_t devlog; +typedef struct psilog { + sal_log_header_t sal_elog_header; + devicelog_t devlog; } ia64_psilog_t; /* @@ -405,7 +410,7 @@ { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_FREQ_BASE, which); + SAL_CALL(isrv, SAL_FREQ_BASE, which, 0, 0, 0, 0, 0, 0); *ticks_per_second = isrv.v0; *drift_info = isrv.v1; return isrv.status; @@ -416,7 +421,7 @@ ia64_sal_cache_flush (u64 cache_type) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type); + SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); return isrv.status; } @@ -427,7 +432,7 @@ ia64_sal_cache_init (void) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_CACHE_INIT); + SAL_CALL(isrv, SAL_CACHE_INIT, 0, 0, 0, 0, 0, 0, 0); return isrv.status; } @@ -438,7 +443,8 @@ ia64_sal_clear_state_info (u64 sal_info_type, u64 sal_info_sub_type) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, sal_info_sub_type); + SAL_CALL(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, sal_info_sub_type, + 0, 0, 0, 0, 0); return isrv.status; } @@ -450,7 +456,8 @@ ia64_sal_get_state_info (u64 sal_info_type, u64 sal_info_sub_type, u64 *sal_info) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_GET_STATE_INFO, sal_info_type, sal_info_sub_type, sal_info); + SAL_CALL(isrv, SAL_GET_STATE_INFO, sal_info_type, sal_info_sub_type, + sal_info, 0, 0, 0, 0); if (isrv.status) return 0; return isrv.v0; @@ -462,7 +469,8 @@ ia64_sal_get_state_info_size (u64 sal_info_type, u64 sal_info_sub_type) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, sal_info_sub_type); + SAL_CALL(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, sal_info_sub_type, + 0, 0, 0, 0, 0); if (isrv.status) return 0; return isrv.v0; @@ -475,7 +483,7 @@ ia64_sal_mc_rendez (void) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_MC_RENDEZ); + SAL_CALL(isrv, SAL_MC_RENDEZ, 0, 0, 0, 0, 0, 0, 0); return isrv.status; } @@ -487,7 +495,8 @@ ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val, timeout); + SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val, timeout, + 0, 0, 0); return isrv.status; } @@ -496,19 +505,7 @@ ia64_sal_pci_config_read (u64 pci_config_addr, u64 size, u64 *value) { struct ia64_sal_retval isrv; -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - extern spinlock_t ivr_read_lock; - unsigned long flags; - - /* - * Avoid PCI configuration read/write overwrite -- A0 Interrupt loss workaround - */ - spin_lock_irqsave(&ivr_read_lock, flags); -#endif - SAL_CALL(isrv, SAL_PCI_CONFIG_READ, pci_config_addr, size); -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - spin_unlock_irqrestore(&ivr_read_lock, flags); -#endif + SAL_CALL(isrv, SAL_PCI_CONFIG_READ, pci_config_addr, size, 0, 0, 0, 0, 0); if (value) *value = isrv.v0; return isrv.status; @@ -519,19 +516,8 @@ ia64_sal_pci_config_write (u64 pci_config_addr, u64 size, u64 value) { struct ia64_sal_retval isrv; -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - extern spinlock_t ivr_read_lock; - unsigned long flags; - - /* - * Avoid PCI configuration read/write overwrite -- A0 Interrupt loss workaround - */ - spin_lock_irqsave(&ivr_read_lock, flags); -#endif - SAL_CALL(isrv, SAL_PCI_CONFIG_WRITE, pci_config_addr, size, value); -#ifdef CONFIG_ITANIUM_A1_SPECIFIC - spin_unlock_irqrestore(&ivr_read_lock, flags); -#endif + SAL_CALL(isrv, SAL_PCI_CONFIG_WRITE, pci_config_addr, size, value, + 0, 0, 0, 0); return isrv.status; } @@ -543,7 +529,8 @@ ia64_sal_register_physical_addr (u64 phys_entry, u64 phys_addr) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_REGISTER_PHYSICAL_ADDR, phys_entry, phys_addr); + SAL_CALL(isrv, SAL_REGISTER_PHYSICAL_ADDR, phys_entry, phys_addr, + 0, 0, 0, 0, 0); return isrv.status; } @@ -569,7 +556,8 @@ u64 *error_code, u64 *scratch_buf_size_needed) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SAL_UPDATE_PAL, param_buf, scratch_buf, scratch_buf_size); + SAL_CALL(isrv, SAL_UPDATE_PAL, param_buf, scratch_buf, scratch_buf_size, + 0, 0, 0, 0); if (error_code) *error_code = isrv.v0; if (scratch_buf_size_needed) diff -urN linux-2.4.0-test12/include/asm-ia64/sn/addrs.h linux-2.4.0-test12-lia/include/asm-ia64/sn/addrs.h --- linux-2.4.0-test12/include/asm-ia64/sn/addrs.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/addrs.h Wed Dec 13 23:52:11 2000 @@ -0,0 +1,545 @@ +/* $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, 1999 Silicon Graphics, Inc. + * Copyright (C) 1999 by Ralf Baechle + */ +#ifndef _ASM_SN_ADDRS_H +#define _ASM_SN_ADDRS_H + +#if _LANGUAGE_C +#include +#endif /* _LANGUAGE_C */ + +#if !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC) +#include +#include +#include +#endif /* CONFIG_IA64_SGI_SN1 */ + +#if defined(CONFIG_IA64_SGI_IO) +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif +#endif /* CONFIG_IA64_SGI_IO */ + + +#if _LANGUAGE_C + +#if defined(CONFIG_IA64_SGI_IO) /* FIXME */ +#define PS_UINT_CAST (__psunsigned_t) +#define UINT64_CAST (uint64_t) +#else /* CONFIG_IA64_SGI_IO */ +#define PS_UINT_CAST (unsigned long) +#define UINT64_CAST (unsigned long) +#endif /* CONFIG_IA64_SGI_IO */ + +#define HUBREG_CAST (volatile hubreg_t *) + +#elif _LANGUAGE_ASSEMBLY + +#define PS_UINT_CAST +#define UINT64_CAST +#define HUBREG_CAST + +#endif + + +#define NASID_GET_META(_n) ((_n) >> NASID_LOCAL_BITS) +#if defined CONFIG_SGI_IP35 || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define NASID_GET_LOCAL(_n) ((_n) & 0x7f) +#endif +#define NASID_MAKE(_m, _l) (((_m) << NASID_LOCAL_BITS) | (_l)) + +#define NODE_ADDRSPACE_MASK (NODE_ADDRSPACE_SIZE - 1) +#define TO_NODE_ADDRSPACE(_pa) (UINT64_CAST (_pa) & NODE_ADDRSPACE_MASK) + +#define CHANGE_ADDR_NASID(_pa, _nasid) \ + ((UINT64_CAST (_pa) & ~NASID_MASK) | \ + (UINT64_CAST(_nasid) << NASID_SHFT)) + + +/* + * The following macros are used to index to the beginning of a specific + * node's address space. + */ + +#define NODE_OFFSET(_n) (UINT64_CAST (_n) << NODE_SIZE_BITS) + +#define NODE_CAC_BASE(_n) (CAC_BASE + NODE_OFFSET(_n)) +#define NODE_HSPEC_BASE(_n) (HSPEC_BASE + NODE_OFFSET(_n)) +#define NODE_IO_BASE(_n) (IO_BASE + NODE_OFFSET(_n)) +#define NODE_MSPEC_BASE(_n) (MSPEC_BASE + NODE_OFFSET(_n)) +#define NODE_UNCAC_BASE(_n) (UNCAC_BASE + NODE_OFFSET(_n)) + +#define TO_NODE(_n, _x) (NODE_OFFSET(_n) | ((_x) )) +#define TO_NODE_CAC(_n, _x) (NODE_CAC_BASE(_n) | ((_x) & TO_PHYS_MASK)) +#define TO_NODE_UNCAC(_n, _x) (NODE_UNCAC_BASE(_n) | ((_x) & TO_PHYS_MASK)) +#define TO_NODE_MSPEC(_n, _x) (NODE_MSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK)) +#define TO_NODE_HSPEC(_n, _x) (NODE_HSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK)) + + +#define RAW_NODE_SWIN_BASE(nasid, widget) \ + (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS)) + +#define WIDGETID_GET(addr) ((unsigned char)((addr >> SWIN_SIZE_BITS) & 0xff)) + +/* + * The following definitions pertain to the IO special address + * space. They define the location of the big and little windows + * of any given node. + */ + +#define SWIN_SIZE_BITS 24 +#define SWIN_SIZE (UINT64_CAST 1 << 24) +#define SWIN_SIZEMASK (SWIN_SIZE - 1) +#define SWIN_WIDGET_MASK 0xF + +/* + * Convert smallwindow address to xtalk address. + * + * 'addr' can be physical or virtual address, but will be converted + * to Xtalk address in the range 0 -> SWINZ_SIZEMASK + */ +#define SWIN_WIDGETADDR(addr) ((addr) & SWIN_SIZEMASK) +#define SWIN_WIDGETNUM(addr) (((addr) >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK) +/* + * Verify if addr belongs to small window address on node with "nasid" + * + * + * NOTE: "addr" is expected to be XKPHYS address, and NOT physical + * address + * + * + */ +#define NODE_SWIN_ADDR(nasid, addr) \ + (((addr) >= NODE_SWIN_BASE(nasid, 0)) && \ + ((addr) < (NODE_SWIN_BASE(nasid, HUB_NUM_WIDGET) + SWIN_SIZE)\ + )) + +/* + * The following define the major position-independent aliases used + * in SN. + * UALIAS -- 256MB in size, reads in the UALIAS result in + * uncached references to the memory of the reader's node. + * CPU_UALIAS -- 128kb in size, the bottom part of UALIAS is flipped + * depending on which CPU does the access to provide + * all CPUs with unique uncached memory at low addresses. + * LBOOT -- 256MB in size, reads in the LBOOT area result in + * uncached references to the local hub's boot prom and + * other directory-bus connected devices. + * IALIAS -- 8MB in size, reads in the IALIAS result in uncached + * references to the local hub's registers. + */ + +#define UALIAS_BASE HSPEC_BASE +#define UALIAS_SIZE 0x10000000 /* 256 Megabytes */ +#define UALIAS_LIMIT (UALIAS_BASE + UALIAS_SIZE) + +/* + * The bottom of ualias space is flipped depending on whether you're + * processor 0 or 1 within a node. + */ +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define LREG_BASE (HSPEC_BASE + 0x10000000) +#define LREG_SIZE 0x8000000 /* 128 MB */ +#define LREG_LIMIT (LREG_BASE + LREG_SIZE) +#define LBOOT_BASE (LREG_LIMIT) +#define LBOOT_SIZE 0x8000000 /* 128 MB */ +#define LBOOT_LIMIT (LBOOT_BASE + LBOOT_SIZE) +#define LBOOT_STRIDE 0x2000000 /* two PROMs, on 32M boundaries */ +#endif + +#define HUB_REGISTER_WIDGET 1 +#define IALIAS_BASE NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET) +#define IALIAS_SIZE 0x800000 /* 8 Megabytes */ +#define IS_IALIAS(_a) (((_a) >= IALIAS_BASE) && \ + ((_a) < (IALIAS_BASE + IALIAS_SIZE))) + +/* + * Macro for referring to Hub's RBOOT space + */ + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + +#define NODE_LREG_BASE(_n) (NODE_HSPEC_BASE(_n) + 0x30000000) +#define NODE_LREG_LIMIT(_n) (NODE_LREG_BASE(_n) + LREG_SIZE) +#define RREG_BASE(_n) (NODE_LREG_BASE(_n)) +#define RREG_LIMIT(_n) (NODE_LREG_LIMIT(_n)) +#define RBOOT_SIZE 0x8000000 /* 128 Megabytes */ +#define NODE_RBOOT_BASE(_n) (NODE_HSPEC_BASE(_n) + 0x38000000) +#define NODE_RBOOT_LIMIT(_n) (NODE_RBOOT_BASE(_n) + RBOOT_SIZE) + +#endif + +/* + * Macros for referring the Hub's back door space + * + * These macros correctly process addresses in any node's space. + * WARNING: They won't work in assembler. + * + * BDDIR_ENTRY_LO returns the address of the low double-word of the dir + * entry corresponding to a physical (Cac or Uncac) address. + * BDDIR_ENTRY_HI returns the address of the high double-word of the entry. + * BDPRT_ENTRY returns the address of the double-word protection entry + * corresponding to the page containing the physical address. + * BDPRT_ENTRY_S Stores the value into the protection entry. + * BDPRT_ENTRY_L Load the value from the protection entry. + * BDECC_ENTRY returns the address of the ECC byte corresponding to a + * double-word at a specified physical address. + * BDECC_ENTRY_H returns the address of the two ECC bytes corresponding to a + * quad-word at a specified physical address. + */ +#define NODE_BDOOR_BASE(_n) (NODE_HSPEC_BASE(_n) + (NODE_ADDRSPACE_SIZE/2)) + +#define NODE_BDECC_BASE(_n) (NODE_BDOOR_BASE(_n)) +#define NODE_BDDIR_BASE(_n) (NODE_BDOOR_BASE(_n) + (NODE_ADDRSPACE_SIZE/4)) +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +/* + * Bedrock's directory entries are a single word: no low/high + */ + +#define BDDIR_ENTRY(_pa) (HSPEC_BASE + \ + NODE_ADDRSPACE_SIZE * 7 / 8 | \ + UINT64_CAST (_pa) & NASID_MASK | \ + UINT64_CAST (_pa) >> 3 & BDDIR_UPPER_MASK) + +#ifdef BRINGUP + /* minimize source changes by mapping *_LO() & *_HI() */ +#define BDDIR_ENTRY_LO(_pa) BDDIR_ENTRY(_pa) +#define BDDIR_ENTRY_HI(_pa) BDDIR_ENTRY(_pa) +#endif /* BRINGUP */ + +#define BDDIR_PAGE_MASK (BDDIR_UPPER_MASK & 0x7ffff << 11) +#define BDDIR_PAGE_BASE_MASK (UINT64_CAST 0xfffffffffffff800) + +#ifdef _LANGUAGE_C + +#define BDPRT_ENTRY_ADDR(_pa, _rgn) ((uint64_t *) ( (HSPEC_BASE + \ + NODE_ADDRSPACE_SIZE * 7 / 8 + 0x408) | \ + (UINT64_CAST (_pa) & NASID_MASK) | \ + (UINT64_CAST (_pa) >> 3 & BDDIR_PAGE_MASK) | \ + (UINT64_CAST (_pa) >> 3 & 0x3 << 4) | \ + ((_rgn) & 0x1e) << 5)) + +static __inline uint64_t BDPRT_ENTRY_L(paddr_t pa,uint32_t rgn) { + uint64_t word=*BDPRT_ENTRY_ADDR(pa,rgn); + + if(rgn&0x20) /*If the region is > 32, move it down*/ + word = word >> 32; + if(rgn&0x1) /*If the region is odd, get that part */ + word = word >> 16; + word = word & 0xffff; /*Get the 16 bits we are interested in*/ + + return word; +} + +static __inline void BDPRT_ENTRY_S(paddr_t pa,uint32_t rgn,uint64_t val) { + uint64_t *addr=(uint64_t *)BDPRT_ENTRY_ADDR(pa,rgn); + uint64_t word,mask; + + word=*addr; + mask=0; + if(rgn&0x1) { + mask|=0x0000ffff0000ffff; + val=val<<16; + } + else + mask|=0xffff0000ffff0000; + if(rgn&0x20) { + mask|=0x00000000ffffffff; + val=val<<32; + } + else + mask|=0xffffffff00000000; + word &= mask; + word |= val; + + *(addr++)=word; + addr++; + *(addr++)=word; + addr++; + *(addr++)=word; + addr++; + *addr=word; +} +#endif /*_LANGUAGE_C*/ + +#define BDCNT_ENTRY(_pa) (HSPEC_BASE + \ + NODE_ADDRSPACE_SIZE * 7 / 8 + 0x8 | \ + UINT64_CAST (_pa) & NASID_MASK | \ + UINT64_CAST (_pa) >> 3 & BDDIR_PAGE_MASK | \ + UINT64_CAST (_pa) >> 3 & 0x3 << 4) + + +#ifdef BRINGUP + /* little endian packing of ecc bytes requires a swizzle */ + /* this is problemmatic for memory_init_ecc */ +#endif /* BRINGUP */ +#define BDECC_ENTRY(_pa) (HSPEC_BASE + \ + NODE_ADDRSPACE_SIZE * 5 / 8 | \ + UINT64_CAST (_pa) & NASID_MASK | \ + UINT64_CAST (_pa) >> 3 & BDECC_UPPER_MASK \ + ^ 0x7ULL) + +#define BDECC_SCRUB(_pa) (HSPEC_BASE + \ + NODE_ADDRSPACE_SIZE / 2 | \ + UINT64_CAST (_pa) & NASID_MASK | \ + UINT64_CAST (_pa) >> 3 & BDECC_UPPER_MASK \ + ^ 0x7ULL) + + /* address for Halfword backdoor ecc access. Note that */ + /* ecc bytes are packed in little endian order */ +#define BDECC_ENTRY_H(_pa) (HSPEC_BASE + \ + NODE_ADDRSPACE_SIZE * 5 / 8 | \ + UINT64_CAST (_pa) & NASID_MASK | \ + UINT64_CAST (_pa) >> 3 & BDECC_UPPER_MASK \ + ^ 0x6ULL) + +/* + * Macro to convert a back door directory, protection, page counter, or ecc + * address into the raw physical address of the associated cache line + * or protection page. + */ + +#define BDDIR_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \ + (UINT64_CAST (_ba) & BDDIR_UPPER_MASK) << 3) + +#ifdef BRINGUP +/* + * This can't be done since there are 4 entries per address so you'd end up + * mapping back to 4 different physical addrs. + */ + +#define BDPRT_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \ + (UINT64_CAST (_ba) & BDDIR_PAGE_MASK) << 3 | \ + (UINT64_CAST (_ba) & 0x3 << 4) << 3) +#endif + +#define BDCNT_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \ + (UINT64_CAST (_ba) & BDDIR_PAGE_MASK) << 3 | \ + (UINT64_CAST (_ba) & 0x3 << 4) << 3) + +#define BDECC_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \ + ((UINT64_CAST (_ba) ^ 0x7ULL) \ + & BDECC_UPPER_MASK) << 3 ) + +#define BDECC_H_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \ + ((UINT64_CAST (_ba) ^ 0x6ULL) \ + & BDECC_UPPER_MASK) << 3 ) + +#define BDADDR_IS_DIR(_ba) ((UINT64_CAST (_ba) & 0x8) == 0) +#define BDADDR_IS_PRT(_ba) ((UINT64_CAST (_ba) & 0x408) == 0x408) +#define BDADDR_IS_CNT(_ba) ((UINT64_CAST (_ba) & 0x8) == 0x8) + +#endif /* CONFIG_SGI_IP35 */ + + +/* + * The following macros produce the correct base virtual address for + * the hub registers. The LOCAL_HUB_* macros produce the appropriate + * address for the local registers. The REMOTE_HUB_* macro produce + * the address for the specified hub's registers. The intent is + * that the appropriate PI, MD, NI, or II register would be substituted + * for _x. + */ + +/* + * WARNING: + * When certain Hub chip workaround are defined, it's not sufficient + * to dereference the *_HUB_ADDR() macros. You should instead use + * HUB_L() and HUB_S() if you must deal with pointers to hub registers. + * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S(). + * They're always safe. + */ +#define LOCAL_HUB_ADDR(_x) (HUBREG_CAST (IALIAS_BASE + (_x))) +#define REMOTE_HUB_ADDR(_n, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \ + 0x800000 + (_x))) +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define REMOTE_HUB_PI_ADDR(_n, _sn, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \ + 0x800000 + PIREG(_x, _sn))) +#define LOCAL_HSPEC_ADDR(_x) (HUBREG_CAST (LREG_BASE + (_x))) +#define REMOTE_HSPEC_ADDR(_n, _x) (HUBREG_CAST (RREG_BASE(_n) + (_x))) +#endif /* CONFIG_SGI_IP35 */ + +#if _LANGUAGE_C + +#define HUB_L(_a) *(_a) +#define HUB_S(_a, _d) *(_a) = (_d) + +#define LOCAL_HUB_L(_r) HUB_L(LOCAL_HUB_ADDR(_r)) +#define LOCAL_HUB_S(_r, _d) HUB_S(LOCAL_HUB_ADDR(_r), (_d)) +#define REMOTE_HUB_L(_n, _r) HUB_L(REMOTE_HUB_ADDR((_n), (_r))) +#define REMOTE_HUB_S(_n, _r, _d) HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d)) +#define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r))) +#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d)) + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define LOCAL_HSPEC_L(_r) HUB_L(LOCAL_HSPEC_ADDR(_r)) +#define LOCAL_HSPEC_S(_r, _d) HUB_S(LOCAL_HSPEC_ADDR(_r), (_d)) +#define REMOTE_HSPEC_L(_n, _r) HUB_L(REMOTE_HSPEC_ADDR((_n), (_r))) +#define REMOTE_HSPEC_S(_n, _r, _d) HUB_S(REMOTE_HSPEC_ADDR((_n), (_r)), (_d)) +#endif /* CONFIG_SGI_IP35 */ + +#endif /* _LANGUAGE_C */ + +/* + * The following macros are used to get to a hub/bridge register, given + * the base of the register space. + */ +#define HUB_REG_PTR(_base, _off) \ + (HUBREG_CAST ((__psunsigned_t)(_base) + (__psunsigned_t)(_off))) + +#define HUB_REG_PTR_L(_base, _off) \ + HUB_L(HUB_REG_PTR((_base), (_off))) + +#define HUB_REG_PTR_S(_base, _off, _data) \ + HUB_S(HUB_REG_PTR((_base), (_off)), (_data)) + +/* + * Software structure locations -- permanently fixed + * See diagram in kldir.h + */ + +#define PHYS_RAMBASE 0x0 +#define K0_RAMBASE PHYS_TO_K0(PHYS_RAMBASE) + +#define EX_HANDLER_OFFSET(slice) ((slice) << 16) +#define EX_HANDLER_ADDR(nasid, slice) \ + PHYS_TO_K0(NODE_OFFSET(nasid) | EX_HANDLER_OFFSET(slice)) +#define EX_HANDLER_SIZE 0x0400 + +#define EX_FRAME_OFFSET(slice) ((slice) << 16 | 0x400) +#define EX_FRAME_ADDR(nasid, slice) \ + PHYS_TO_K0(NODE_OFFSET(nasid) | EX_FRAME_OFFSET(slice)) +#define EX_FRAME_SIZE 0x0c00 + +#define ARCS_SPB_OFFSET 0x1000 +#define ARCS_SPB_ADDR(nasid) \ + PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET) +#define ARCS_SPB_SIZE 0x0400 + +#define KLDIR_OFFSET 0x2000 +#define KLDIR_ADDR(nasid) \ + TO_NODE_UNCAC((nasid), KLDIR_OFFSET) +#define KLDIR_SIZE 0x0400 + + +/* + * Software structure locations -- indirected through KLDIR + * See diagram in kldir.h + * + * Important: All low memory structures must only be accessed + * uncached, except for the symmon stacks. + */ + +#define KLI_LAUNCH 0 /* Dir. entries */ +#define KLI_KLCONFIG 1 +#define KLI_NMI 2 +#define KLI_GDA 3 +#define KLI_FREEMEM 4 +#define KLI_SYMMON_STK 5 +#define KLI_PI_ERROR 6 +#define KLI_KERN_VARS 7 +#define KLI_KERN_XP 8 +#define KLI_KERN_PARTID 9 + +#if _LANGUAGE_C + +#define KLD_BASE(nasid) ((kldir_ent_t *) KLDIR_ADDR(nasid)) +#define KLD_LAUNCH(nasid) (KLD_BASE(nasid) + KLI_LAUNCH) +#define KLD_NMI(nasid) (KLD_BASE(nasid) + KLI_NMI) +#define KLD_KLCONFIG(nasid) (KLD_BASE(nasid) + KLI_KLCONFIG) +#define KLD_PI_ERROR(nasid) (KLD_BASE(nasid) + KLI_PI_ERROR) +#define KLD_GDA(nasid) (KLD_BASE(nasid) + KLI_GDA) +#define KLD_SYMMON_STK(nasid) (KLD_BASE(nasid) + KLI_SYMMON_STK) +#define KLD_FREEMEM(nasid) (KLD_BASE(nasid) + KLI_FREEMEM) +#define KLD_KERN_VARS(nasid) (KLD_BASE(nasid) + KLI_KERN_VARS) +#define KLD_KERN_XP(nasid) (KLD_BASE(nasid) + KLI_KERN_XP) +#define KLD_KERN_PARTID(nasid) (KLD_BASE(nasid) + KLI_KERN_PARTID) + +#define LAUNCH_OFFSET(nasid, slice) \ + (KLD_LAUNCH(nasid)->offset + \ + KLD_LAUNCH(nasid)->stride * (slice)) +#define LAUNCH_ADDR(nasid, slice) \ + TO_NODE_UNCAC((nasid), LAUNCH_OFFSET(nasid, slice)) +#define LAUNCH_SIZE(nasid) KLD_LAUNCH(nasid)->size + +#define NMI_OFFSET(nasid, slice) \ + (KLD_NMI(nasid)->offset + \ + KLD_NMI(nasid)->stride * (slice)) +#define NMI_ADDR(nasid, slice) \ + TO_NODE_UNCAC((nasid), NMI_OFFSET(nasid, slice)) +#define NMI_SIZE(nasid) KLD_NMI(nasid)->size + +#define KLCONFIG_OFFSET(nasid) KLD_KLCONFIG(nasid)->offset +#define KLCONFIG_ADDR(nasid) \ + TO_NODE_UNCAC((nasid), KLCONFIG_OFFSET(nasid)) +#define KLCONFIG_SIZE(nasid) KLD_KLCONFIG(nasid)->size + +#define GDA_ADDR(nasid) KLD_GDA(nasid)->pointer +#define GDA_SIZE(nasid) KLD_GDA(nasid)->size + +#define SYMMON_STK_OFFSET(nasid, slice) \ + (KLD_SYMMON_STK(nasid)->offset + \ + KLD_SYMMON_STK(nasid)->stride * (slice)) +#define SYMMON_STK_STRIDE(nasid) KLD_SYMMON_STK(nasid)->stride + +#define SYMMON_STK_ADDR(nasid, slice) \ + TO_NODE_CAC((nasid), SYMMON_STK_OFFSET(nasid, slice)) + +#define SYMMON_STK_SIZE(nasid) KLD_SYMMON_STK(nasid)->stride + +#define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size) + +/* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a + * relocatable program + */ +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +/* update master.d/sn1_elspec.dbg, SN1/addrs.h/DEBUGUNIX_ADDR, and + * DBGLOADADDR in symmon's Makefile when changing this */ +#define UNIX_DEBUG_LOADADDR 0x310000 +#elif defined(SN0XXL) +#define UNIX_DEBUG_LOADADDR 0x360000 +#else +#define UNIX_DEBUG_LOADADDR 0x300000 +#endif +#define SYMMON_LOADADDR(nasid) \ + TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000)) + +#define FREEMEM_OFFSET(nasid) KLD_FREEMEM(nasid)->offset +#define FREEMEM_ADDR(nasid) SYMMON_STK_END(nasid) +/* + * XXX + * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded. + * Also, it should take into account what prom thinks to be a safe + * address + PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid)) + */ +#define FREEMEM_SIZE(nasid) KLD_FREEMEM(nasid)->size + +#define PI_ERROR_OFFSET(nasid) KLD_PI_ERROR(nasid)->offset +#define PI_ERROR_ADDR(nasid) \ + TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid)) +#define PI_ERROR_SIZE(nasid) KLD_PI_ERROR(nasid)->size + +#define NODE_OFFSET_TO_K0(_nasid, _off) \ + (PAGE_OFFSET | NODE_OFFSET(_nasid) | (_off)) +#define K0_TO_NODE_OFFSET(_k0addr) \ + ((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK) + +#define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer +#define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size + +#define KERN_XP_ADDR(nasid) KLD_KERN_XP(nasid)->pointer +#define KERN_XP_SIZE(nasid) KLD_KERN_XP(nasid)->size + +#define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET) + +#endif /* _LANGUAGE_C */ + + +#endif /* _ASM_SN_ADDRS_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/agent.h linux-2.4.0-test12-lia/include/asm-ia64/sn/agent.h --- linux-2.4.0-test12/include/asm-ia64/sn/agent.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/agent.h Wed Dec 13 23:52:14 2000 @@ -0,0 +1,45 @@ +/* $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. + * + * This file has definitions for the hub and snac interfaces. + * + * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc. + * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + */ +#ifndef _ASM_SGI_SN_AGENT_H +#define _ASM_SGI_SN_AGENT_H + +#include +#include +//#include + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif /* CONFIG_SGI_IP35 */ + +/* + * NIC register macros + */ + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define HUB_NIC_ADDR(_cpuid) \ + REMOTE_HUB_ADDR(COMPACT_TO_NASID_NODEID(cputocnode(_cpuid)), \ + LB_MICROLAN_CTL) +#endif + +#define SET_HUB_NIC(_my_cpuid, _val) \ + (HUB_S(HUB_NIC_ADDR(_my_cpuid), (_val))) + +#define SET_MY_HUB_NIC(_v) \ + SET_HUB_NIC(cpuid(), (_v)) + +#define GET_HUB_NIC(_my_cpuid) \ + (HUB_L(HUB_NIC_ADDR(_my_cpuid))) + +#define GET_MY_HUB_NIC() \ + GET_HUB_NIC(cpuid()) + +#endif /* _ASM_SGI_SN_AGENT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/alenlist.h linux-2.4.0-test12-lia/include/asm-ia64/sn/alenlist.h --- linux-2.4.0-test12/include/asm-ia64/sn/alenlist.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/alenlist.h Wed Dec 6 21:56:06 2000 @@ -0,0 +1,204 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_ALENLIST_H +#define _ASM_SN_ALENLIST_H + +/* Definition of Address/Length List */ + +/* + * An Address/Length List is used when setting up for an I/O DMA operation. + * A driver creates an Address/Length List that describes to the the DMA + * interface where in memory the DMA should go. The bus interface sets up + * mapping registers, if required, and returns a suitable list of "physical + * addresses" or "I/O address" to the driver. The driver then uses these + * to set up an appropriate scatter/gather operation(s). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * An Address/Length List Address. It'll get cast to the appropriate type, + * and must be big enough to hold the largest possible address in any + * supported address space. + */ +typedef u64 alenaddr_t; +typedef u64 uvaddr_t; + +typedef struct alenlist_s *alenlist_t; + +/* + * For tracking progress as we walk down an address/length list. + */ +typedef struct alenlist_cursor_s *alenlist_cursor_t; + +/* + * alenlist representation that can be passed via an idl + */ +struct external_alenlist { + alenaddr_t addr; + size_t len; +}; +typedef struct external_alenlist *external_alenlist_t; + + +/* Return codes from alenlist routines. */ +#define ALENLIST_FAILURE -1 +#define ALENLIST_SUCCESS 0 + + +/* Flags to alenlist routines */ +#define AL_NOSLEEP 0x01 /* Do not sleep, waiting for memory */ +#define AL_NOCOMPACT 0x02 /* Do not try to compact adjacent entries */ +#define AL_LEAVE_CURSOR 0x04 /* Do not update cursor */ + + +/* Create an Address/Length List, and clear it of all entries. */ +extern alenlist_t alenlist_create(unsigned flags); + +/* Grow/shrink an Address/Length List and FIX its size. */ +extern int alenlist_grow(alenlist_t, size_t npairs); + +/* Clear an Address/Length List so that it now describes 0 pairs. */ +extern void alenlist_clear(alenlist_t alenlist); + +/* + * Convenience function to create an Address/Length List and then append + * the specified Address/Length Pair. Exactly the same as alenlist_create + * followed by alenlist_append. Can be used when a small list (e.g. 1 pair) + * is adequate. + */ +extern alenlist_t +alenpair_init( alenaddr_t address, /* init to this address */ + size_t length); /* init to this length */ + +/* + * Peek at the head of an Address/Length List. This does *NOT* update + * the internal cursor. + */ +extern int +alenpair_get( alenlist_t alenlist, /* in: get from this List */ + alenaddr_t *address, /* out: address */ + size_t *length); /* out: length */ + +/* Free the space consumed by an Address/Length List. */ +extern void alenlist_destroy(alenlist_t alenlist); + +/* + * Indicate that we're done using an Address/Length List. + * If we are the last user, destroy the List. + */ +extern void +alenlist_done(alenlist_t alenlist); + +/* Append another Pair to a List */ +extern int alenlist_append(alenlist_t alenlist, /* append to this list */ + alenaddr_t address, /* address to append */ + size_t length, /* length to append */ + unsigned flags); + +/* + * Replace a Pair in the middle of a List, and return old values. + * (not generally useful for drivers; used by bus providers). + */ +extern int +alenlist_replace( alenlist_t alenlist, /* in: replace in this list */ + alenlist_cursor_t cursorp, /* inout: which item to replace */ + alenaddr_t *addrp, /* inout: address */ + size_t *lengthp, /* inout: length */ + unsigned flags); + + +/* Get the next Pair from a List */ +extern int alenlist_get(alenlist_t alenlist, /* in: get from this list */ + alenlist_cursor_t cursorp, /* inout: which item to get */ + size_t maxlength, /* in: at most length */ + alenaddr_t *addr, /* out: address */ + size_t *length, /* out: length */ + unsigned flags); + + +/* Return the number of Pairs stored in this List */ +extern int alenlist_size(alenlist_t alenlist); + +/* Concatenate two Lists. */ +extern void alenlist_concat( alenlist_t from, /* copy from this list */ + alenlist_t to); /* to this list */ + +/* Create a copy of an Address/Length List */ +extern alenlist_t alenlist_clone(alenlist_t old, /* clone this list */ + unsigned flags); + + +/* Allocate and initialize an Address/Length List Cursor */ +extern alenlist_cursor_t alenlist_cursor_create(alenlist_t alenlist, unsigned flags); + +/* Free an Address/Length List Cursor */ +extern void alenlist_cursor_destroy(alenlist_cursor_t cursorp); + +/* + * Initialize an Address/Length List Cursor in order to walk thru an + * Address/Length List from the beginning. + */ +extern int alenlist_cursor_init(alenlist_t alenlist, + size_t offset, + alenlist_cursor_t cursorp); + +/* Clone an Address/Length List Cursor. */ +extern int alenlist_cursor_clone(alenlist_t alenlist, + alenlist_cursor_t cursorp_in, + alenlist_cursor_t cursorp_out); + +/* + * Return the number of bytes passed so far according to the specified + * Address/Length List Cursor. + */ +extern size_t alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp); + + + + +/* Convert from a Kernel Virtual Address to a Physical Address/Length List */ +extern alenlist_t kvaddr_to_alenlist( alenlist_t alenlist, + caddr_t kvaddr, + size_t length, + unsigned flags); + +/* Convert from a User Virtual Address to a Physical Address/Length List */ +extern alenlist_t uvaddr_to_alenlist( alenlist_t alenlist, + uvaddr_t vaddr, + size_t length, + unsigned flags); + +/* Convert from a buf struct to a Physical Address/Length List */ +struct buf; +extern alenlist_t buf_to_alenlist( alenlist_t alenlist, + struct buf *buf, + unsigned flags); + + +/* + * Tracking position as we walk down an Address/Length List. + * This structure is NOT generally for use by device drivers. + */ +struct alenlist_cursor_s { + struct alenlist_s *al_alenlist; /* which list */ + size_t al_offset; /* total bytes passed by cursor */ + struct alenlist_chunk_s *al_chunk; /* which chunk in alenlist */ + unsigned int al_index; /* which pair in chunk */ + size_t al_bcount; /* offset into address/length pair */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASM_SN_ALENLIST_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/arc/hinv.h linux-2.4.0-test12-lia/include/asm-ia64/sn/arc/hinv.h --- linux-2.4.0-test12/include/asm-ia64/sn/arc/hinv.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/arc/hinv.h Wed Dec 6 21:56:06 2000 @@ -0,0 +1,186 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +/* $Id$ + * + * ARCS hardware/memory inventory/configuration and system ID definitions. + */ +#ifndef _ASM_SN_ARC_HINV_H +#define _ASM_SN_ARC_HINV_H + +#include + +/* configuration query defines */ +typedef enum configclass { + SystemClass, + ProcessorClass, + CacheClass, +#ifndef _NT_PROM + MemoryClass, + AdapterClass, + ControllerClass, + PeripheralClass +#else /* _NT_PROM */ + AdapterClass, + ControllerClass, + PeripheralClass, + MemoryClass +#endif /* _NT_PROM */ +} CONFIGCLASS; + +typedef enum configtype { + ARC, + CPU, + FPU, + PrimaryICache, + PrimaryDCache, + SecondaryICache, + SecondaryDCache, + SecondaryCache, +#ifndef _NT_PROM + Memory, +#endif + EISAAdapter, + TCAdapter, + SCSIAdapter, + DTIAdapter, + MultiFunctionAdapter, + DiskController, + TapeController, + CDROMController, + WORMController, + SerialController, + NetworkController, + DisplayController, + ParallelController, + PointerController, + KeyboardController, + AudioController, + OtherController, + DiskPeripheral, + FloppyDiskPeripheral, + TapePeripheral, + ModemPeripheral, + MonitorPeripheral, + PrinterPeripheral, + PointerPeripheral, + KeyboardPeripheral, + TerminalPeripheral, + LinePeripheral, + NetworkPeripheral, +#ifdef _NT_PROM + Memory, +#endif + OtherPeripheral, + + /* new stuff for IP30 */ + /* added without moving anything */ + /* except ANONYMOUS. */ + + XTalkAdapter, + PCIAdapter, + GIOAdapter, + TPUAdapter, + + Anonymous +} CONFIGTYPE; + +typedef enum { + Failed = 1, + ReadOnly = 2, + Removable = 4, + ConsoleIn = 8, + ConsoleOut = 16, + Input = 32, + Output = 64 +} IDENTIFIERFLAG; + +#ifndef NULL /* for GetChild(NULL); */ +#define NULL 0 +#endif + +union key_u { + struct { +#ifdef _MIPSEB + unsigned char c_bsize; /* block size in lines */ + unsigned char c_lsize; /* line size in bytes/tag */ + unsigned short c_size; /* cache size in 4K pages */ +#else /* _MIPSEL */ + unsigned short c_size; /* cache size in 4K pages */ + unsigned char c_lsize; /* line size in bytes/tag */ + unsigned char c_bsize; /* block size in lines */ +#endif /* _MIPSEL */ + } cache; + ULONG FullKey; +}; + +#if _MIPS_SIM == _ABI64 +#define SGI_ARCS_VERS 64 /* sgi 64-bit version */ +#define SGI_ARCS_REV 0 /* rev .00 */ +#else +#define SGI_ARCS_VERS 1 /* first version */ +#define SGI_ARCS_REV 10 /* rev .10, 3/04/92 */ +#endif + +typedef struct component { + CONFIGCLASS Class; + CONFIGTYPE Type; + IDENTIFIERFLAG Flags; + USHORT Version; + USHORT Revision; + ULONG Key; + ULONG AffinityMask; + ULONG ConfigurationDataSize; + ULONG IdentifierLength; + char *Identifier; +} COMPONENT; + +/* internal structure that holds pathname parsing data */ +struct cfgdata { + char *name; /* full name */ + int minlen; /* minimum length to match */ + CONFIGTYPE type; /* type of token */ +}; + +/* System ID */ +typedef struct systemid { + CHAR VendorId[8]; + CHAR ProductId[8]; +} SYSTEMID; + +/* memory query functions */ +typedef enum memorytype { + ExceptionBlock, + SPBPage, /* ARCS == SystemParameterBlock */ +#ifndef _NT_PROM + FreeContiguous, + FreeMemory, + BadMemory, + LoadedProgram, + FirmwareTemporary, + FirmwarePermanent +#else /* _NT_PROM */ + FreeMemory, + BadMemory, + LoadedProgram, + FirmwareTemporary, + FirmwarePermanent, + FreeContiguous +#endif /* _NT_PROM */ +} MEMORYTYPE; + +typedef struct memorydescriptor { + MEMORYTYPE Type; + LONG BasePage; + LONG PageCount; +} MEMORYDESCRIPTOR; + +#endif /* _ASM_SN_ARC_HINV_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/arc/types.h linux-2.4.0-test12-lia/include/asm-ia64/sn/arc/types.h --- linux-2.4.0-test12/include/asm-ia64/sn/arc/types.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/arc/types.h Wed Dec 6 21:56:06 2000 @@ -0,0 +1,43 @@ +/* + * 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 1999 Ralf Baechle (ralf@gnu.org) + * Copyright 1999 Silicon Graphics, Inc. + */ +#ifndef _ASM_SN_ARC_TYPES_H +#define _ASM_SN_ARC_TYPES_H + +#include + +typedef char CHAR; +typedef short SHORT; +typedef long LARGE_INTEGER __attribute__ ((__mode__ (__DI__))); +typedef long LONG __attribute__ ((__mode__ (__DI__))); +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned long ULONG __attribute__ ((__mode__ (__DI__))); +typedef void VOID; + +/* The pointer types. We're 64-bit and the firmware is also 64-bit, so + live is sane ... */ +typedef CHAR *_PCHAR; +typedef SHORT *_PSHORT; +typedef LARGE_INTEGER *_PLARGE_INTEGER; +typedef LONG *_PLONG; +typedef UCHAR *_PUCHAR; +typedef USHORT *_PUSHORT; +typedef ULONG *_PULONG; +typedef VOID *_PVOID; + +typedef CHAR *PCHAR; +typedef SHORT *PSHORT; +typedef LARGE_INTEGER *PLARGE_INTEGER; +typedef LONG *PLONG; +typedef UCHAR *PUCHAR; +typedef USHORT *PUSHORT; +typedef ULONG *PULONG; +typedef VOID *PVOID; + +#endif /* _ASM_SN_ARC_TYPES_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/arch.h linux-2.4.0-test12-lia/include/asm-ia64/sn/arch.h --- linux-2.4.0-test12/include/asm-ia64/sn/arch.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/arch.h Wed Dec 13 19:35:00 2000 @@ -0,0 +1,175 @@ +/* $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. + * + * SGI specific setup. + * + * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc. + * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + */ +#ifndef _ASM_SN_ARCH_H +#define _ASM_SN_ARCH_H + +#include +#include + +#if defined(CONFIG_IA64_SGI_IO) +#include +#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_SGI_IP37) || defined(CONFIG_IA64_GENERIC) +#include +#endif +#endif /* CONFIG_IA64_SGI_IO */ + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +typedef u64 hubreg_t; +typedef u64 nic_t; +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +typedef u64 bdrkreg_t; +#endif /* CONFIG_SGI_xxxxx */ +#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define CPUS_PER_NODE 4 /* CPUs on a single hub */ +#define CPUS_PER_NODE_SHFT 2 /* Bits to shift in the node number */ +#define CPUS_PER_SUBNODE 2 /* CPUs on a single hub PI */ +#endif +#define CNODE_NUM_CPUS(_cnode) (NODEPDA(_cnode)->node_num_cpus) + +#define CNODE_TO_CPU_BASE(_cnode) (NODEPDA(_cnode)->node_first_cpu) + +#define makespnum(_nasid, _slice) \ + (((_nasid) << CPUS_PER_NODE_SHFT) | (_slice)) + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + +/* + * There are 2 very similar macros for dealing with "slices". Make sure + * you use the right one. + * Unfortunately, on all platforms except IP35 (currently), the 2 macros + * are interchangible. + * + * On IP35, there are 4 cpus per node. Each cpu is refered to by it's slice. + * The slices are numbered 0 thru 3. + * + * There are also 2 PI interfaces per node. Each PI interface supports 2 cpus. + * The term "local slice" specifies the cpu number relative to the PI. + * + * The cpus on the node are numbered: + * slice localslice + * 0 0 + * 1 1 + * 2 0 + * 3 1 + * + * cputoslice - returns a number 0..3 that is the slice of the specified cpu. + * cputolocalslice - returns a number 0..1 that identifies the local slice of + * the cpu within it's PI interface. + */ +#ifdef notyet + /* These are dummied up for now ..... */ +#define cputocnode(cpu) \ + (pdaindr[(cpu)].p_nodeid) +#define cputonasid(cpu) \ + (pdaindr[(cpu)].p_nasid) +#define cputoslice(cpu) \ + (ASSERT(pdaindr[(cpu)].pda), (pdaindr[(cpu)].pda->p_slice)) +#define cputolocalslice(cpu) \ + (ASSERT(pdaindr[(cpu)].pda), (LOCALCPU(pdaindr[(cpu)].pda->p_slice))) +#define cputosubnode(cpu) \ + (ASSERT(pdaindr[(cpu)].pda), (SUBNODE(pdaindr[(cpu)].pda->p_slice))) +#else +#define cputocnode(cpu) 0 +#define cputonasid(cpu) 0 +#define cputoslice(cpu) 0 +#define cputolocalslice(cpu) 0 +#define cputosubnode(cpu) 0 +#endif /* notyet */ +#endif /* CONFIG_SGI_IP35 */ + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#define INVALID_NASID (nasid_t)-1 +#define INVALID_CNODEID (cnodeid_t)-1 +#define INVALID_PNODEID (pnodeid_t)-1 +#define INVALID_MODULE (moduleid_t)-1 +#define INVALID_PARTID (partid_t)-1 + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +extern int get_slice(void); +extern cpuid_t get_cnode_cpu(cnodeid_t); +extern int get_cpu_slice(cpuid_t); +extern cpuid_t cnodetocpu(cnodeid_t); +// extern cpuid_t cnode_slice_to_cpuid(cnodeid_t, int); + +extern int cnode_exists(cnodeid_t cnode); +extern cnodeid_t cpuid_to_compact_node[MAXCPUS]; +#endif /* CONFIG_IP35 */ + +extern nasid_t get_nasid(void); +extern cnodeid_t get_cpu_cnode(int); +extern int get_cpu_slice(cpuid_t); + +/* + * NO ONE should access these arrays directly. The only reason we refer to + * them here is to avoid the procedure call that would be required in the + * macros below. (Really want private data members here :-) + */ +extern cnodeid_t nasid_to_compact_node[MAX_NASIDS]; +extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; + +/* + * These macros are used by various parts of the kernel to convert + * between the three different kinds of node numbering. At least some + * of them may change to procedure calls in the future, but the macros + * will continue to work. Don't use the arrays above directly. + */ + +#define NASID_TO_REGION(nnode) \ + ((nnode) >> \ + (is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT)) + +extern cnodeid_t nasid_to_compact_node[MAX_NASIDS]; +extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; +extern cnodeid_t cpuid_to_compact_node[MAXCPUS]; + +#if !defined(DEBUG) + +#define NASID_TO_COMPACT_NODEID(nnode) (nasid_to_compact_node[nnode]) +#define COMPACT_TO_NASID_NODEID(cnode) (compact_to_nasid_node[cnode]) +#define CPUID_TO_COMPACT_NODEID(cpu) (cpuid_to_compact_node[(cpu)]) +#else + +/* + * These functions can do type checking and fail if they need to return + * a bad nodeid, but they're not as fast so just use 'em for debug kernels. + */ +cnodeid_t nasid_to_compact_nodeid(nasid_t nasid); +nasid_t compact_to_nasid_nodeid(cnodeid_t cnode); + +#define NASID_TO_COMPACT_NODEID(nnode) nasid_to_compact_nodeid(nnode) +#define COMPACT_TO_NASID_NODEID(cnode) compact_to_nasid_nodeid(cnode) +#define CPUID_TO_COMPACT_NODEID(cpu) (cpuid_to_compact_node[(cpu)]) +#endif + +extern int node_getlastslot(cnodeid_t); + +#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ + +#define SLOT_BITMASK (MAX_MEM_SLOTS - 1) +#define SLOT_SIZE (1LL< + +/* + * cdl: connection/driver list + * + * support code for bus infrastructure for busses + * that have self-identifying devices; initially + * constructed for xtalk, pciio and gioio modules. + */ +typedef struct cdl *cdl_p; + +/* + * cdl_itr_f is the type for the functions + * that are handled by cdl_iterate. + */ + +typedef void +cdl_iter_f (devfs_handle_t vhdl); + +/* + * If CDL_PRI_HI is specified in the flags + * parameter for cdl_add_driver, then that driver's + * attach routine will be called for future connect + * points before any (non-CDL_PRI_HI) drivers. + * + * The IOC3 driver uses this facility to make sure + * that the ioc3_attach() function is called before + * the attach routines of any subdevices. + * + * Drivers for bridge-based crosstalk cards that + * are almost but not quite generic can use it to + * arrange that their attach() functions get called + * before the generic bridge drivers, so they can + * leave behind "hint" structures that will + * properly configure the generic driver. + */ +#define CDL_PRI_HI 0x0001 + +/* + * cdl_new: construct a new connection/driver list + * + * Called once for each "kind" of bus. Returns an + * opaque cookie representing the particular list + * that will be operated on by the other calls. + */ +extern cdl_p cdl_new(char *, char *, char *); + +/* + * cdl_del: destroy a connection/driver list. + * + * Releases all dynamically allocated resources + * associated with the specified list. Forgets what + * drivers might be involved in this kind of bus, + * forgets what connection points have been noticed + * on this kind of bus. + */ +extern void cdl_del(cdl_p reg); + +/* + * cdl_add_driver: register a device driver + * + * Calls the driver's attach routine with all + * connection points on the list that have the same + * key information as the driver; then places the + * driver on the list so that any connection points + * discovered in the future that match the driver + * can be handed off to the driver's attach + * routine. + * + * CDL_PRI_HI may be specified (see above). + */ + +extern int cdl_add_driver(cdl_p reg, + int key1, + int key2, + char *prefix, + int flags); + +/* + * cdl_del_driver: remove a device driver + * + * Calls the driver's detach routine with all + * connection points on the list that match the + * driver; then forgets about the driver. Future + * calls to cdl_add_connpt with connections that + * would match this driver no longer trigger calls + * to the driver's attach routine. + * + * NOTE: Yes, I said CONNECTION POINTS, not + * verticies that the driver has been attached to + * with hwgraph_driver_add(); this gives the driver + * a chance to clean up anything it did to the + * connection point in its attach routine. Also, + * this is done whether or not the attach routine + * was successful. + */ +extern void cdl_del_driver(cdl_p reg, + char *prefix); + +/* + * cdl_add_connpt: add a connection point + * + * Calls the attach routines of all the drivers on + * the list that match this connection point, in + * the order that they were added to the list, + * except that CDL_PRI_HI drivers are called first. + * + * Then the vertex is added to the list, so it can + * be presented to any matching drivers that may be + * subsequently added to the list. + */ +extern int cdl_add_connpt(cdl_p reg, + int key1, + int key2, + devfs_handle_t conn); + +/* + * cdl_del_connpt: delete a connection point + * + * Calls the detach routines of all matching + * drivers for this connection point, in the same + * order that the attach routines were called; then + * forgets about this vertex, so drivers added in + * the future will not be told about it. + * + * NOTE: Same caveat here about the detach calls as + * in the cdl_del_driver() comment above. + */ +extern void cdl_del_connpt(cdl_p reg, + int key1, + int key2, + devfs_handle_t conn); + +/* + * cdl_iterate: find all verticies in the registry + * corresponding to the named driver and call them + * with the specified function (giving the vertex + * as the parameter). + */ + +extern void cdl_iterate(cdl_p reg, + char *prefix, + cdl_iter_f *func); + +/* + * An INFO_LBL_ASYNC_ATTACH label is attached to a vertex, pointing to + * an instance of async_attach_s to indicate that asynchronous + * attachment may be applied to that device ... if the corresponding + * driver allows it. + */ + +struct async_attach_s { + sema_t async_sema; + int async_count; +}; +typedef struct async_attach_s *async_attach_t; + +async_attach_t async_attach_new(void); +void async_attach_free(async_attach_t); +async_attach_t async_attach_get_info(devfs_handle_t); +void async_attach_add_info(devfs_handle_t, async_attach_t); +void async_attach_del_info(devfs_handle_t); +void async_attach_signal_start(async_attach_t); +void async_attach_signal_done(async_attach_t); +void async_attach_waitall(async_attach_t); + +#endif /* _ASM_SN_CDL_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/clksupport.h linux-2.4.0-test12-lia/include/asm-ia64/sn/clksupport.h --- linux-2.4.0-test12/include/asm-ia64/sn/clksupport.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/clksupport.h Wed Dec 13 23:52:28 2000 @@ -0,0 +1,64 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +#ifndef _ASM_KSYS_CLKSUPPORT_H +#define _ASM_KSYS_CLKSUPPORT_H + +/* #include */ + +#if SN +#include +#include +typedef hubreg_t clkreg_t; +extern nasid_t master_nasid; + +#define GET_LOCAL_RTC (clkreg_t)LOCAL_HUB_L(PI_RT_COUNT) +#define DISABLE_TMO_INTR() if (cpuid_to_localslice(cpuid())) \ + REMOTE_HUB_PI_S(get_nasid(),\ + cputosubnode(cpuid()),\ + PI_RT_COMPARE_B, 0); \ + else \ + REMOTE_HUB_PI_S(get_nasid(),\ + cputosubnode(cpuid()),\ + PI_RT_COMPARE_A, 0); + +/* This is a hack; we really need to figure these values out dynamically */ +/* + * Since 800 ns works very well with various HUB frequencies, such as + * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. + */ +#define NSEC_PER_CYCLE 800 +#define CYCLE_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE) +/* + * Number of cycles per profiling intr + */ +#define CLK_FCLOCK_FAST_FREQ 1250 +#define CLK_FCLOCK_SLOW_FREQ 0 +/* The is the address that the user will use to mmap the cycle counter */ +#define CLK_CYCLE_ADDRESS_FOR_USER LOCAL_HUB_ADDR(PI_RT_COUNT) + +#elif IP30 +#include +typedef heartreg_t clkreg_t; +#define NSEC_PER_CYCLE 80 +#define CYCLE_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE) +#define GET_LOCAL_RTC *((volatile clkreg_t *)PHYS_TO_COMPATK1(HEART_COUNT)) +#define DISABLE_TMO_INTR() +#define CLK_CYCLE_ADDRESS_FOR_USER PHYS_TO_K1(HEART_COUNT) +#define CLK_FCLOCK_SLOW_FREQ (CYCLE_PER_SEC / HZ) +#endif + +/* Prototypes */ +extern void init_timebase(void); +extern void fastick_maint(struct eframe_s *); +extern int audioclock; +extern int prfclk_enabled_cnt; +#endif /* _ASM_KSYS_CLKSUPPORT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/cmn_err.h linux-2.4.0-test12-lia/include/asm-ia64/sn/cmn_err.h --- linux-2.4.0-test12/include/asm-ia64/sn/cmn_err.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/cmn_err.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,120 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_CMN_ERR_H +#define _ASM_SN_CMN_ERR_H + +/* +** Common error handling severity levels. Converted to be +** represented by the associated 4.3BSD syslog priorities. +*/ + +#define CE_DEBUG KERN_DEBUG /* debug */ +#define CE_CONT KERN_INFO /* continuation */ +#define CE_NOTE KERN_NOTICE /* notice */ +#define CE_WARN KERN_WARNING /* warning */ +#define CE_ALERT KERN_ALERT /* alert */ +#define CE_PANIC KERN_EMERG /* panic */ + +#define CE_LEVELMASK LOG_PRIMASK /* mask for severity level */ +#define CE_CPUID 0x8 /* prepend CPU id to output */ +#define CE_PHYSID 0x10 /* prepend CPU phys location */ +#define CE_SYNC 0x20 /* wait for uart to drain before returning */ + +/* Flags for Availmon Monitoring + * When a developer or's these bits into the cmn_err flags above, + * and they have availmon installed, certain "actions" will take + * place depending upon how they have the availmon software configured. + */ +#define CE_TOOKACTIONS 0x0100 /* Actions taken by some error */ +#define CE_RUNNINGPOOR 0x0200 /* System running degraded */ +#define CE_MAINTENANCE 0x0400 /* System needs maintenance */ +#define CE_CONFIGERROR 0x0800 /* System configured incorrectly */ + +/* Bitmasks for separating subtasks from priority levels */ +#define CE_PRIOLEVELMASK 0x00ff /* bitmask for severity levels of cmn_err */ +#define CE_SUBTASKMASK 0xff00 /* bitmask for availmon actions of cmn_err */ +#define CE_AVAILMONALL (CE_TOOKACTIONS|CE_RUNNINGPOOR| \ + CE_MAINTENANCE|CE_CONFIGERROR) + +#ifdef __KERNEL__ + +#define CE_PBPANIC KERN_CRIT /* Special define used to manipulate + * putbufndx in kernel */ + +/* Console output flushing flag and routine */ + +extern int constrlen; /* Length of current console string, if zero, + there are no characters to flush */ +#define CONBUF_LOCKED 0 /* conbuf is already locked */ +#define CONBUF_UNLOCKED 1 /* need to reacquire lock */ +#define CONBUF_DRAIN 2 /* ensure output before returning */ + +/* + * bit field descriptions for printf %r and %R formats + * + * printf("%r %R", val, reg_descp); + * struct reg_desc *reg_descp; + * + * the %r and %R formats allow formatted print of bit fields. individual + * bit fields are described by a struct reg_desc, multiple bit fields within + * a single word can be described by multiple reg_desc structures. + * %r outputs a string of the format "" + * %R outputs a string of the format "0x%x" + * + * The fields in a reg_desc are: + * __psunsigned_t rd_mask; An appropriate mask to isolate the bit field + * within a word, and'ed with val + * + * int rd_shift; A shift amount to be done to the isolated + * bit field. done before printing the isolate + * bit field with rd_format and before searching + * for symbolic value names in rd_values + * + * char *rd_name; If non-null, a bit field name to label any + * out from rd_format or searching rd_values. + * if neither rd_format or rd_values is non-null + * rd_name is printed only if the isolated + * bit field is non-null. + * + * char *rd_format; If non-null, the shifted bit field value + * is printed using this format. + * + * struct reg_values *rd_values; If non-null, a pointer to a table + * matching numeric values with symbolic names. + * rd_values are searched and the symbolic + * value is printed if a match is found, if no + * match is found "???" is printed. + * + */ + + +/* + * register values + * map between numeric values and symbolic values + */ +struct reg_values { + __psunsigned_t rv_value; + char *rv_name; +}; + +/* + * register descriptors are used for formatted prints of register values + * rd_mask and rd_shift must be defined, other entries may be null + */ +struct reg_desc { + k_machreg_t rd_mask; /* mask to extract field */ + int rd_shift; /* shift for extracted value, - >>, + << */ + char *rd_name; /* field name */ + char *rd_format; /* format to print field */ + struct reg_values *rd_values; /* symbolic names of values */ +}; + +#endif /* __KERNEL__ */ +#endif /* _ASM_SN_CMN_ERR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/dmamap.h linux-2.4.0-test12-lia/include/asm-ia64/sn/dmamap.h --- linux-2.4.0-test12/include/asm-ia64/sn/dmamap.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/dmamap.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,88 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_DMAMAP_H +#define _ASM_SN_DMAMAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Definitions for allocating, freeing, and using DMA maps + */ + +/* + * DMA map types + */ +#define DMA_SCSI 0 +#define DMA_A24VME 1 /* Challenge/Onyx only */ +#define DMA_A32VME 2 /* Challenge/Onyx only */ +#define DMA_A64VME 3 /* SN0/Racer */ + +#define DMA_EISA 4 + +#define DMA_PCI32 5 /* SN0/Racer */ +#define DMA_PCI64 6 /* SN0/Racer */ + +/* + * DMA map structure as returned by dma_mapalloc() + */ +typedef struct dmamap { + int dma_type; /* Map type (see above) */ + int dma_adap; /* I/O adapter */ + int dma_index; /* Beginning map register to use */ + int dma_size; /* Number of map registers to use */ + paddr_t dma_addr; /* Corresponding bus addr for A24/A32 */ + caddr_t dma_virtaddr; /* Beginning virtual address that is mapped */ +} dmamap_t; + +struct alenlist_s; + +/* + * Prototypes of exported functions + */ +extern dmamap_t *dma_mapalloc(int, int, int, int); +extern void dma_mapfree(dmamap_t *); +extern int dma_map(dmamap_t *, caddr_t, int); +extern int dma_map2(dmamap_t *, caddr_t, caddr_t, int); +extern paddr_t dma_mapaddr(dmamap_t *, caddr_t); +#ifdef IRIX +extern int dma_mapbp(dmamap_t *, buf_t *, int); +#endif +extern int dma_map_alenlist(dmamap_t *, struct alenlist_s *, size_t); +extern uint ev_kvtoiopnum(caddr_t); + +/* + * These variables are defined in master.d/kernel + */ +extern struct map *a24map[]; +extern struct map *a32map[]; + +extern int a24_mapsize; +extern int a32_mapsize; + +extern lock_t dmamaplock; +extern sv_t dmamapout; + +#ifdef __cplusplus +} +#endif + +/* standard flags values for pio_map routines, + * including {xtalk,pciio}_dmamap calls. + * NOTE: try to keep these in step with PIOMAP flags. + */ +#define DMAMAP_FIXED 0x1 +#define DMAMAP_NOSLEEP 0x2 +#define DMAMAP_INPLACE 0x4 + +#define DMAMAP_FLAGS 0x7 + +#endif /* _ASM_SN_DMAMAP_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/driver.h linux-2.4.0-test12-lia/include/asm-ia64/sn/driver.h --- linux-2.4.0-test12/include/asm-ia64/sn/driver.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/driver.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,150 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_DRIVER_H +#define _ASM_SN_DRIVER_H + +/* +** Interface for device driver handle management. +** +** These functions are mostly for use by the loadable driver code, and +** for use by I/O bus infrastructure code. +*/ + +typedef struct device_driver_s *device_driver_t; +#define DEVICE_DRIVER_NONE (device_driver_t)NULL + +/* == Driver thread priority support == */ +typedef int ilvl_t; +/* default driver thread priority level */ +#define DRIVER_THREAD_PRI_DEFAULT (ilvl_t)230 +/* invalid driver thread priority level */ +#define DRIVER_THREAD_PRI_INVALID (ilvl_t)-1 + +/* Associate a thread priority with a driver */ +extern int device_driver_thread_pri_set(device_driver_t driver, + ilvl_t pri); + +/* Get the thread priority associated with the driver */ +extern ilvl_t device_driver_thread_pri_get(device_driver_t driver); + +/* Get the thread priority for a driver from the sysgen paramters */ +extern ilvl_t device_driver_sysgen_thread_pri_get(char *driver_prefix); + +/* Initialize device driver functions. */ +extern void device_driver_init(void); + + +/* Allocate a driver handle */ +extern device_driver_t device_driver_alloc(char *prefix); + + +/* Free a driver handle */ +extern void device_driver_free(device_driver_t driver); + + +/* Given a device driver prefix, return a handle to the driver. */ +extern device_driver_t device_driver_get(char *prefix); + +/* Given a device, return a handle to the driver. */ +extern device_driver_t device_driver_getbydev(devfs_handle_t device); + +struct cdevsw; +struct bdevsw; + +/* Associate a driver with bdevsw/cdevsw pointers. */ +extern int +device_driver_devsw_put(device_driver_t driver, + struct bdevsw *my_bdevsw, + struct cdevsw *my_cdevsw); + + +/* Given a driver, return the corresponding bdevsw and cdevsw pointers. */ +extern void +device_driver_devsw_get( device_driver_t driver, + struct bdevsw **bdevswp, + struct cdevsw **cdevswp); + +/* Given a driver, return its name (prefix). */ +extern void device_driver_name_get(device_driver_t driver, char *buffer, int length); + + +/* + * A descriptor for every static device driver in the system. + * lboot creates a table of these and places in in master.c. + * device_driver_init runs through this table during initialization + * in order to "register" every static device driver. + */ +typedef struct static_device_driver_desc_s { + char *sdd_prefix; + struct bdevsw *sdd_bdevsw; + struct cdevsw *sdd_cdevsw; +} *static_device_driver_desc_t; + +extern struct static_device_driver_desc_s static_device_driver_table[]; +extern int static_devsw_count; + + +/*====== administration support ========== */ +/* structure of each entry in the table created by lboot for + * device / driver administration +*/ +typedef struct dev_admin_info_s { + char *dai_name; /* name of the device or driver + * prefix + */ + char *dai_param_name; /* device or driver parameter name */ + char *dai_param_val; /* value of the parameter */ +} dev_admin_info_t; + + +/* Update all the administrative hints associated with the device */ +extern void device_admin_info_update(devfs_handle_t dev_vhdl); + +/* Update all the administrative hints associated with the device driver */ +extern void device_driver_admin_info_update(device_driver_t driver); + +/* Get a particular administrative hint associated with a device */ +extern char *device_admin_info_get(devfs_handle_t dev_vhdl, + char *info_lbl); + +/* Associate a particular administrative hint for a device */ +extern int device_admin_info_set(devfs_handle_t dev_vhdl, + char *info_lbl, + char *info_val); + +/* Get a particular administrative hint associated with a device driver*/ +extern char *device_driver_admin_info_get(char *driver_prefix, + char *info_name); + +/* Associate a particular administrative hint for a device driver*/ +extern int device_driver_admin_info_set(char *driver_prefix, + char *driver_info_lbl, + char *driver_info_val); + +/* Initialize the extended device administrative hint table */ +extern void device_admin_table_init(void); + +/* Add a hint corresponding to a device to the extended device administrative + * hint table. + */ +extern void device_admin_table_update(char *dev_name, + char *param_name, + char *param_val); + +/* Initialize the extended device driver administrative hint table */ +extern void device_driver_admin_table_init(void); + +/* Add a hint corresponding to a device to the extended device driver + * administrative hint table. + */ +extern void device_driver_admin_table_update(char *drv_prefix, + char *param_name, + char *param_val); +#endif /* _ASM_SN_DRIVER_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/eeprom.h linux-2.4.0-test12-lia/include/asm-ia64/sn/eeprom.h --- linux-2.4.0-test12/include/asm-ia64/sn/eeprom.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/eeprom.h Wed Dec 13 23:52:34 2000 @@ -0,0 +1,402 @@ +/* $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. + * + * Public interface for reading Atmel EEPROMs via L1 system controllers + * + * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_EEPROM_H +#define _ASM_SN_EEPROM_H + +#include +#include +#include +#include +#include + +/* + * The following structures are an implementation of the EEPROM info + * areas described in the SN1 EEPROM spec and the IPMI FRU Information + * Storage definition + */ + +/* Maximum lengths for EEPROM fields + */ +#define EEPROM_PARTNUM_LEN 20 +#define EEPROM_SERNUM_LEN 10 +#define EEPROM_MANUF_NAME_LEN 10 +#define EEPROM_PROD_NAME_LEN 14 + + + +/* The EEPROM "common header", which contains offsets to the other + * info areas in the EEPROM + */ +typedef struct eeprom_common_hdr_t +{ + uchar_t format; /* common header format byte */ + uchar_t internal_use; /* offsets to various info areas */ + uchar_t chassis; /* (in doubleword units) */ + uchar_t board; + uchar_t product; + uchar_t multi_record; + uchar_t pad; + uchar_t checksum; +} eeprom_common_hdr_t; + + +/* The chassis (brick) info area + */ +typedef struct eeprom_chassis_ia_t +{ + uchar_t format; /* format byte */ + uchar_t length; /* info area length in doublewords */ + uchar_t type; /* chassis type (always 0x17 "rack mount") */ + uchar_t part_num_tl; /* type/length of part number field */ + + char part_num[EEPROM_PARTNUM_LEN]; + /* ASCII part number */ + + uchar_t serial_num_tl; /* type/length of serial number field */ + + char serial_num[EEPROM_SERNUM_LEN]; + /* ASCII serial number */ + + uchar_t checksum; + +} eeprom_chassis_ia_t; + + +/* The board info area + */ +typedef struct eeprom_board_ia_t +{ + uchar_t format; /* format byte */ + uchar_t length; /* info area length in doublewords */ + uchar_t language; /* language code, always 0x00 "English" */ + int mfg_date; /* date & time of manufacture, in minutes + since 0:00 1/1/96 */ + uchar_t manuf_tl; /* type/length of manufacturer name field */ + + char manuf[EEPROM_MANUF_NAME_LEN]; + /* ASCII manufacturer name */ + + uchar_t product_tl; /* type/length of product name field */ + + char product[EEPROM_PROD_NAME_LEN]; + /* ASCII product name */ + + uchar_t serial_num_tl; /* type/length of board serial number */ + + char serial_num[EEPROM_SERNUM_LEN]; + /* ASCII serial number */ + + uchar_t part_num_tl; /* type/length of board part number */ + + char part_num[EEPROM_PARTNUM_LEN]; + /* ASCII part number */ + + /* + * "custom" fields -- see SN1 EEPROM Spec + */ + uchar_t board_rev_tl; /* type/length of board rev (always 0xC2) */ + + char board_rev[2]; /* ASCII board revision */ + + uchar_t eeprom_size_tl; /* type/length of eeprom size field */ + uchar_t eeprom_size; /* size code for eeprom */ + uchar_t temp_waiver_tl; /* type/length of temp waiver field (0xC2) */ + char temp_waiver[2]; /* temp waiver */ + + + /* + * these fields only appear in main boards' EEPROMs + */ + uchar_t ekey_G_tl; /* type/length of encryption key "G" */ + uint32_t ekey_G; /* encryption key "G" */ + uchar_t ekey_P_tl; /* type/length of encryption key "P" */ + uint32_t ekey_P; /* encryption key "P" */ + uchar_t ekey_Y_tl; /* type/length of encryption key "Y" */ + uint32_t ekey_Y; /* encryption key "Y" */ + + + /* + * these fields are used for I bricks only + */ + uchar_t mac_addr_tl; /* type/length of MAC address */ + char mac_addr[12]; /* MAC address */ + uchar_t ieee1394_cfg_tl; /* type/length of IEEE 1394 info */ + uchar_t ieee1394_cfg[32]; /* IEEE 1394 config info */ + + + /* + * all boards have a checksum + */ + uchar_t checksum; + +} eeprom_board_ia_t; + +/* given a pointer to the three-byte little-endian EEPROM representation + * of date-of-manufacture, this function translates to a big-endian + * integer format + */ +int eeprom_xlate_board_mfr_date( uchar_t *src ); + + +/* EEPROM Serial Presence Detect record (used for DIMMs in IP35) + */ +typedef struct eeprom_spd_t +{ + /* 0*/ uchar_t spd_used; /* # of bytes written to serial memory by manufacturer */ + /* 1*/ uchar_t spd_size; /* Total # of bytes of SPD memory device */ + /* 2*/ uchar_t mem_type; /* Fundamental memory type (FPM, EDO, SDRAM..) */ + /* 3*/ uchar_t num_rows; /* # of row addresses on this assembly */ + /* 4*/ uchar_t num_cols; /* # Column Addresses on this assembly */ + /* 5*/ uchar_t mod_rows; /* # Module Rows on this assembly */ + /* 6*/ uchar_t data_width[2]; /* Data Width of this assembly (16b little-endian) */ + /* 8*/ uchar_t volt_if; /* Voltage interface standard of this assembly */ + /* 9*/ uchar_t cyc_time; /* SDRAM Cycle time, CL=X (highest CAS latency) */ + /* A*/ uchar_t acc_time; /* SDRAM Access from Clock (highest CAS latency) */ + /* B*/ uchar_t dimm_cfg; /* DIMM Configuration type (non-parity, ECC) */ + /* C*/ uchar_t refresh_rt; /* Refresh Rate/Type */ + /* D*/ uchar_t prim_width; /* Primary SDRAM Width */ + /* E*/ uchar_t ec_width; /* Error Checking SDRAM width */ + /* F*/ uchar_t min_delay; /* Min Clock Delay Back to Back Random Col Address */ + /*10*/ uchar_t burst_len; /* Burst Lengths Supported */ + /*11*/ uchar_t num_banks; /* # of Banks on Each SDRAM Device */ + /*12*/ uchar_t cas_latencies; /* CAS# Latencies Supported */ + /*13*/ uchar_t cs_latencies; /* CS# Latencies Supported */ + /*14*/ uchar_t we_latencies; /* Write Latencies Supported */ + /*15*/ uchar_t mod_attrib; /* SDRAM Module Attributes */ + /*16*/ uchar_t dev_attrib; /* SDRAM Device Attributes: General */ + /*17*/ uchar_t cyc_time2; /* Min SDRAM Cycle time at CL X-1 (2nd highest CAS latency) */ + /*18*/ uchar_t acc_time2; /* SDRAM Access from Clock at CL X-1 (2nd highest CAS latency) */ + /*19*/ uchar_t cyc_time3; /* Min SDRAM Cycle time at CL X-2 (3rd highest CAS latency) */ + /*1A*/ uchar_t acc_time3; /* Max SDRAM Access from Clock at CL X-2 (3nd highest CAS latency) */ + /*1B*/ uchar_t min_row_prechg; /* Min Row Precharge Time (Trp) */ + /*1C*/ uchar_t min_ra_to_ra; /* Min Row Active to Row Active (Trrd) */ + /*1D*/ uchar_t min_ras_to_cas; /* Min RAS to CAS Delay (Trcd) */ + /*1E*/ uchar_t min_ras_pulse; /* Minimum RAS Pulse Width (Tras) */ + /*1F*/ uchar_t row_density; /* Density of each row on module */ + /*20*/ uchar_t ca_setup; /* Command and Address signal input setup time */ + /*21*/ uchar_t ca_hold; /* Command and Address signal input hold time */ + /*22*/ uchar_t d_setup; /* Data signal input setup time */ + /*23*/ uchar_t d_hold; /* Data signal input hold time */ + + /*24*/ uchar_t pad0[26]; /* unused */ + + /*3E*/ uchar_t data_rev; /* SPD Data Revision Code */ + /*3F*/ uchar_t checksum; /* Checksum for bytes 0-62 */ + /*40*/ uchar_t jedec_id[8]; /* Manufacturer's JEDEC ID code */ + + /*48*/ uchar_t mfg_loc; /* Manufacturing Location */ + /*49*/ uchar_t part_num[18]; /* Manufacturer's Part Number */ + + /*5B*/ uchar_t rev_code[2]; /* Revision Code */ + + /*5D*/ uchar_t mfg_date[2]; /* Manufacturing Date */ + + /*5F*/ uchar_t ser_num[4]; /* Assembly Serial Number */ + + /*63*/ uchar_t manuf_data[27]; /* Manufacturer Specific Data */ + + /*7E*/ uchar_t intel_freq; /* Intel specification frequency */ + /*7F*/ uchar_t intel_100MHz; /* Intel spec details for 100MHz support */ + +} eeprom_spd_t; + + +#define EEPROM_SPD_RECORD_MAXLEN 256 + +typedef union eeprom_spd_u +{ + eeprom_spd_t fields; + char bytes[EEPROM_SPD_RECORD_MAXLEN]; + +} eeprom_spd_u; + + +/* EEPROM board record + */ +typedef struct eeprom_brd_record_t +{ + eeprom_chassis_ia_t *chassis_ia; + eeprom_board_ia_t *board_ia; + eeprom_spd_u *spd; + +} eeprom_brd_record_t; + + +/* End-of-fields marker + */ +#define EEPROM_EOF 0xc1 + + +/* masks for dissecting the type/length bytes + */ +#define FIELD_FORMAT_MASK 0xc0 +#define FIELD_LENGTH_MASK 0x3f + + +/* field format codes (used in type/length bytes) + */ +#define FIELD_FORMAT_BINARY 0x00 /* binary format */ +#define FIELD_FORMAT_BCD 0x40 /* BCD */ +#define FIELD_FORMAT_PACKED 0x80 /* packed 6-bit ASCII */ +#define FIELD_FORMAT_ASCII 0xC0 /* 8-bit ASCII */ + + + + +/* codes specifying brick and board type + */ +#define C_BRICK 0x100 + +#define C_PIMM (C_BRICK | 0x10) +#define C_PIMM_0 (C_PIMM) /* | 0x0 */ +#define C_PIMM_1 (C_PIMM | 0x1) + +#define C_DIMM (C_BRICK | 0x20) +#define C_DIMM_0 (C_DIMM) /* | 0x0 */ +#define C_DIMM_1 (C_DIMM | 0x1) +#define C_DIMM_2 (C_DIMM | 0x2) +#define C_DIMM_3 (C_DIMM | 0x3) +#define C_DIMM_4 (C_DIMM | 0x4) +#define C_DIMM_5 (C_DIMM | 0x5) +#define C_DIMM_6 (C_DIMM | 0x6) +#define C_DIMM_7 (C_DIMM | 0x7) + +#define R_BRICK 0x200 +#define R_POWER (R_BRICK | 0x10) + +#define VECTOR 0x300 /* used in vector ops when the destination + * could be a cbrick or an rbrick */ + +#define IO_BRICK 0x400 +#define IO_POWER (IO_BRICK | 0x10) + +#define BRICK_MASK 0xf00 +#define SUBORD_MASK 0xf0 /* AND with component specification; if the + the result is non-zero, then the component + is a subordinate board of some kind */ +#define COMPT_MASK 0xf /* if there's more than one instance of a + particular type of subordinate board, this + masks out which one we're talking about */ + + + +/* functions & macros for obtaining "NIC-like" strings from EEPROMs + */ + +int eeprom_str( char *nic_str, nasid_t nasid, int component ); +int vector_eeprom_str( char *nic_str, nasid_t nasid, + int component, net_vec_t path ); + +#define CBRICK_EEPROM_STR(s,n) eeprom_str((s),(n),C_BRICK) +#define IOBRICK_EEPROM_STR(s,n) eeprom_str((s),(n),IO_BRICK) +#define RBRICK_EEPROM_STR(s,n,p) vector_eeprom_str((s),(n),R_BRICK,p) +#define VECTOR_EEPROM_STR(s,n,p) vector_eeprom_str((s),(n),VECTOR,p) + + + +/* functions for obtaining formatted records from EEPROMs + */ + +int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, + int component ); +int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, + int component ); +int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid, + net_vec_t path, int component ); + + +/* functions providing unique id's for duplonet and i/o discovery + */ + +int cbrick_uid_get( nasid_t nasid, uint64_t *uid ); +int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid ); +int iobrick_uid_get( nasid_t nasid, uint64_t *uid ); + + +/* retrieve the ethernet MAC address for an I-brick + */ + +int ibrick_mac_addr_get( nasid_t nasid, char *eaddr ); + + +/* error codes + */ + +#define EEP_OK 0 +#define EEP_L1 1 +#define EEP_FAIL 2 +#define EEP_BAD_CHECKSUM 3 +#define EEP_NICIFY 4 +#define EEP_PARAM 6 +#define EEP_NOMEM 7 + + + +/* given a hardware graph vertex and an indication of the brick type, + * brick and board to be read, this functions reads the eeprom and + * attaches a "NIC"-format string of manufacturing information to the + * vertex. If the vertex already has the string, just returns the + * string. If component is not VECTOR or R_BRICK, the path parameter + * is ignored. + */ + +#ifdef IRIX +char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v, + net_vec_t path ); +#endif + + + +/* We may need to differentiate between an XBridge and other types of + * bridges during discovery to tell whether the bridge in question + * is part of an IO brick. The following function reads the WIDGET_ID + * register of the bridge under examination and returns a positive value + * if the part and mfg numbers stored there indicate that this widget + * is an XBridge (and so must be part of a brick). + */ +#ifdef IRIX +int is_iobrick( int nasid, int widget_num ); +#endif + +/* the following macro derives the widget number from the register + * address passed to it and uses is_iobrick to determine whether + * the widget in question is part of an SN1 IO brick. + */ +#ifdef IRIX +#define IS_IOBRICK(rg) is_iobrick( NASID_GET((rg)), SWIN_WIDGETNUM((rg)) ) +#else +#define IS_IOBRICK(rg) 1 +#endif + + + +/* macros for NIC compatability */ +/* always invoked on "this" cbrick */ +#define HUB_VERTEX_MFG_INFO(v) \ + eeprom_vertex_info_set( C_BRICK, get_nasid(), (v), 0 ) + +#define BRIDGE_VERTEX_MFG_INFO(v, r) \ + ( IS_IOBRICK((r)) ? eeprom_vertex_info_set \ + ( IO_BRICK, NASID_GET((r)), (v), 0 ) \ + : nic_bridge_vertex_info((v), (r)) ) + +#ifdef BRINGUP /* will we read mfg info from IOC3's that aren't + * part of IO7 cards, or aren't in I/O bricks? */ +#define IOC3_VERTEX_MFG_INFO(v, r, e) \ + eeprom_vertex_info_set( IO_IO7, NASID_GET((r)), (v), 0 ) +#endif /* BRINGUP */ + +#define HUB_UID_GET(n,v,p) cbrick_uid_get((n),(p)) +#define ROUTER_UID_GET(d,p) rbrick_uid_get(get_nasid(),(d),(p)) +#define XBOW_UID_GET(n,p) iobrick_uid_get((n),(p)) + +#endif /* _ASM_SN_EEPROM_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/gda.h linux-2.4.0-test12-lia/include/asm-ia64/sn/gda.h --- linux-2.4.0-test12/include/asm-ia64/sn/gda.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/gda.h Wed Dec 13 23:52:14 2000 @@ -0,0 +1,108 @@ +/* $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. + * + * Derived from IRIX . + * + * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. + * + * gda.h -- Contains the data structure for the global data area, + * The GDA contains information communicated between the + * PROM, SYMMON, and the kernel. + */ +#ifndef _ASM_SN_GDA_H +#define _ASM_SN_GDA_H + +#include + +#define GDA_MAGIC 0x58464552 + +/* + * GDA Version History + * + * Version # | Change + * -------------+------------------------------------------------------- + * 1 | Initial IP27 version + * 2 | Prom sets g_partid field to the partition number. 0 IS + * | a valid partition #. + */ + +#define GDA_VERSION 2 /* Current GDA version # */ + +#define G_MAGICOFF 0 +#define G_VERSIONOFF 4 +#define G_PROMOPOFF 6 +#define G_MASTEROFF 8 +#define G_VDSOFF 12 +#define G_HKDNORMOFF 16 +#define G_HKDUTLBOFF 24 +#define G_HKDXUTLBOFF 32 +#define G_PARTIDOFF 40 +#define G_TABLEOFF 128 + +#ifdef _LANGUAGE_C + +typedef struct gda { + u32 g_magic; /* GDA magic number */ + u16 g_version; /* Version of this structure */ + u16 g_masterid; /* The NASID:CPUNUM of the master cpu */ + u32 g_promop; /* Passes requests from the kernel to prom */ + u32 g_vds; /* Store the virtual dipswitches here */ + void **g_hooked_norm;/* ptr to pda loc for norm hndlr */ + void **g_hooked_utlb;/* ptr to pda loc for utlb hndlr */ + void **g_hooked_xtlb;/* ptr to pda loc for xtlb hndlr */ + int g_partid; /* partition id */ + int g_symmax; /* Max symbols in name table. */ + void *g_dbstab; /* Address of idbg symbol table */ + char *g_nametab; /* Address of idbg name table */ + void *g_ktext_repmask; + /* Pointer to a mask of nodes with copies + * of the kernel. */ + char g_padding[56]; /* pad out to 128 bytes */ + nasid_t g_nasidtable[MAX_COMPACT_NODES]; /* NASID of each node, + * indexed by cnodeid. + */ +} gda_t; + +#define GDA ((gda_t*) GDA_ADDR(get_nasid())) + +#endif /* __LANGUAGE_C */ +/* + * Define: PART_GDA_VERSION + * Purpose: Define the minimum version of the GDA required, lower + * revisions assume GDA is NOT set up, and read partition + * information from the board info. + */ +#define PART_GDA_VERSION 2 + +/* + * The following requests can be sent to the PROM during startup. + */ + +#define PROMOP_MAGIC 0x0ead0000 +#define PROMOP_MAGIC_MASK 0x0fff0000 + +#define PROMOP_BIST_SHIFT 11 +#define PROMOP_BIST_MASK (0x3 << 11) + +#define PROMOP_REG PI_ERR_STACK_ADDR_A + +#define PROMOP_INVALID (PROMOP_MAGIC | 0x00) +#define PROMOP_HALT (PROMOP_MAGIC | 0x10) +#define PROMOP_POWERDOWN (PROMOP_MAGIC | 0x20) +#define PROMOP_RESTART (PROMOP_MAGIC | 0x30) +#define PROMOP_REBOOT (PROMOP_MAGIC | 0x40) +#define PROMOP_IMODE (PROMOP_MAGIC | 0x50) + +#define PROMOP_CMD_MASK 0x00f0 +#define PROMOP_OPTIONS_MASK 0xfff0 + +#define PROMOP_SKIP_DIAGS 0x0100 /* don't bother running diags */ +#define PROMOP_SKIP_MEMINIT 0x0200 /* don't bother initing memory */ +#define PROMOP_SKIP_DEVINIT 0x0400 /* don't bother initing devices */ +#define PROMOP_BIST1 0x0800 /* keep track of which BIST ran */ +#define PROMOP_BIST2 0x1000 /* keep track of which BIST ran */ + +#endif /* _ASM_SN_GDA_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/hack.h linux-2.4.0-test12-lia/include/asm-ia64/sn/hack.h --- linux-2.4.0-test12/include/asm-ia64/sn/hack.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/hack.h Wed Dec 13 23:51:44 2000 @@ -0,0 +1,92 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +#ifndef _ASM_SN_HACK_H +#define _ASM_SN_HACK_H + +#include +#include /* for copy_??_user */ + +/****************************************** + * Definitions that do not exist in linux * + ******************************************/ + +typedef int cred_t; /* This is for compilation reasons */ +struct cred { int x; }; + +/* + * Hardware Graph routines that are currently stubbed! + */ +#include + +#define DELAY(a) +#define cpuid() 0 + +/************************************************ + * Routines redefined to use linux equivalents. * + ************************************************/ + +#define FIXME(s) printk("FIXME: [ %s ] in %s at %s:%d\n", s, __FUNCTION__, __FILE__, __LINE__) + +#define sv_init(a,b,c) FIXME("Fixme: sv_init : no-op") +#define sv_wait(a,b,c,d) FIXME("Fixme: sv_wait : no-op") +#define sv_broadcast(a) FIXME("Fixme: sv_broadcast : no-op") +#define sv_destroy(a) FIXME("Fixme: sv_destroy : no-op") + +extern devfs_handle_t dummy_vrtx; +#define cpuid_to_vertex(cpuid) dummy_vrtx /* (pdaindr[cpuid].pda->p_vertex) */ + +#define PUTBUF_LOCK(a) { FIXME("PUTBUF_LOCK"); } +#define PUTBUF_UNLOCK(a) { FIXME("PUTBUF_UNLOCK"); } +static inline int sv_signal(sv_t *a) {FIXME("sv_signal : return 0"); return (0); } + +#define cmn_err(x,y...) { FIXME("cmn_err : use printk"); printk(x y); } + +typedef int (*splfunc_t)(void); +extern int badaddr_val(volatile void *, int , volatile void *); + +extern int cap_able_cred(uint64_t a, uint64_t b); + +#define _CAP_CRABLE(cr,c) (cap_able_cred(cr,c)) +#define CAP_MEMORY_MGT (0x01LL << 25) +#define CAP_DEVICE_MGT (0x01LL << 37) + +#define io_splock(l) l +#define io_spunlock(l,s) + +/* move to stubs.c yet */ +#define spinlock_destroy(a) /* needed by pcibr_detach() */ +#define mutex_spinlock(a) 0 +#define mutex_spinunlock(a,b) +#define mutex_spinlock_spl(x,y) y +#define mutex_init(a,b,c) ; +#define mutex_lock(a,b) ; +#define mutex_unlock(a) ; +#define dev_to_vhdl(dev) 0 +#define get_timestamp() 0 +#define us_delay(a) +#define v_mapphys(a,b,c) printk("Fixme: v_mapphys - soft->base 0x%p\n", b); +#define splhi() 0 +#define spl7 splhi() +#define splx(s) +#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name); + +extern void * kmem_alloc_node(register size_t, register int, cnodeid_t); +extern void * kmem_zalloc(size_t, int); +extern void * kmem_zalloc_node(register size_t, register int, cnodeid_t ); +extern void * kmem_zone_alloc(register zone_t *, int); +extern zone_t * kmem_zone_init(register int , char *); +extern void kmem_zone_free(register zone_t *, void *); +extern int is_specified(char *); +extern int cap_able(uint64_t); +extern int compare_and_swap_ptr(void **, void *, void *); + +#endif /* _ASM_SN_HACK_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/hcl.h linux-2.4.0-test12-lia/include/asm-ia64/sn/hcl.h --- linux-2.4.0-test12/include/asm-ia64/sn/hcl.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/hcl.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,114 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_HCL_H +#define _ASM_SN_HCL_H + +extern spinlock_t hcl_spinlock; +extern devfs_handle_t hcl_handle; /* HCL driver */ +extern devfs_handle_t hwgraph_root; + + +typedef long labelcl_info_place_t; +typedef long arbitrary_info_t; +typedef long arb_info_desc_t; + +/* Support for INVENTORY */ +struct inventory_s; +struct invplace_s; +extern struct invplace_s invplace_none; + + +/* + * Reserve room in every vertex for 2 pieces of fast access indexed information + * Note that we do not save a pointer to the bdevsw or cdevsw[] tables anymore. + */ +#define HWGRAPH_NUM_INDEX_INFO 2 /* MAX Entries */ +#define HWGRAPH_CONNECTPT 0 /* connect point (aprent) */ +#define HWGRAPH_FASTINFO 1 /* callee's private handle */ + +/* + * Reserved edge_place_t values, used as the "place" parameter to edge_get_next. + * Every vertex in the hwgraph has up to 2 *implicit* edges. There is an implicit + * edge called "." that points to the current vertex. There is an implicit edge + * called ".." that points to the vertex' connect point. + */ +#define EDGE_PLACE_WANT_CURRENT 0 /* "." */ +#define EDGE_PLACE_WANT_CONNECTPT 1 /* ".." */ +#define EDGE_PLACE_WANT_REAL_EDGES 2 /* Get the first real edge */ +#define HWGRAPH_RESERVED_PLACES 2 + + +/* + * Special pre-defined edge labels. + */ +#define HWGRAPH_EDGELBL_HW "hw" +#define HWGRAPH_EDGELBL_DOT "." +#define HWGRAPH_EDGELBL_DOTDOT ".." +#define graph_edge_place_t uint + +/* + * External declarations of EXPORTED SYMBOLS in hcl.c + */ +extern devfs_handle_t hwgraph_register(devfs_handle_t, const char *, + unsigned int, unsigned int, unsigned int, unsigned int, + umode_t, uid_t, gid_t, struct file_operations *, void *); + +extern int hwgraph_mk_symlink(devfs_handle_t, const char *, unsigned int, + unsigned int, const char *, unsigned int, devfs_handle_t *, void *); + +extern int hwgraph_vertex_destroy(devfs_handle_t); + +extern int hwgraph_edge_add(devfs_handle_t, devfs_handle_t, char *); +extern int hwgraph_edge_get(devfs_handle_t, char *, devfs_handle_t *); + +extern arbitrary_info_t hwgraph_fastinfo_get(devfs_handle_t); +extern void hwgraph_fastinfo_set(devfs_handle_t, arbitrary_info_t ); +extern devfs_handle_t hwgraph_mk_dir(devfs_handle_t, const char *, unsigned int, void *); + +extern int hwgraph_connectpt_set(devfs_handle_t, devfs_handle_t); +extern devfs_handle_t hwgraph_connectpt_get(devfs_handle_t); +extern int hwgraph_edge_get_next(devfs_handle_t, char *, devfs_handle_t *, uint *); +extern graph_error_t hwgraph_edge_remove(devfs_handle_t, char *, devfs_handle_t *); + +extern graph_error_t hwgraph_traverse(devfs_handle_t, char *, devfs_handle_t *); + +extern int hwgraph_vertex_get_next(devfs_handle_t *, devfs_handle_t *); +extern int hwgraph_inventory_get_next(devfs_handle_t, invplace_t *, + inventory_t **); +extern int hwgraph_inventory_add(devfs_handle_t, int, int, major_t, minor_t, int); +extern int hwgraph_inventory_remove(devfs_handle_t, int, int, major_t, minor_t, int); +extern int hwgraph_controller_num_get(devfs_handle_t); +extern void hwgraph_controller_num_set(devfs_handle_t, int); +extern int hwgraph_path_ad(devfs_handle_t, char *, devfs_handle_t *); +extern devfs_handle_t hwgraph_path_to_vertex(char *); +extern devfs_handle_t hwgraph_path_to_dev(char *); +extern devfs_handle_t hwgraph_block_device_get(devfs_handle_t); +extern devfs_handle_t hwgraph_char_device_get(devfs_handle_t); +extern graph_error_t hwgraph_char_device_add(devfs_handle_t, char *, char *, devfs_handle_t *); +extern int hwgraph_path_add(devfs_handle_t, char *, devfs_handle_t *); +extern struct file_operations * hwgraph_bdevsw_get(devfs_handle_t); +extern int hwgraph_info_add_LBL(devfs_handle_t, char *, arbitrary_info_t); +extern int hwgraph_info_get_LBL(devfs_handle_t, char *, arbitrary_info_t *); +extern int hwgraph_info_replace_LBL(devfs_handle_t, char *, arbitrary_info_t, + arbitrary_info_t *); +extern int hwgraph_info_get_exported_LBL(devfs_handle_t, char *, int *, arbitrary_info_t *); +extern int hwgraph_info_get_next_LBL(devfs_handle_t, char *, arbitrary_info_t *, + labelcl_info_place_t *); + +extern int hwgraph_path_lookup(devfs_handle_t, char *, devfs_handle_t *, char **); +extern int hwgraph_info_export_LBL(devfs_handle_t, char *, int); +extern int hwgraph_info_unexport_LBL(devfs_handle_t, char *); +extern int hwgraph_info_remove_LBL(devfs_handle_t, char *, arbitrary_info_t *); +extern char * vertex_to_name(devfs_handle_t, char *, uint); +extern graph_error_t hwgraph_vertex_unref(devfs_handle_t); + + + +#endif /* _ASM_SN_HCL_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/hcl_util.h linux-2.4.0-test12-lia/include/asm-ia64/sn/hcl_util.h --- linux-2.4.0-test12/include/asm-ia64/sn/hcl_util.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/hcl_util.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,24 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_HCL_UTIL_H +#define _ASM_SN_HCL_UTIL_H + +extern char * dev_to_name(devfs_handle_t, char *, uint); +extern int device_master_set(devfs_handle_t, devfs_handle_t); +extern devfs_handle_t device_master_get(devfs_handle_t); +extern cnodeid_t master_node_get(devfs_handle_t); +extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t); +extern void mark_nodevertex_as_node(devfs_handle_t, cnodeid_t); +extern void device_info_set(devfs_handle_t, void *); +extern void *device_info_get(devfs_handle_t); + + +#endif _ASM_SN_HCL_UTIL_H diff -urN linux-2.4.0-test12/include/asm-ia64/sn/hubspc.h linux-2.4.0-test12-lia/include/asm-ia64/sn/hubspc.h --- linux-2.4.0-test12/include/asm-ia64/sn/hubspc.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/hubspc.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,25 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_HUBSPC_H +#define _ASM_SN_HUBSPC_H + +typedef enum { + HUBSPC_REFCOUNTERS, + HUBSPC_PROM +} hubspc_subdevice_t; + + +/* + * Reference Counters + */ + +extern int refcounters_attach(devfs_handle_t hub); + +#endif /* _ASM_SN_HUBSPC_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/hwcntrs.h linux-2.4.0-test12-lia/include/asm-ia64/sn/hwcntrs.h --- linux-2.4.0-test12/include/asm-ia64/sn/hwcntrs.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/hwcntrs.h Wed Dec 6 21:56:07 2000 @@ -0,0 +1,98 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_HWCNTRS_H +#define _ASM_SN_HWCNTRS_H + + +typedef uint64_t refcnt_t; + +#define SN0_REFCNT_MAX_COUNTERS 64 + +typedef struct sn0_refcnt_set { + refcnt_t refcnt[SN0_REFCNT_MAX_COUNTERS]; + uint64_t flags; + uint64_t reserved[4]; +} sn0_refcnt_set_t; + +typedef struct sn0_refcnt_buf { + sn0_refcnt_set_t refcnt_set; + uint64_t paddr; + uint64_t page_size; + cnodeid_t cnodeid; /* cnodeid + pad[3] use 64 bits */ + uint16_t pad[3]; + uint64_t reserved[4]; +} sn0_refcnt_buf_t; + +typedef struct sn0_refcnt_args { + uint64_t vaddr; + uint64_t len; + sn0_refcnt_buf_t* buf; + uint64_t reserved[4]; +} sn0_refcnt_args_t; + +/* + * Info needed by the user level program + * to mmap the refcnt buffer + */ + +#define RCB_INFO_GET 1 +#define RCB_SLOT_GET 2 + +typedef struct rcb_info { + uint64_t rcb_len; /* total refcnt buffer len in bytes */ + + int rcb_sw_sets; /* number of sw counter sets in buffer */ + int rcb_sw_counters_per_set; /* sw counters per set -- numnodes */ + int rcb_sw_counter_size; /* sizeof(refcnt_t) -- size of sw cntr */ + + int rcb_base_pages; /* number of base pages in node */ + int rcb_base_page_size; /* sw base page size */ + uint64_t rcb_base_paddr; /* base physical address for this node */ + + int rcb_cnodeid; /* cnodeid for this node */ + int rcb_granularity; /* hw page size used for counter sets */ + uint rcb_hw_counter_max; /* max hwcounter count (width mask) */ + int rcb_diff_threshold; /* current node differential threshold */ + int rcb_abs_threshold; /* current node absolute threshold */ + int rcb_num_slots; /* physmem slots */ + + int rcb_reserved[512]; + +} rcb_info_t; + +typedef struct rcb_slot { + uint64_t base; + uint64_t size; +} rcb_slot_t; + +#if defined(__KERNEL__) +// #include +typedef struct sn0_refcnt_args_32 { + uint64_t vaddr; + uint64_t len; + app32_ptr_t buf; + uint64_t reserved[4]; +} sn0_refcnt_args_32_t; + +/* Defines and Macros */ +/* A set of reference counts are for 4k bytes of physical memory */ +#define NBPREFCNTP 0x1000 +#define BPREFCNTPSHIFT 12 +#define bytes_to_refcntpages(x) (((__psunsigned_t)(x)+(NBPREFCNTP-1))>>BPREFCNTPSHIFT) +#define refcntpage_offset(x) ((__psunsigned_t)(x)&((NBPP-1)&~(NBPREFCNTP-1))) +#define align_to_refcntpage(x) ((__psunsigned_t)(x)&(~(NBPREFCNTP-1))) + +extern void migr_refcnt_read(sn0_refcnt_buf_t*); +extern void migr_refcnt_read_extended(sn0_refcnt_buf_t*); +extern int migr_refcnt_enabled(void); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SN_HWCNTRS_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/intr.h linux-2.4.0-test12-lia/include/asm-ia64/sn/intr.h --- linux-2.4.0-test12/include/asm-ia64/sn/intr.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/intr.h Wed Dec 13 19:35:00 2000 @@ -0,0 +1,250 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_INTR_H +#define _ASM_SN_INTR_H + +/* Number of interrupt levels associated with each interrupt register. */ +#define N_INTPEND_BITS 64 + +#define INT_PEND0_BASELVL 0 +#define INT_PEND1_BASELVL 64 + +#define N_INTPENDJUNK_BITS 8 +#define INTPENDJUNK_CLRBIT 0x80 + +#include + +#if LANGUAGE_C + +#if defined(CONFIG_IA64_SGI_IO) + +#define II_NAMELEN 24 + +/* + * Dispatch table entry - contains information needed to call an interrupt + * routine. + */ +typedef struct intr_vector_s { + intr_func_t iv_func; /* Interrupt handler function */ + intr_func_t iv_prefunc; /* Interrupt handler prologue func */ + void *iv_arg; /* Argument to pass to handler */ +#ifdef IRIX + thd_int_t iv_tinfo; /* Thread info */ +#endif + cpuid_t iv_mustruncpu; /* Where we must run. */ +} intr_vector_t; + +/* Interrupt information table. */ +typedef struct intr_info_s { + xtalk_intr_setfunc_t ii_setfunc; /* Function to set the interrupt + * destination and level register. + * It returns 0 (success) or an + * error code. + */ + void *ii_cookie; /* arg passed to setfunc */ + devfs_handle_t ii_owner_dev; /* device that owns this intr */ + char ii_name[II_NAMELEN]; /* Name of this intr. */ + int ii_flags; /* informational flags */ +} intr_info_t; + +#define iv_tflags iv_tinfo.thd_flags +#define iv_isync iv_tinfo.thd_isync +#define iv_lat iv_tinfo.thd_latstats +#define iv_thread iv_tinfo.thd_ithread +#define iv_pri iv_tinfo.thd_pri + +#define THD_CREATED 0x00000001 /* + * We've created a thread for this + * interrupt. + */ + +/* + * Bits for ii_flags: + */ +#define II_UNRESERVE 0 +#define II_RESERVE 1 /* Interrupt reserved. */ +#define II_INUSE 2 /* Interrupt connected */ +#define II_ERRORINT 4 /* INterrupt is an error condition */ +#define II_THREADED 8 /* Interrupt handler is threaded. */ + +/* + * Interrupt level wildcard + */ +#define INTRCONNECT_ANYBIT -1 + +/* + * This structure holds information needed both to call and to maintain + * interrupts. The two are in separate arrays for the locality benefits. + * Since there's only one set of vectors per hub chip (but more than one + * CPU, the lock to change the vector tables must be here rather than in + * the PDA. + */ + +typedef struct intr_vecblk_s { + intr_vector_t vectors[N_INTPEND_BITS]; /* information needed to + call an intr routine. */ + intr_info_t info[N_INTPEND_BITS]; /* information needed only + to maintain interrupts. */ + lock_t vector_lock; /* Lock for this and the + masks in the PDA. */ + splfunc_t vector_spl; /* vector_lock req'd spl */ + int vector_state; /* Initialized to zero. + Set to INTR_INITED + by hubintr_init. + */ + int vector_count; /* Number of vectors + * reserved. + */ + int cpu_count[CPUS_PER_SUBNODE]; /* How many interrupts are + * connected to each CPU + */ + int ithreads_enabled; /* Are interrupt threads + * initialized on this node. + * and block? + */ +} intr_vecblk_t; + +/* Possible values for vector_state: */ +#define VECTOR_UNINITED 0 +#define VECTOR_INITED 1 +#define VECTOR_SET 2 + +#define hub_intrvect0 private.p_intmasks.dispatch0->vectors +#define hub_intrvect1 private.p_intmasks.dispatch1->vectors +#define hub_intrinfo0 private.p_intmasks.dispatch0->info +#define hub_intrinfo1 private.p_intmasks.dispatch1->info + +#endif /* CONFIG_IA64_SGI_IO */ + +/* + * Macros to manipulate the interrupt register on the calling hub chip. + */ + +#define LOCAL_HUB_SEND_INTR(_level) LOCAL_HUB_S(PI_INT_PEND_MOD, \ + (0x100|(_level))) +#if defined(CONFIG_IA64_SGI_IO) +#define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \ + REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level))) + +#define REMOTE_CPU_SEND_INTR(_cpuid, _level) \ + REMOTE_HUB_PI_S(cputonasid(_cpuid), \ + SUBNODE(cputoslice(_cpuid)), \ + PI_INT_PEND_MOD, (0x100|(_level))) +#endif /* CONFIG_IA64_SGI_IO*/ + +/* + * When clearing the interrupt, make sure this clear does make it + * to the hub. Otherwise we could end up losing interrupts. + * We do an uncached load of the int_pend0 register to ensure this. + */ + +#define LOCAL_HUB_CLR_INTR(_level) \ + LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)), \ + LOCAL_HUB_L(PI_INT_PEND0) +#define REMOTE_HUB_PI_CLR_INTR(_hub, _sn, _level) \ + REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)), \ + REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0) + +#if defined(CONFIG_IA64_SGI_IO) +/* Special support for use by gfx driver only. Supports special gfx hub interrupt. */ +extern void install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg); + +void setrtvector(intr_func_t func); + +/* + * Interrupt blocking + */ +extern void intr_block_bit(cpuid_t cpu, int bit); +extern void intr_unblock_bit(cpuid_t cpu, int bit); +#endif /* CONFIG_IA64_SGI_IO */ + +#endif /* LANGUAGE_C */ + +/* + * Hard-coded interrupt levels: + */ + +/* + * L0 = SW1 + * L1 = SW2 + * L2 = INT_PEND0 + * L3 = INT_PEND1 + * L4 = RTC + * L5 = Profiling Timer + * L6 = Hub Errors + * L7 = Count/Compare (T5 counters) + */ + + +/* INT_PEND0 hard-coded bits. */ +#ifdef DEBUG_INTR_TSTAMP +/* hard coded interrupt level for interrupt latency test interrupt */ +#define CPU_INTRLAT_B 62 +#define CPU_INTRLAT_A 61 +#endif + +/* Hardcoded bits required by software. */ +#define MSC_MESG_INTR 9 +#define CPU_ACTION_B 8 +#define CPU_ACTION_A 7 + +/* These are determined by hardware: */ +#define CC_PEND_B 6 +#define CC_PEND_A 5 +#define UART_INTR 4 +#define PG_MIG_INTR 3 +#define GFX_INTR_B 2 +#define GFX_INTR_A 1 +#define RESERVED_INTR 0 + +/* INT_PEND1 hard-coded bits: */ +#define MSC_PANIC_INTR 63 +#define NI_ERROR_INTR 62 +#define MD_COR_ERR_INTR 61 +#define COR_ERR_INTR_B 60 +#define COR_ERR_INTR_A 59 +#define CLK_ERR_INTR 58 + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +# define NACK_INT_B 57 +# define NACK_INT_A 56 +# define LB_ERROR 55 +# define XB_ERROR 54 +#else + << BOMB! >> Must define IP27 or IP35 or IP37 +#endif + +#define BRIDGE_ERROR_INTR 53 /* Setup by PROM to catch Bridge Errors */ + +#define IP27_INTR_0 52 /* Reserved for PROM use */ +#define IP27_INTR_1 51 /* (do not use in Kernel) */ +#define IP27_INTR_2 50 +#define IP27_INTR_3 49 +#define IP27_INTR_4 48 +#define IP27_INTR_5 47 +#define IP27_INTR_6 46 +#define IP27_INTR_7 45 + +#define TLB_INTR_B 44 /* used for tlb flush random */ +#define TLB_INTR_A 43 + +#define LLP_PFAIL_INTR_B 42 /* see ml/SN/SN0/sysctlr.c */ +#define LLP_PFAIL_INTR_A 41 + +#define NI_BRDCAST_ERR_B 40 +#define NI_BRDCAST_ERR_A 39 + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +# define IO_ERROR_INTR 38 /* set up by prom */ +# define DEBUG_INTR_B 37 /* used by symmon to stop all cpus */ +# define DEBUG_INTR_A 36 +#endif + +#endif /* _ASM_SN_INTR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/intr_public.h linux-2.4.0-test12-lia/include/asm-ia64/sn/intr_public.h --- linux-2.4.0-test12/include/asm-ia64/sn/intr_public.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/intr_public.h Wed Dec 13 19:35:00 2000 @@ -0,0 +1,59 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef __SYS_SN_INTR_PUBLIC_H__ +#define __SYS_SN_INTR_PUBLIC_H__ + + +/* REMEMBER: If you change these, the whole world needs to be recompiled. + * It would also require changing the hubspl.s code and SN0/intr.c + * Currently, the spl code has no support for multiple INTPEND1 masks. + */ + +#define N_INTPEND0_MASKS 1 +#define N_INTPEND1_MASKS 1 + +#define INTPEND0_MAXMASK (N_INTPEND0_MASKS - 1) +#define INTPEND1_MAXMASK (N_INTPEND1_MASKS - 1) + +#if _LANGUAGE_C +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif +#include + +struct intr_vecblk_s; /* defined in asm/sn/intr.h */ + +/* + * The following are necessary to create the illusion of a CEL + * on the IP27 hub. We'll add more priority levels soon, but for + * now, any interrupt in a particular band effectively does an spl. + * These must be in the PDA since they're different for each processor. + * Users of this structure must hold the vector_lock in the appropriate vector + * block before modifying the mask arrays. There's only one vector block + * for each Hub so a lock in the PDA wouldn't be adequate. + */ +typedef struct hub_intmasks_s { + /* + * The masks are stored with the lowest-priority (most inclusive) + * in the lowest-numbered masks (i.e., 0, 1, 2...). + */ + /* INT_PEND0: */ + hubreg_t intpend0_masks[N_INTPEND0_MASKS]; + /* INT_PEND1: */ + hubreg_t intpend1_masks[N_INTPEND1_MASKS]; + /* INT_PEND0: */ + struct intr_vecblk_s *dispatch0; + /* INT_PEND1: */ + struct intr_vecblk_s *dispatch1; +} hub_intmasks_t; + +#endif /* _LANGUAGE_C */ +#endif /* __SYS_SN_INTR_PUBLIC_H__ */ + diff -urN linux-2.4.0-test12/include/asm-ia64/sn/invent.h linux-2.4.0-test12-lia/include/asm-ia64/sn/invent.h --- linux-2.4.0-test12/include/asm-ia64/sn/invent.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/invent.h Wed Dec 6 21:56:08 2000 @@ -0,0 +1,684 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_INVENT_H +#define _ASM_SN_INVENT_H + +/* + * sys/sn/invent.h -- Kernel Hardware Inventory + * + * As the system boots, a list of recognized devices is assembled. + * This list can then be accessed through syssgi() by user-level programs + * so that they can learn about available peripherals and the system's + * hardware configuration. + * + * The data is organized into a linked list of structures that are composed + * of an inventory item class and a class-specific type. Each instance may + * also specify a 32-bit "state" which might be size, readiness, or + * anything else that's relevant. + * + */ + +#define major_t int +#define minor_t int +#define app32_ptr_t unsigned long +#define graph_vertex_place_t long +#define GRAPH_VERTEX_NONE ((devfs_handle_t)-1) + +typedef struct inventory_s { + struct inventory_s *inv_next; /* next inventory record in list */ + int inv_class; /* class of object */ + int inv_type; /* class sub-type of object */ + major_t inv_controller; /* object major identifier */ + minor_t inv_unit; /* object minor identifier */ + int inv_state; /* information specific to object or + class */ +} inventory_t; + +typedef struct cpu_inv_s { + int cpuflavor; /* differentiate processor */ + int cpufq; /* cpu frequency */ + int sdsize; /* secondary data cache size */ + int sdfreq; /* speed of the secondary cache */ +} cpu_inv_t; + + +typedef struct diag_inv_s{ + char name[80]; + int diagval; + int physid; + int virtid; +} diag_inv_t; + + +typedef struct router_inv_s{ + char portmap[80]; /* String indicating which ports int/ext */ + char type[40]; /* String name: e.g. "star", "meta", etc. */ + int freq; /* From hub */ + int rev; /* From hub */ +} router_inv_t; + + +/* + * NOTE: This file is a central registry for inventory IDs for each + * class of inventory object. It is important to keep the central copy + * of this file up-to-date with the work going on in various engineering + * projects. When making changes to this file in an engineering project + * tree, please make those changes separately from any others and then + * merge the changes to this file into the main line trees in order to + * prevent other engineering projects from conflicting with your ID + * allocations. + */ + + +/* Inventory Classes */ +/* when adding a new class, add also to classes[] in hinv.c */ +#define INV_PROCESSOR 1 +#define INV_DISK 2 +#define INV_MEMORY 3 +#define INV_SERIAL 4 +#define INV_PARALLEL 5 +#define INV_TAPE 6 +#define INV_GRAPHICS 7 +#define INV_NETWORK 8 +#define INV_SCSI 9 /* SCSI devices other than disk and tape */ +#define INV_AUDIO 10 +#define INV_IOBD 11 +#define INV_VIDEO 12 +#define INV_BUS 13 +#define INV_MISC 14 /* miscellaneous: a catchall */ +/*** add post-5.2 classes here for backward compatibility ***/ +#define INV_COMPRESSION 15 +#define INV_VSCSI 16 /* SCSI devices on jag other than disk and tape */ +#define INV_DISPLAY 17 +#define INV_UNC_SCSILUN 18 /* Unconnected SCSI lun */ +#define INV_PCI 19 /* PCI Bus */ +#define INV_PCI_NO_DRV 20 /* PCI Bus without any driver */ +#define INV_PROM 21 /* Different proms in the system */ +#define INV_IEEE1394 22 /* IEEE1394 devices */ +#define INV_RPS 23 /* redundant power source */ +#define INV_TPU 24 /* Tensor Processing Unit */ +#define INV_FCNODE 25 /* Helper class for SCSI classes, not in classes[] */ + +/* types for class processor */ +#define INV_CPUBOARD 1 +#define INV_CPUCHIP 2 +#define INV_FPUCHIP 3 +#define INV_CCSYNC 4 /* CC Rev 2+ sync join counter */ + +/* states for cpu and fpu chips are revision numbers */ + +/* cpuboard states */ +#define INV_IP20BOARD 10 +#define INV_IP19BOARD 11 +#define INV_IP22BOARD 12 +#define INV_IP21BOARD 13 +#define INV_IP26BOARD 14 +#define INV_IP25BOARD 15 +#define INV_IP30BOARD 16 +#define INV_IP28BOARD 17 +#define INV_IP32BOARD 18 +#define INV_IP27BOARD 19 +#define INV_IPMHSIMBOARD 20 +#define INV_IP33BOARD 21 +#define INV_IP35BOARD 22 + +/* types for class INV_IOBD */ +#define INV_EVIO 2 /* EVEREST I/O board */ +#define INV_O200IO 3 /* Origin 200 base I/O */ + +/* IO board types for origin2000 for class INV_IOBD*/ + +#define INV_O2000BASEIO 0x21 +#define INV_O2000MSCSI 0x22 +#define INV_O2000MENET 0x23 +#define INV_O2000HIPPI 0x24 +#define INV_O2000GFX 0x25 +#define INV_O2000HAROLD 0x26 +#define INV_O2000VME 0x27 +#define INV_O2000MIO 0x28 +#define INV_O2000FC 0x29 +#define INV_O2000LINC 0x2a + +#define INV_PCIADAP 4 +/* states for class INV_IOBD type INV_EVERESTIO -- value of eb_type field */ +#define INV_IO4_REV1 0x21 + +/* types for class disk */ +/* NB: types MUST be unique within a class. + Please check this if adding new types. */ + +#define INV_SCSICONTROL 1 +#define INV_SCSIDRIVE 2 +#define INV_SCSIFLOPPY 5 /* also cdroms, optical disks, etc. */ +#define INV_JAGUAR 16 /* Interphase Jaguar */ +#define INV_VSCSIDRIVE 17 /* Disk connected to Jaguar */ +#define INV_GIO_SCSICONTROL 18 /* optional GIO SCSI controller */ +#define INV_SCSIRAID 19 /* SCSI attached RAID */ +#define INV_XLVGEN 20 /* Generic XLV disk device */ +#define INV_PCCARD 21 /* PC-card (PCMCIA) devices */ +#define INV_PCI_SCSICONTROL 22 /* optional PCI SCSI controller */ + +/* states for INV_SCSICONTROL disk type; indicate which chip rev; + * for 93A and B, unit field has microcode rev. */ +#define INV_WD93 0 /* WD 33C93 */ +#define INV_WD93A 1 /* WD 33C93A */ +#define INV_WD93B 2 /* WD 33C93B */ +#define INV_WD95A 3 /* WD 33C95A */ +#define INV_SCIP95 4 /* SCIP with a WD 33C95A */ +#define INV_ADP7880 5 /* Adaptec 7880 (single channel) */ +#define INV_QL_REV1 6 /* qlogic 1040 */ +#define INV_QL_REV2 7 /* qlogic 1040A */ +#define INV_QL_REV2_4 8 /* qlogic 1040A rev 4 */ +#define INV_QL_REV3 9 /* qlogic 1040B */ +#define INV_FCADP 10 /* Adaptec Emerald Fibrechannel */ +#define INV_QL_REV4 11 /* qlogic 1040B rev 2 */ +#define INV_QL 12 /* Unknown QL version */ +#define INV_QL_1240 13 /* qlogic 1240 */ +#define INV_QL_1080 14 /* qlogic 1080 */ +#define INV_QL_1280 15 /* qlogic 1280 */ +#define INV_QL_10160 16 /* qlogic 10160 */ +#define INV_QL_12160 17 /* qlogic 12160 */ +#define INV_QL_2100 18 /* qLogic 2100 Fibrechannel */ +#define INV_QL_2200 19 /* qLogic 2200 Fibrechannel */ +#define INV_SBP2 20 /* SBP2 protocol over OHCI on 1394 */ + + + +/* states for INV_SCSIDRIVE type of class disk */ +#define INV_RAID5_LUN 0x100 +#define INV_PRIMARY 0x200 /* primary path */ +#define INV_ALTERNATE 0x400 /* alternate path */ +#define INV_FAILED 0x800 /* path has failed */ +#define INV_XVMVOL 0x1000 /* disk is managed by XVM */ + +/* states for INV_SCSIFLOPPY type of class disk */ +#define INV_TEAC_FLOPPY 1 /* TEAC 3 1/2 inch floppy drive */ +#define INV_INSITE_FLOPPY 2 /* INSITE, IOMEGA Io20S, SyQuest floppy drives */ + +/* END OF CLASS DISK TYPES */ + +/* types for class memory */ +/* NB. the states for class memory are sizes in bytes */ +#define INV_MAIN 1 +#define INV_DCACHE 3 +#define INV_ICACHE 4 +#define INV_WBUFFER 5 +#define INV_SDCACHE 6 +#define INV_SICACHE 7 +#define INV_SIDCACHE 8 +#define INV_MAIN_MB 9 +#define INV_HUBSPC 10 /* HUBSPC */ + +/* types for class serial */ +#define INV_CDSIO 1 /* Central Data serial board */ +#define INV_T3270 2 /* T3270 emulation */ +#define INV_GSE 3 /* SpectraGraphics Gerbil coax cable */ +#define INV_SI 4 /* SNA SDLC controller */ +#define INV_M333X25 6 /* X.25 controller */ +#define INV_CDSIO_E 7 /* Central Data serial board on E space */ +#define INV_ONBOARD 8 /* Serial ports per CPU board */ +#define INV_EPC_SERIAL 9 /* EVEREST I/O EPC serial port */ +#define INV_ICA 10 /* IRIS (IBM) Channel Adapter card */ +#define INV_VSC 11 /* SBE VME Synch Comm board */ +#define INV_ISC 12 /* SBE ISA Synch Comm board */ +#define INV_GSC 13 /* SGI GIO Synch Comm board */ +#define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ +#define INV_PSC 15 /* SBE PCI Synch Comm board */ +#define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ +#define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ +#define INV_INVISIBLE 18 /* invisible inventory entry for kernel use */ +#define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ + +/* types for class parallel */ +#define INV_GPIB 2 /* National Instrument GPIB board */ +#define INV_GPIB_E 3 /* National Instrument GPIB board on E space*/ +#define INV_EPC_PLP 4 /* EVEREST I/O EPC Parallel Port */ +#define INV_ONBOARD_PLP 5 /* Integral parallel port, + state = 0 -> output only + state = 1 -> bi-directional */ +#define INV_EPP_ECP_PLP 6 /* Integral EPP/ECP parallel port */ +#define INV_EPP_PFD 7 /* External EPP parallel peripheral */ + +/* types for class tape */ +#define INV_SCSIQIC 1 /* Any SCSI tape, not just QIC{24,150}... */ +#define INV_VSCSITAPE 4 /* SCSI tape connected to Jaguar */ + +/* sub types for type INV_SCSIQIC and INV_VSCSITAPE (in state) */ +#define TPUNKNOWN 0 /* type not known */ +#define TPQIC24 1 /* QIC24 1/4" cartridge */ +#define TPDAT 2 /* 4mm Digital Audio Tape cartridge */ +#define TPQIC150 3 /* QIC150 1/4" cartridge */ +#define TP9TRACK 4 /* 9 track reel */ +#define TP8MM_8200 5 /* 8 mm video tape cartridge */ +#define TP8MM_8500 6 /* 8 mm video tape cartridge */ +#define TPQIC1000 7 /* QIC1000 1/4" cartridge */ +#define TPQIC1350 8 /* QIC1350 1/4" cartridge */ +#define TP3480 9 /* 3480 compatible cartridge */ +#define TPDLT 10 /* DEC Digital Linear Tape cartridge */ +#define TPD2 11 /* D2 tape cartridge */ +#define TPDLTSTACKER 12 /* DEC Digital Linear Tape stacker */ +#define TPNTP 13 /* IBM Magstar 3590 Tape Device cartridge */ +#define TPNTPSTACKER 14 /* IBM Magstar 3590 Tape Device stacker */ +#define TPSTK9490 15 /* StorageTeK 9490 */ +#define TPSTKSD3 16 /* StorageTeK SD3 */ +#define TPGY10 17 /* Sony GY-10 */ +#define TP8MM_8900 18 /* 8 mm (AME) tape cartridge */ +#define TPMGSTRMP 19 /* IBM Magster MP 3570 cartridge */ +#define TPMGSTRMPSTCKR 20 /* IBM Magstar MP stacker */ +#define TPSTK4791 21 /* StorageTek 4791 */ +#define TPSTK4781 22 /* StorageTek 4781 */ +#define TPFUJDIANA1 23 /* Fujitsu Diana-1 (M1016/M1017) */ +#define TPFUJDIANA2 24 /* Fujitsu Diana-2 (M2483) */ +#define TPFUJDIANA3 25 /* Fujitsu Diana-3 (M2488) */ +#define TP8MM_AIT 26 /* Sony AIT format tape */ +#define TPTD3600 27 /* Philips TD3600 */ +#define TPTD3600STCKR 28 /* Philips TD3600 stacker */ +#define TPNCTP 29 /* Philips NCTP */ +#define TPGY2120 30 /* Sony GY-2120 (replaces GY-10) */ +#define TPOVL490E 31 /* Overland Data L490E (3490E compatible) */ +#define TPSTK9840 32 /* StorageTeK 9840 (aka Eagle) */ + +/* Diagnostics inventory */ +#define INV_CPUDIAGVAL 70 + + +/* + * GFX invent is a subset of gfxinfo + */ + +/* types for class graphics */ +#define INV_GR1BOARD 1 /* GR1 (Eclipse) graphics */ +#define INV_GR1BP 2 /* OBSOLETE - use INV_GR1BIT24 instead */ +#define INV_GR1ZBUFFER 3 /* OBSOLETE - use INV_GR1ZBUF24 instead */ +#define INV_GRODEV 4 /* Clover1 graphics */ +#define INV_GMDEV 5 /* GT graphics */ +#define INV_CG2 6 /* CG2 composite video/genlock board */ +#define INV_VMUXBOARD 7 /* VMUX video mux board */ +#define INV_VGX 8 /* VGX (PowerVision) graphics */ +#define INV_VGXT 9 /* VGXT (PowerVision) graphics with IMP5s. */ +#define INV_LIGHT 10 /* LIGHT graphics */ +#define INV_GR2 11 /* EXPRESS graphics */ +#define INV_RE 12 /* RealityEngine graphics */ +#define INV_VTX 13 /* RealityEngine graphics - VTX variant */ +#define INV_NEWPORT 14 /* Newport graphics */ +#define INV_MGRAS 15 /* Mardigras graphics */ +#define INV_IR 16 /* InfiniteReality graphics */ +#define INV_CRIME 17 /* Moosehead on board CRIME graphics */ +#define INV_IR2 18 /* InfiniteReality2 graphics */ +#define INV_IR2LITE 19 /* Reality graphics */ +#define INV_IR2E 20 /* InfiniteReality2e graphics */ +#define INV_ODSY 21 /* Odyssey graphics */ +#define INV_IR3 22 /* InfiniteReality3 graphics */ + +/* states for graphics class GR1 */ +#define INV_GR1REMASK 0x7 /* RE version */ +#define INV_GR1REUNK 0x0 /* RE version unknown */ +#define INV_GR1RE1 0x1 /* RE1 */ +#define INV_GR1RE2 0x2 /* RE2 */ +#define INV_GR1BUSMASK 0x38 /* GR1 bus architecture */ +#define INV_GR1PB 0x00 /* Eclipse private bus */ +#define INV_GR1PBVME 0x08 /* VGR2 board VME and private bus interfaces */ +#define INV_GR1TURBO 0x40 /* has turbo option */ +#define INV_GR1BIT24 0x80 /* has bitplane option */ +#define INV_GR1ZBUF24 0x100 /* has z-buffer option */ +#define INV_GR1SMALLMON 0x200 /* using 14" monitor */ +#define INV_GR1SMALLMAP 0x400 /* has 256 entry color map */ +#define INV_GR1AUX4 0x800 /* has AUX/WID plane option */ + +/* states for graphics class GR2 */ + /* bitmasks */ +#define INV_GR2_Z 0x1 /* has z-buffer option */ +#define INV_GR2_24 0x2 /* has bitplane option */ +#define INV_GR2_4GE 0x4 /* has 4 GEs */ +#define INV_GR2_1GE 0x8 /* has 1 GEs */ +#define INV_GR2_2GE 0x10 /* has 2 GEs */ +#define INV_GR2_8GE 0x20 /* has 8 GEs */ +#define INV_GR2_GR3 0x40 /* board GR3 */ +#define INV_GR2_GU1 0x80 /* board GU1 */ +#define INV_GR2_INDY 0x100 /* board GR3 on Indy*/ +#define INV_GR2_GR5 0x200 /* board GR3 with 4 GEs, hinv prints GR5-XZ */ + + /* supported configurations */ +#define INV_GR2_XS 0x0 /* GR2-XS */ +#define INV_GR2_XSZ 0x1 /* GR2-XS with z-buffer */ +#define INV_GR2_XS24 0x2 /* GR2-XS24 */ +#define INV_GR2_XS24Z 0x3 /* GR2-XS24 with z-buffer */ +#define INV_GR2_XSM 0x4 /* GR2-XSM */ +#define INV_GR2_ELAN 0x7 /* GR2-Elan */ +#define INV_GR2_XZ 0x13 /* GR2-XZ */ +#define INV_GR3_XSM 0x44 /* GR3-XSM */ +#define INV_GR3_ELAN 0x47 /* GR3-Elan */ +#define INV_GU1_EXTREME 0xa3 /* GU1-Extreme */ + +/* States for graphics class NEWPORT */ +#define INV_NEWPORT_XL 0x01 /* Indigo2 XL model */ +#define INV_NEWPORT_24 0x02 /* board has 24 bitplanes */ +#define INV_NEWTON 0x04 /* Triton SUBGR tagging */ + +/* States for graphics class MGRAS */ +#define INV_MGRAS_ARCHS 0xff000000 /* architectures */ +#define INV_MGRAS_HQ3 0x00000000 /*impact*/ +#define INV_MGRAS_HQ4 0x01000000 /*gamera*/ +#define INV_MGRAS_MOT 0x02000000 /*mothra*/ +#define INV_MGRAS_GES 0x00ff0000 /* number of GEs */ +#define INV_MGRAS_1GE 0x00010000 +#define INV_MGRAS_2GE 0x00020000 +#define INV_MGRAS_RES 0x0000ff00 /* number of REs */ +#define INV_MGRAS_1RE 0x00000100 +#define INV_MGRAS_2RE 0x00000200 +#define INV_MGRAS_TRS 0x000000ff /* number of TRAMs */ +#define INV_MGRAS_0TR 0x00000000 +#define INV_MGRAS_1TR 0x00000001 +#define INV_MGRAS_2TR 0x00000002 + +/* States for graphics class CRIME */ +#define INV_CRM_BASE 0x01 /* Moosehead basic model */ + +/* States for graphics class ODSY */ +#define INV_ODSY_ARCHS 0xff000000 /* architectures */ +#define INV_ODSY_REVA_ARCH 0x01000000 /* Buzz Rev A */ +#define INV_ODSY_REVB_ARCH 0x02000000 /* Buzz Rev B */ +#define INV_ODSY_MEMCFG 0x00ff0000 /* memory configs */ +#define INV_ODSY_MEMCFG_32 0x00010000 /* 32MB memory */ +#define INV_ODSY_MEMCFG_64 0x00020000 /* 64MB memory */ +#define INV_ODSY_MEMCFG_128 0x00030000 /* 128MB memory */ +#define INV_ODSY_MEMCFG_256 0x00040000 /* 256MB memory */ +#define INV_ODSY_MEMCFG_512 0x00050000 /* 512MB memory */ + + +/* types for class network */ +#define INV_NET_ETHER 0 /* 10Mb Ethernet */ +#define INV_NET_HYPER 1 /* HyperNet */ +#define INV_NET_CRAYIOS 2 /* Cray Input/Ouput Subsystem */ +#define INV_NET_FDDI 3 /* FDDI */ +#define INV_NET_TOKEN 4 /* 16/4 Token Ring */ +#define INV_NET_HIPPI 5 /* HIPPI */ +#define INV_NET_ATM 6 /* ATM */ +#define INV_NET_ISDN_BRI 7 /* ISDN */ +#define INV_NET_ISDN_PRI 8 /* PRI ISDN */ +#define INV_NET_HIPPIS 9 /* HIPPI-Serial */ +#define INV_NET_GSN 10 /* GSN (aka HIPPI-6400) */ + +/* controllers for network types, unique within class network */ +#define INV_ETHER_EC 0 /* IP6 integral controller */ +#define INV_ETHER_ENP 1 /* CMC board */ +#define INV_ETHER_ET 2 /* IP5 integral controller */ +#define INV_HYPER_HY 3 /* HyperNet controller */ +#define INV_CRAYIOS_CFEI3 4 /* Cray Front End Interface, v3 */ +#define INV_FDDI_IMF 5 /* Interphase/Martin 3211 FDDI */ +#define INV_ETHER_EGL 6 /* Interphase V/4207 Eagle */ +#define INV_ETHER_FXP 7 /* CMC C/130 FXP */ +#define INV_FDDI_IPG 8 /* Interphase/SGI 4211 Peregrine FDDI */ +#define INV_TOKEN_FV 9 /* Formation fv1600 Token-Ring board */ +#define INV_FDDI_XPI 10 /* XPI GIO bus FDDI */ +#define INV_TOKEN_GTR 11 /* GTR GIO bus TokenRing */ +#define INV_ETHER_GIO 12 /* IP12/20 optional GIO ethernet controller */ +#define INV_ETHER_EE 13 /* Everest IO4 EPC SEEQ/EDLC */ +#define INV_HIO_HIPPI 14 /* HIO HIPPI for Challenge/Onyx */ +#define INV_ATM_GIO64 15 /* ATM OC-3c Mez card */ +#define INV_ETHER_EP 16 /* 8-port E-Plex Ethernet */ +#define INV_ISDN_SM 17 /* Siemens PEB 2085 */ +#define INV_TOKEN_MTR 18 /* EISA TokenRing */ +#define INV_ETHER_EF 19 /* IOC3 Fast Ethernet */ +#define INV_ISDN_48XP 20 /* Xircom PRI-48XP */ +#define INV_FDDI_RNS 21 /* Rockwell Network Systems FDDI */ +#define INV_HIPPIS_XTK 22 /* Xtalk HIPPI-Serial */ +#define INV_ATM_QUADOC3 23 /* Xtalk Quad OC-3c ATM interface */ +#define INV_TOKEN_MTRPCI 24 /* PCI TokenRing */ +#define INV_ETHER_ECF 25 /* PCI Fast Ethernet */ +#define INV_GFE 26 /* GIO Fast Ethernet */ +#define INV_VFE 27 /* VME Fast Ethernet */ +#define INV_ETHER_GE 28 /* Gigabit Ethernet */ +#define INV_ETHER_EFP INV_ETHER_EF /* unused (same as IOC3 Fast Ethernet) */ +#define INV_GSN_XTK1 29 /* single xtalk version of GSN */ +#define INV_GSN_XTK2 30 /* dual xtalk version of GSN */ +#define INV_FORE_HE 31 /* FORE HE ATM Card */ +#define INV_FORE_PCA 32 /* FORE PCA ATM Card */ +#define INV_FORE_VMA 33 /* FORE VMA ATM Card */ +#define INV_FORE_ESA 34 /* FORE ESA ATM Card */ +#define INV_FORE_GIA 35 /* FORE GIA ATM Card */ + +/* Types for class INV_SCSI and INV_VSCSI; The type code is the same as + * the device type code returned by the Inquiry command, iff the Inquiry + * command defines a type code for the device in question. If it doesn't, + * values over 31 will be used for the device type. + * Note: the lun is encoded in bits 8-15 of the state. The + * state field low 3 bits contains the information from the inquiry + * cmd that indicates ANSI SCSI 1,2, etc. compliance, and bit 7 + * contains the inquiry info that indicates whether the media is + * removable. + */ +#define INV_PRINTER 2 /* SCSI printer */ +#define INV_CPU 3 /* SCSI CPU device */ +#define INV_WORM 4 /* write-once-read-many (e.g. optical disks) */ +#define INV_CDROM 5 /* CD-ROM */ +#define INV_SCANNER 6 /* scanners */ +#define INV_OPTICAL 7 /* optical disks (read-write) */ +#define INV_CHANGER 8 /* jukebox's for CDROMS, for example */ +#define INV_COMM 9 /* Communications device */ +#define INV_RAIDCTLR 32 /* RAID ctlr actually gives type 0 */ + +/* bit definitions for state field for class INV_SCSI */ +#define INV_REMOVE 0x80 /* has removable media */ +#define INV_SCSI_MASK 7 /* to which ANSI SCSI standard device conforms*/ + +/* types for class INV_AUDIO */ + +#define INV_AUDIO_HDSP 0 /* Indigo DSP system */ +#define INV_AUDIO_VIGRA110 1 /* ViGRA 110 audio board */ +#define INV_AUDIO_VIGRA210 2 /* ViGRA 210 audio board */ +#define INV_AUDIO_A2 3 /* HAL2 / Audio Module for Indigo 2 */ +#define INV_AUDIO_A3 4 /* Moosehead (IP32) AD1843 codec */ +#define INV_AUDIO_RAD 5 /* RAD PCI chip */ + +/* types for class INV_VIDEO */ + +#define INV_VIDEO_LIGHT 0 +#define INV_VIDEO_VS2 1 /* MultiChannel Option */ +#define INV_VIDEO_EXPRESS 2 /* kaleidecope video */ +#define INV_VIDEO_VINO 3 +#define INV_VIDEO_VO2 4 /* Sirius Video */ +#define INV_VIDEO_INDY 5 /* Indy Video - kal vid on Newport + gfx on Indy */ +#define INV_VIDEO_MVP 6 /* Moosehead Video Ports */ +#define INV_VIDEO_INDY_601 7 /* Indy Video 601 */ +#define INV_VIDEO_PMUX 8 /* PALMUX video w/ PGR gfx */ +#define INV_VIDEO_MGRAS 9 /* Galileo 1.5 video */ +#define INV_VIDEO_DIVO 10 /* DIVO video */ +#define INV_VIDEO_RACER 11 /* SpeedRacer Pro Video */ +#define INV_VIDEO_EVO 12 /* EVO Personal Video */ +#define INV_VIDEO_XTHD 13 /* XIO XT-HDTV video */ + +/* states for video class INV_VIDEO_EXPRESS */ + +#define INV_GALILEO_REV 0xF +#define INV_GALILEO_JUNIOR 0x10 +#define INV_GALILEO_INDY_CAM 0x20 +#define INV_GALILEO_DBOB 0x40 +#define INV_GALILEO_ELANTEC 0x80 + +/* states for video class VINO */ + +#define INV_VINO_REV 0xF +#define INV_VINO_INDY_CAM 0x10 +#define INV_VINO_INDY_NOSW 0x20 /* nebulous - means s/w not installed */ + +/* states for video class MVP */ + +#define INV_MVP_REV(x) (((x)&0x0000000f)) +#define INV_MVP_REV_SW(x) (((x)&0x000000f0)>>4) +#define INV_MVP_AV_BOARD(x) (((x)&0x00000f00)>>8) +#define INV_MVP_AV_REV(x) (((x)&0x0000f000)>>12) +#define INV_MVP_CAMERA(x) (((x)&0x000f0000)>>16) +#define INV_MVP_CAM_REV(x) (((x)&0x00f00000)>>20) +#define INV_MVP_SDIINF(x) (((x)&0x0f000000)>>24) +#define INV_MVP_SDI_REV(x) (((x)&0xf0000000)>>28) + +/* types for class INV_BUS */ + +#define INV_BUS_VME 0 +#define INV_BUS_EISA 1 +#define INV_BUS_GIO 2 +#define INV_BUS_BT3_PCI 3 + +/* types for class INV_MISC */ +#define INV_MISC_EPC_EINT 0 /* EPC external interrupts */ +#define INV_MISC_PCKM 1 /* pc keyboard or mouse */ +#define INV_MISC_IOC3_EINT 2 /* IOC3 external interrupts */ +#define INV_MISC_OTHER 3 /* non-specific type */ + +/* + * The four components below do not actually have inventory information + * associated with the vertex. These symbols are used by grio at the + * moment to figure out the device type from the vertex. If these get + * inventory structures in the future, either the type values must + * remain the same or grio code needs to change. + */ + +#define INV_XBOW 3 /* cross bow */ +#define INV_HUB 4 /* hub */ +#define INV_PCI_BRIDGE 5 /* pci bridge */ +#define INV_ROUTER 6 /* router */ + +/* types for class INV_PROM */ +#define INV_IO6PROM 0 +#define INV_IP27PROM 1 +#define INV_IP35PROM 2 + +/* types for class INV_COMPRESSION */ + +#define INV_COSMO 0 +#define INV_INDYCOMP 1 +#define INV_IMPACTCOMP 2 /* cosmo2, aka impact compression */ +#define INV_VICE 3 /* Video imaging & compression engine */ + +/* types for class INV_DISPLAY */ +#define INV_PRESENTER_BOARD 0 /* Indy Presenter adapter board */ +#define INV_PRESENTER_PANEL 1 /* Indy Presenter board and panel */ +#define INV_ICO_BOARD 2 /* IMPACT channel option board */ +#define INV_DCD_BOARD 3 /* O2 dual channel option board */ +#define INV_7of9_BOARD 4 /* 7of9 flatpanel adapter board */ +#define INV_7of9_PANEL 5 /* 7of9 flatpanel board and panel */ + +/* types for class INV_IEEE1394 */ +#define INV_OHCI 0 /* Ohci IEEE1394 pci card */ +#define INV_RAWISO1394 10 /* Raw Isochronous IEEE 1394 protocol driver */ +#define INV_RAWASYNC1394 11 /* Raw Asynchronous IEEE 1394 protocol driver */ +#define INV_AVC1394 12 /* Audio, Video & Control (AV/C) IEEE 1394 protocol driver */ + +/* state for class INV_IEEE1394 & type INV_OHCI */ +#define INV_IEEE1394_STATE_TI_REV_1 0 + +/* O2 DVLink 1.1 controller static info */ +#define INV_IEEE1394_CTLR_O2_DVLINK_11 0x8009104c + +/* types for class INV_TPU */ +#define INV_TPU_EXT 0 /* External XIO Tensor Processing Unit */ +#define INV_TPU_XIO 1 /* Internal XIO Tensor Processing Unit */ + +typedef struct invent_generic_s { + unsigned short ig_module; + unsigned short ig_slot; + unsigned char ig_flag; + int ig_invclass; +} invent_generic_t; + +#define INVENT_ENABLED 0x1 + +typedef struct invent_membnkinfo { + unsigned short imb_size; /* bank size in MB */ + unsigned short imb_attr; /* Mem attributes */ + unsigned int imb_flag; /* bank flags */ +} invent_membnkinfo_t; + + +typedef struct invent_meminfo { + invent_generic_t im_gen; + unsigned short im_size; /* memory size */ + unsigned short im_banks; /* number of banks */ + /* + * declare an array with one element. Each platform is expected to + * allocate the size required based on the number of banks and set + * the im_banks correctly for this array traversal. + */ + invent_membnkinfo_t im_bank_info[1]; +} invent_meminfo_t; + +#define INV_MEM_PREMIUM 0x01 + +typedef struct invent_cpuinfo { + invent_generic_t ic_gen; + cpu_inv_t ic_cpu_info; + unsigned short ic_cpuid; + unsigned short ic_slice; +} invent_cpuinfo_t; + +typedef struct invent_rpsinfo { + invent_generic_t ir_gen; + int ir_xbox; /* is RPS connected to an xbox */ +} invent_rpsinfo_t; + +typedef struct invent_miscinfo { + invent_generic_t im_gen; + int im_rev; + int im_version; + int im_type; + uint64_t im_speed; +} invent_miscinfo_t; + + +typedef struct invent_routerinfo{ + invent_generic_t im_gen; + router_inv_t rip; +} invent_routerinfo_t; + + + +#ifdef __KERNEL__ + +typedef struct irix5_inventory_s { + app32_ptr_t inv_next; /* next inventory record in list */ + int inv_class; /* class of object */ + int inv_type; /* class sub-type of object */ + major_t inv_controller; /* object major identifier */ + minor_t inv_unit; /* object minor identifier */ + int inv_state; /* information specific to object or + class */ +} irix5_inventory_t; + +typedef struct invplace_s { + devfs_handle_t invplace_vhdl; /* current vertex */ + devfs_handle_t invplace_vplace; /* place in vertex list */ + inventory_t *invplace_inv; /* place in inv list on vertex */ +} invplace_t; /* Magic cookie placeholder in inventory list */ + +extern void add_to_inventory(int, int, int, int, int); +extern void replace_in_inventory(inventory_t *, int, int, int, int, int); +extern inventory_t *get_next_inventory(invplace_t *); +extern inventory_t *find_inventory(inventory_t *, int, int, int, int, int); +extern int scaninvent(int (*)(inventory_t *, void *), void *); +extern int get_sizeof_inventory(int); + +extern void device_inventory_add( devfs_handle_t device, + int class, + int type, + major_t ctlr, + minor_t unit, + int state); + + +extern inventory_t *device_inventory_get_next( devfs_handle_t device, + invplace_t *); + +extern void device_controller_num_set( devfs_handle_t, + int); +extern int device_controller_num_get( devfs_handle_t); +#endif /* __KERNEL__ */ +#endif /* _ASM_SN_INVENT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/io.h linux-2.4.0-test12-lia/include/asm-ia64/sn/io.h --- linux-2.4.0-test12/include/asm-ia64/sn/io.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/io.h Wed Dec 13 19:35:44 2000 @@ -0,0 +1,76 @@ + +/* $Id: io.h,v 1.2 2000/02/02 16:35:57 ralf 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) 2000 Ralf Baechle + * Copyright (C) 2000 Silicon Graphics, Inc. + */ +#ifndef _ASM_SN_IO_H +#define _ASM_SN_IO_H + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif + +#define IO_SPACE_BASE IO_BASE + +/* Because we only have PCI I/O ports. */ +#if !defined(CONFIG_IA64_SGI_IO) +#define IO_SPACE_LIMIT 0xffffffff + +/* No isa_* versions, the Origin doesn't have ISA / EISA bridges. */ + +#else /* CONFIG_IA64_SGI_IO */ + +#define IIO_ITTE_BASE 0x400160 /* base of translation table entries */ +#define IIO_ITTE(bigwin) (IIO_ITTE_BASE + 8*(bigwin)) + +#define IIO_ITTE_OFFSET_BITS 5 /* size of offset field */ +#define IIO_ITTE_OFFSET_MASK ((1<> BWIN_SIZE_BITS) & \ + IIO_ITTE_OFFSET_MASK) << IIO_ITTE_OFFSET_SHIFT) | \ + (io_or_mem << IIO_ITTE_IOSP_SHIFT) | \ + (((widget) & IIO_ITTE_WIDGET_MASK) << IIO_ITTE_WIDGET_SHIFT))) + +#define IIO_ITTE_DISABLE(nasid, bigwin) \ + IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \ + (bigwin), IIO_ITTE_INVALID_WIDGET, 0) + +#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin)) + +/* + * Macro which takes the widget number, and returns the + * IO PRB address of that widget. + * value _x is expected to be a widget number in the range + * 0, 8 - 0xF + */ +#define IIO_IOPRB(_x) (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \ + (_x) : \ + (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) ) + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif + +#endif /* CONFIG_IA64_SGI_IO */ + +#endif /* _ASM_SN_IO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/iobus.h linux-2.4.0-test12-lia/include/asm-ia64/sn/iobus.h --- linux-2.4.0-test12/include/asm-ia64/sn/iobus.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/iobus.h Wed Dec 6 21:56:08 2000 @@ -0,0 +1,185 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_IOBUS_H +#define _ASM_SN_IOBUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct eframe_s; +struct piomap; +struct dmamap; + + +/* for ilvl_t interrupt level, for use with intr_block_level. Can't + * typedef twice without causing warnings, and some users of this header + * file do not already include driver.h, but expect ilvl_t to be defined, + * while others include both, leading to the warning ... + */ + +#include +#include + + +typedef __psunsigned_t iobush_t; + +#if __KERNEL__ +/* adapter handle */ +typedef devfs_handle_t adap_t; +#endif + + +/* interrupt function */ +typedef void *intr_arg_t; +typedef void intr_func_f(intr_arg_t); +typedef intr_func_f *intr_func_t; + +#define INTR_ARG(n) ((intr_arg_t)(__psunsigned_t)(n)) + +/* system interrupt resource handle -- returned from intr_alloc */ +typedef struct intr_s *intr_t; +#define INTR_HANDLE_NONE ((intr_t)0) + +/* + * restore interrupt level value, returned from intr_block_level + * for use with intr_unblock_level. + */ +typedef void *rlvl_t; + + +/* + * A basic, platform-independent description of I/O requirements for + * a device. This structure is usually formed by lboot based on information + * in configuration files. It contains information about PIO, DMA, and + * interrupt requirements for a specific instance of a device. + * + * The pio description is currently unused. + * + * The dma description describes bandwidth characteristics and bandwidth + * allocation requirements. (TBD) + * + * The Interrupt information describes the priority of interrupt, desired + * destination, policy (TBD), whether this is an error interrupt, etc. + * For now, interrupts are targeted to specific CPUs. + */ + +typedef struct device_desc_s { + /* pio description (currently none) */ + + /* dma description */ + /* TBD: allocated badwidth requirements */ + + /* interrupt description */ + devfs_handle_t intr_target; /* Hardware locator string */ + int intr_policy; /* TBD */ + ilvl_t intr_swlevel; /* software level for blocking intr */ + char *intr_name; /* name of interrupt, if any */ + + int flags; +} *device_desc_t; + +/* flag values */ +#define D_INTR_ISERR 0x1 /* interrupt is for error handling */ +#define D_IS_ASSOC 0x2 /* descriptor is associated with a dev */ +#define D_INTR_NOTHREAD 0x4 /* Interrupt handler isn't threaded. */ + +#define INTR_SWLEVEL_NOTHREAD_DEFAULT 0 /* Default + * Interrupt level in case of + * non-threaded interrupt + * handlers + */ +/* + * Drivers use these interfaces to manage device descriptors. + * + * To examine defaults: + * desc = device_desc_default_get(dev); + * device_desc_*_get(desc); + * + * To modify defaults: + * desc = device_desc_default_get(dev); + * device_desc_*_set(desc); + * + * To eliminate defaults: + * device_desc_default_set(dev, NULL); + * + * To override defaults: + * desc = device_desc_dup(dev); + * device_desc_*_set(desc,...); + * use device_desc in calls + * device_desc_free(desc); + * + * Software must not set or eliminate default device descriptors for a device while + * concurrently get'ing, dup'ing or using them. Default device descriptors can be + * changed only for a device that is quiescent. In general, device drivers have no + * need to permanently change defaults anyway -- they just override defaults, when + * necessary. + */ +extern device_desc_t device_desc_dup(devfs_handle_t dev); +extern void device_desc_free(device_desc_t device_desc); +extern device_desc_t device_desc_default_get(devfs_handle_t dev); +extern void device_desc_default_set(devfs_handle_t dev, device_desc_t device_desc); + +extern devfs_handle_t device_desc_intr_target_get(device_desc_t device_desc); +extern int device_desc_intr_policy_get(device_desc_t device_desc); +extern ilvl_t device_desc_intr_swlevel_get(device_desc_t device_desc); +extern char * device_desc_intr_name_get(device_desc_t device_desc); +extern int device_desc_flags_get(device_desc_t device_desc); + +extern void device_desc_intr_target_set(device_desc_t device_desc, devfs_handle_t target); +extern void device_desc_intr_policy_set(device_desc_t device_desc, int policy); +extern void device_desc_intr_swlevel_set(device_desc_t device_desc, ilvl_t swlevel); +extern void device_desc_intr_name_set(device_desc_t device_desc, char *name); +extern void device_desc_flags_set(device_desc_t device_desc, int flags); + + +/* IO state */ +#ifdef COMMENT +#define IO_STATE_EMPTY 0x01 /* non-existent */ +#define IO_STATE_INITIALIZING 0x02 /* being initialized */ +#define IO_STATE_ATTACHING 0x04 /* becoming active */ +#define IO_STATE_ACTIVE 0x08 /* active */ +#define IO_STATE_DETACHING 0x10 /* becoming inactive */ +#define IO_STATE_INACTIVE 0x20 /* not in use */ +#define IO_STATE_ERROR 0x40 /* problems */ +#define IO_STATE_BAD_HARDWARE 0x80 /* broken hardware */ +#endif + +struct edt; + + +/* return codes */ +#define RC_OK 0 +#define RC_ERROR 1 + +/* bus configuration management op code */ +#define IOBUS_CONFIG_ATTACH 0 /* vary on */ +#define IOBUS_CONFIG_DETACH 1 /* vary off */ +#define IOBUS_CONFIG_RECOVER 2 /* clear error then vary on */ + +/* get low-level PIO handle */ +extern int pio_geth(struct piomap*, int bus, int bus_id, int subtype, + iopaddr_t addr, int size); + +/* get low-level DMA handle */ +extern int dma_geth(struct dmamap*, int bus_type, int bus_id, int dma_type, + int npages, int page_size, int flags); + +#ifdef __cplusplus +} +#endif + +/* + * Macros for page number and page offsets, using ps as page size + */ +#define x_pnum(addr, ps) ((__psunsigned_t)(addr) / (__psunsigned_t)(ps)) +#define x_poff(addr, ps) ((__psunsigned_t)(addr) & ((__psunsigned_t)(ps) - 1)) + +#endif /* _ASM_SN_IOBUS_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/ioc3.h linux-2.4.0-test12-lia/include/asm-ia64/sn/ioc3.h --- linux-2.4.0-test12/include/asm-ia64/sn/ioc3.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/ioc3.h Wed Dec 6 21:56:08 2000 @@ -0,0 +1,671 @@ +/* $Id: ioc3.h,v 1.2 2000/11/16 19:49:17 pfg Exp $ + * + * Copyright (C) 1999 Ralf Baechle + * This file is part of the Linux driver for the SGI IOC3. + */ +#ifndef IOC3_H +#define IOC3_H + +/* SUPERIO uart register map */ +typedef volatile struct ioc3_uartregs { + union { + volatile u8 rbr; /* read only, DLAB == 0 */ + volatile u8 thr; /* write only, DLAB == 0 */ + volatile u8 dll; /* DLAB == 1 */ + } u1; + union { + volatile u8 ier; /* DLAB == 0 */ + volatile u8 dlm; /* DLAB == 1 */ + } u2; + union { + volatile u8 iir; /* read only */ + volatile u8 fcr; /* write only */ + } u3; + volatile u8 iu_lcr; + volatile u8 iu_mcr; + volatile u8 iu_lsr; + volatile u8 iu_msr; + volatile u8 iu_scr; +} ioc3_uregs_t; + +#define iu_rbr u1.rbr +#define iu_thr u1.thr +#define iu_dll u1.dll +#define iu_ier u2.ier +#define iu_dlm u2.dlm +#define iu_iir u3.iir +#define iu_fcr u3.fcr + +struct ioc3_sioregs { + volatile u8 fill[0x141]; /* starts at 0x141 */ + + volatile u8 uartc; + volatile u8 kbdcg; + + volatile u8 fill0[0x150 - 0x142 - 1]; + + volatile u8 pp_data; + volatile u8 pp_dsr; + volatile u8 pp_dcr; + + volatile u8 fill1[0x158 - 0x152 - 1]; + + volatile u8 pp_fifa; + volatile u8 pp_cfgb; + volatile u8 pp_ecr; + + volatile u8 fill2[0x168 - 0x15a - 1]; + + volatile u8 rtcad; + volatile u8 rtcdat; + + volatile u8 fill3[0x170 - 0x169 - 1]; + + struct ioc3_uartregs uartb; /* 0x20170 */ + struct ioc3_uartregs uarta; /* 0x20178 */ +}; + +/* Register layout of IOC3 in configuration space. */ +struct ioc3 { + volatile u32 pad0[7]; /* 0x00000 */ + volatile u32 sio_ir; /* 0x0001c */ + volatile u32 sio_ies; /* 0x00020 */ + volatile u32 sio_iec; /* 0x00024 */ + volatile u32 sio_cr; /* 0x00028 */ + volatile u32 int_out; /* 0x0002c */ + volatile u32 mcr; /* 0x00030 */ + + /* General Purpose I/O registers */ + volatile u32 gpcr_s; /* 0x00034 */ + volatile u32 gpcr_c; /* 0x00038 */ + volatile u32 gpdr; /* 0x0003c */ + volatile u32 gppr_0; /* 0x00040 */ + volatile u32 gppr_1; /* 0x00044 */ + volatile u32 gppr_2; /* 0x00048 */ + volatile u32 gppr_3; /* 0x0004c */ + volatile u32 gppr_4; /* 0x00050 */ + volatile u32 gppr_5; /* 0x00054 */ + volatile u32 gppr_6; /* 0x00058 */ + volatile u32 gppr_7; /* 0x0005c */ + volatile u32 gppr_8; /* 0x00060 */ + volatile u32 gppr_9; /* 0x00064 */ + volatile u32 gppr_10; /* 0x00068 */ + volatile u32 gppr_11; /* 0x0006c */ + volatile u32 gppr_12; /* 0x00070 */ + volatile u32 gppr_13; /* 0x00074 */ + volatile u32 gppr_14; /* 0x00078 */ + volatile u32 gppr_15; /* 0x0007c */ + + /* Parallel Port Registers */ + volatile u32 ppbr_h_a; /* 0x00080 */ + volatile u32 ppbr_l_a; /* 0x00084 */ + volatile u32 ppcr_a; /* 0x00088 */ + volatile u32 ppcr; /* 0x0008c */ + volatile u32 ppbr_h_b; /* 0x00090 */ + volatile u32 ppbr_l_b; /* 0x00094 */ + volatile u32 ppcr_b; /* 0x00098 */ + + /* Keyboard and Mouse Registers */ + volatile u32 km_csr; /* 0x0009c */ + volatile u32 k_rd; /* 0x000a0 */ + volatile u32 m_rd; /* 0x000a4 */ + volatile u32 k_wd; /* 0x000a8 */ + volatile u32 m_wd; /* 0x000ac */ + + /* Serial Port Registers */ + volatile u32 sbbr_h; /* 0x000b0 */ + volatile u32 sbbr_l; /* 0x000b4 */ + volatile u32 sscr_a; /* 0x000b8 */ + volatile u32 stpir_a; /* 0x000bc */ + volatile u32 stcir_a; /* 0x000c0 */ + volatile u32 srpir_a; /* 0x000c4 */ + volatile u32 srcir_a; /* 0x000c8 */ + volatile u32 srtr_a; /* 0x000cc */ + volatile u32 shadow_a; /* 0x000d0 */ + volatile u32 sscr_b; /* 0x000d4 */ + volatile u32 stpir_b; /* 0x000d8 */ + volatile u32 stcir_b; /* 0x000dc */ + volatile u32 srpir_b; /* 0x000e0 */ + volatile u32 srcir_b; /* 0x000e4 */ + volatile u32 srtr_b; /* 0x000e8 */ + volatile u32 shadow_b; /* 0x000ec */ + + /* Ethernet Registers */ + volatile u32 emcr; /* 0x000f0 */ + volatile u32 eisr; /* 0x000f4 */ + volatile u32 eier; /* 0x000f8 */ + volatile u32 ercsr; /* 0x000fc */ + volatile u32 erbr_h; /* 0x00100 */ + volatile u32 erbr_l; /* 0x00104 */ + volatile u32 erbar; /* 0x00108 */ + volatile u32 ercir; /* 0x0010c */ + volatile u32 erpir; /* 0x00110 */ + volatile u32 ertr; /* 0x00114 */ + volatile u32 etcsr; /* 0x00118 */ + volatile u32 ersr; /* 0x0011c */ + volatile u32 etcdc; /* 0x00120 */ + volatile u32 ebir; /* 0x00124 */ + volatile u32 etbr_h; /* 0x00128 */ + volatile u32 etbr_l; /* 0x0012c */ + volatile u32 etcir; /* 0x00130 */ + volatile u32 etpir; /* 0x00134 */ + volatile u32 emar_h; /* 0x00138 */ + volatile u32 emar_l; /* 0x0013c */ + volatile u32 ehar_h; /* 0x00140 */ + volatile u32 ehar_l; /* 0x00144 */ + volatile u32 micr; /* 0x00148 */ + volatile u32 midr_r; /* 0x0014c */ + volatile u32 midr_w; /* 0x00150 */ + volatile u32 pad1[(0x20000 - 0x00154) / 4]; + + /* SuperIO Registers XXX */ + struct ioc3_sioregs sregs; /* 0x20000 */ + volatile u32 pad2[(0x40000 - 0x20180) / 4]; + + /* SSRAM Diagnostic Access */ + volatile u32 ssram[(0x80000 - 0x40000) / 4]; + + /* Bytebus device offsets + 0x80000 - Access to the generic devices selected with DEV0 + 0x9FFFF bytebus DEV_SEL_0 + 0xA0000 - Access to the generic devices selected with DEV1 + 0xBFFFF bytebus DEV_SEL_1 + 0xC0000 - Access to the generic devices selected with DEV2 + 0xDFFFF bytebus DEV_SEL_2 + 0xE0000 - Access to the generic devices selected with DEV3 + 0xFFFFF bytebus DEV_SEL_3 */ +}; + +/* + * Ethernet RX Buffer + */ +struct ioc3_erxbuf { + u32 w0; /* first word (valid,bcnt,cksum) */ + u32 err; /* second word various errors */ + /* next comes n bytes of padding */ + /* then the received ethernet frame itself */ +}; + +#define ERXBUF_IPCKSUM_MASK 0x0000ffff +#define ERXBUF_BYTECNT_MASK 0x07ff0000 +#define ERXBUF_BYTECNT_SHIFT 16 +#define ERXBUF_V 0x80000000 + +#define ERXBUF_CRCERR 0x00000001 /* aka RSV15 */ +#define ERXBUF_FRAMERR 0x00000002 /* aka RSV14 */ +#define ERXBUF_CODERR 0x00000004 /* aka RSV13 */ +#define ERXBUF_INVPREAMB 0x00000008 /* aka RSV18 */ +#define ERXBUF_LOLEN 0x00007000 /* aka RSV2_0 */ +#define ERXBUF_HILEN 0x03ff0000 /* aka RSV12_3 */ +#define ERXBUF_MULTICAST 0x04000000 /* aka RSV16 */ +#define ERXBUF_BROADCAST 0x08000000 /* aka RSV17 */ +#define ERXBUF_LONGEVENT 0x10000000 /* aka RSV19 */ +#define ERXBUF_BADPKT 0x20000000 /* aka RSV20 */ +#define ERXBUF_GOODPKT 0x40000000 /* aka RSV21 */ +#define ERXBUF_CARRIER 0x80000000 /* aka RSV22 */ + +/* + * Ethernet TX Descriptor + */ +#define ETXD_DATALEN 104 +struct ioc3_etxd { + u32 cmd; /* command field */ + u32 bufcnt; /* buffer counts field */ + u64 p1; /* buffer pointer 1 */ + u64 p2; /* buffer pointer 2 */ + u8 data[ETXD_DATALEN]; /* opt. tx data */ +}; + +#define ETXD_BYTECNT_MASK 0x000007ff /* total byte count */ +#define ETXD_INTWHENDONE 0x00001000 /* intr when done */ +#define ETXD_D0V 0x00010000 /* data 0 valid */ +#define ETXD_B1V 0x00020000 /* buf 1 valid */ +#define ETXD_B2V 0x00040000 /* buf 2 valid */ +#define ETXD_DOCHECKSUM 0x00080000 /* insert ip cksum */ +#define ETXD_CHKOFF_MASK 0x07f00000 /* cksum byte offset */ +#define ETXD_CHKOFF_SHIFT 20 + +#define ETXD_D0CNT_MASK 0x0000007f +#define ETXD_B1CNT_MASK 0x0007ff00 +#define ETXD_B1CNT_SHIFT 8 +#define ETXD_B2CNT_MASK 0x7ff00000 +#define ETXD_B2CNT_SHIFT 20 + +/* + * Bytebus device space + */ +#define IOC3_BYTEBUS_DEV0 0x80000L +#define IOC3_BYTEBUS_DEV1 0xa0000L +#define IOC3_BYTEBUS_DEV2 0xc0000L +#define IOC3_BYTEBUS_DEV3 0xe0000L + +/* ------------------------------------------------------------------------- */ + +/* Superio Registers (PIO Access) */ +#define IOC3_SIO_BASE 0x20000 +#define IOC3_SIO_UARTC (IOC3_SIO_BASE+0x141) /* UART Config */ +#define IOC3_SIO_KBDCG (IOC3_SIO_BASE+0x142) /* KBD Config */ +#define IOC3_SIO_PP_BASE (IOC3_SIO_BASE+PP_BASE) /* Parallel Port */ +#define IOC3_SIO_RTC_BASE (IOC3_SIO_BASE+0x168) /* Real Time Clock */ +#define IOC3_SIO_UB_BASE (IOC3_SIO_BASE+UARTB_BASE) /* UART B */ +#define IOC3_SIO_UA_BASE (IOC3_SIO_BASE+UARTA_BASE) /* UART A */ + +/* SSRAM Diagnostic Access */ +#define IOC3_SSRAM IOC3_RAM_OFF /* base of SSRAM diagnostic access */ +#define IOC3_SSRAM_LEN 0x40000 /* 256kb (address space size, may not be fully populated) */ +#define IOC3_SSRAM_DM 0x0000ffff /* data mask */ +#define IOC3_SSRAM_PM 0x00010000 /* parity mask */ + +/* bitmasks for PCI_SCR */ +#define PCI_SCR_PAR_RESP_EN 0x00000040 /* enb PCI parity checking */ +#define PCI_SCR_SERR_EN 0x00000100 /* enable the SERR# driver */ +#define PCI_SCR_DROP_MODE_EN 0x00008000 /* drop pios on parity err */ +#define PCI_SCR_RX_SERR (0x1 << 16) +#define PCI_SCR_DROP_MODE (0x1 << 17) +#define PCI_SCR_SIG_PAR_ERR (0x1 << 24) +#define PCI_SCR_SIG_TAR_ABRT (0x1 << 27) +#define PCI_SCR_RX_TAR_ABRT (0x1 << 28) +#define PCI_SCR_SIG_MST_ABRT (0x1 << 29) +#define PCI_SCR_SIG_SERR (0x1 << 30) +#define PCI_SCR_PAR_ERR (0x1 << 31) + +/* bitmasks for IOC3_KM_CSR */ +#define KM_CSR_K_WRT_PEND 0x00000001 /* kbd port xmitting or resetting */ +#define KM_CSR_M_WRT_PEND 0x00000002 /* mouse port xmitting or resetting */ +#define KM_CSR_K_LCB 0x00000004 /* Line Cntrl Bit for last KBD write */ +#define KM_CSR_M_LCB 0x00000008 /* same for mouse */ +#define KM_CSR_K_DATA 0x00000010 /* state of kbd data line */ +#define KM_CSR_K_CLK 0x00000020 /* state of kbd clock line */ +#define KM_CSR_K_PULL_DATA 0x00000040 /* pull kbd data line low */ +#define KM_CSR_K_PULL_CLK 0x00000080 /* pull kbd clock line low */ +#define KM_CSR_M_DATA 0x00000100 /* state of ms data line */ +#define KM_CSR_M_CLK 0x00000200 /* state of ms clock line */ +#define KM_CSR_M_PULL_DATA 0x00000400 /* pull ms data line low */ +#define KM_CSR_M_PULL_CLK 0x00000800 /* pull ms clock line low */ +#define KM_CSR_EMM_MODE 0x00001000 /* emulation mode */ +#define KM_CSR_SIM_MODE 0x00002000 /* clock X8 */ +#define KM_CSR_K_SM_IDLE 0x00004000 /* Keyboard is idle */ +#define KM_CSR_M_SM_IDLE 0x00008000 /* Mouse is idle */ +#define KM_CSR_K_TO 0x00010000 /* Keyboard trying to send/receive */ +#define KM_CSR_M_TO 0x00020000 /* Mouse trying to send/receive */ +#define KM_CSR_K_TO_EN 0x00040000 /* KM_CSR_K_TO + KM_CSR_K_TO_EN = cause + SIO_IR to assert */ +#define KM_CSR_M_TO_EN 0x00080000 /* KM_CSR_M_TO + KM_CSR_M_TO_EN = cause + SIO_IR to assert */ +#define KM_CSR_K_CLAMP_ONE 0x00100000 /* Pull K_CLK low after rec. one char */ +#define KM_CSR_M_CLAMP_ONE 0x00200000 /* Pull M_CLK low after rec. one char */ +#define KM_CSR_K_CLAMP_THREE 0x00400000 /* Pull K_CLK low after rec. three chars */ +#define KM_CSR_M_CLAMP_THREE 0x00800000 /* Pull M_CLK low after rec. three char */ + +/* bitmasks for IOC3_K_RD and IOC3_M_RD */ +#define KM_RD_DATA_2 0x000000ff /* 3rd char recvd since last read */ +#define KM_RD_DATA_2_SHIFT 0 +#define KM_RD_DATA_1 0x0000ff00 /* 2nd char recvd since last read */ +#define KM_RD_DATA_1_SHIFT 8 +#define KM_RD_DATA_0 0x00ff0000 /* 1st char recvd since last read */ +#define KM_RD_DATA_0_SHIFT 16 +#define KM_RD_FRAME_ERR_2 0x01000000 /* framing or parity error in byte 2 */ +#define KM_RD_FRAME_ERR_1 0x02000000 /* same for byte 1 */ +#define KM_RD_FRAME_ERR_0 0x04000000 /* same for byte 0 */ + +#define KM_RD_KBD_MSE 0x08000000 /* 0 if from kbd, 1 if from mouse */ +#define KM_RD_OFLO 0x10000000 /* 4th char recvd before this read */ +#define KM_RD_VALID_2 0x20000000 /* DATA_2 valid */ +#define KM_RD_VALID_1 0x40000000 /* DATA_1 valid */ +#define KM_RD_VALID_0 0x80000000 /* DATA_0 valid */ +#define KM_RD_VALID_ALL (KM_RD_VALID_0|KM_RD_VALID_1|KM_RD_VALID_2) + +/* bitmasks for IOC3_K_WD & IOC3_M_WD */ +#define KM_WD_WRT_DATA 0x000000ff /* write to keyboard/mouse port */ +#define KM_WD_WRT_DATA_SHIFT 0 + +/* bitmasks for serial RX status byte */ +#define RXSB_OVERRUN 0x01 /* char(s) lost */ +#define RXSB_PAR_ERR 0x02 /* parity error */ +#define RXSB_FRAME_ERR 0x04 /* framing error */ +#define RXSB_BREAK 0x08 /* break character */ +#define RXSB_CTS 0x10 /* state of CTS */ +#define RXSB_DCD 0x20 /* state of DCD */ +#define RXSB_MODEM_VALID 0x40 /* DCD, CTS and OVERRUN are valid */ +#define RXSB_DATA_VALID 0x80 /* data byte, FRAME_ERR PAR_ERR & BREAK valid */ + +/* bitmasks for serial TX control byte */ +#define TXCB_INT_WHEN_DONE 0x20 /* interrupt after this byte is sent */ +#define TXCB_INVALID 0x00 /* byte is invalid */ +#define TXCB_VALID 0x40 /* byte is valid */ +#define TXCB_MCR 0x80 /* data<7:0> to modem control register */ +#define TXCB_DELAY 0xc0 /* delay data<7:0> mSec */ + +/* bitmasks for IOC3_SBBR_L */ +#define SBBR_L_SIZE 0x00000001 /* 0 == 1KB rings, 1 == 4KB rings */ +#define SBBR_L_BASE 0xfffff000 /* lower serial ring base addr */ + +/* bitmasks for IOC3_SSCR_ */ +#define SSCR_RX_THRESHOLD 0x000001ff /* hiwater mark */ +#define SSCR_TX_TIMER_BUSY 0x00010000 /* TX timer in progress */ +#define SSCR_HFC_EN 0x00020000 /* hardware flow control enabled */ +#define SSCR_RX_RING_DCD 0x00040000 /* post RX record on delta-DCD */ +#define SSCR_RX_RING_CTS 0x00080000 /* post RX record on delta-CTS */ +#define SSCR_HIGH_SPD 0x00100000 /* 4X speed */ +#define SSCR_DIAG 0x00200000 /* bypass clock divider for sim */ +#define SSCR_RX_DRAIN 0x08000000 /* drain RX buffer to memory */ +#define SSCR_DMA_EN 0x10000000 /* enable ring buffer DMA */ +#define SSCR_DMA_PAUSE 0x20000000 /* pause DMA */ +#define SSCR_PAUSE_STATE 0x40000000 /* sets when PAUSE takes effect */ +#define SSCR_RESET 0x80000000 /* reset DMA channels */ + +/* all producer/comsumer pointers are the same bitfield */ +#define PROD_CONS_PTR_4K 0x00000ff8 /* for 4K buffers */ +#define PROD_CONS_PTR_1K 0x000003f8 /* for 1K buffers */ +#define PROD_CONS_PTR_OFF 3 + +/* bitmasks for IOC3_SRCIR_ */ +#define SRCIR_ARM 0x80000000 /* arm RX timer */ + +/* bitmasks for IOC3_SRPIR_ */ +#define SRPIR_BYTE_CNT 0x07000000 /* bytes in packer */ +#define SRPIR_BYTE_CNT_SHIFT 24 + +/* bitmasks for IOC3_STCIR_ */ +#define STCIR_BYTE_CNT 0x0f000000 /* bytes in unpacker */ +#define STCIR_BYTE_CNT_SHIFT 24 + +/* bitmasks for IOC3_SHADOW_ */ +#define SHADOW_DR 0x00000001 /* data ready */ +#define SHADOW_OE 0x00000002 /* overrun error */ +#define SHADOW_PE 0x00000004 /* parity error */ +#define SHADOW_FE 0x00000008 /* framing error */ +#define SHADOW_BI 0x00000010 /* break interrupt */ +#define SHADOW_THRE 0x00000020 /* transmit holding register empty */ +#define SHADOW_TEMT 0x00000040 /* transmit shift register empty */ +#define SHADOW_RFCE 0x00000080 /* char in RX fifo has an error */ +#define SHADOW_DCTS 0x00010000 /* delta clear to send */ +#define SHADOW_DDCD 0x00080000 /* delta data carrier detect */ +#define SHADOW_CTS 0x00100000 /* clear to send */ +#define SHADOW_DCD 0x00800000 /* data carrier detect */ +#define SHADOW_DTR 0x01000000 /* data terminal ready */ +#define SHADOW_RTS 0x02000000 /* request to send */ +#define SHADOW_OUT1 0x04000000 /* 16550 OUT1 bit */ +#define SHADOW_OUT2 0x08000000 /* 16550 OUT2 bit */ +#define SHADOW_LOOP 0x10000000 /* loopback enabled */ + +/* bitmasks for IOC3_SRTR_ */ +#define SRTR_CNT 0x00000fff /* reload value for RX timer */ +#define SRTR_CNT_VAL 0x0fff0000 /* current value of RX timer */ +#define SRTR_CNT_VAL_SHIFT 16 +#define SRTR_HZ 16000 /* SRTR clock frequency */ + +/* bitmasks for IOC3_SIO_IR, IOC3_SIO_IEC and IOC3_SIO_IES */ +#define SIO_IR_SA_TX_MT 0x00000001 /* Serial port A TX empty */ +#define SIO_IR_SA_RX_FULL 0x00000002 /* port A RX buf full */ +#define SIO_IR_SA_RX_HIGH 0x00000004 /* port A RX hiwat */ +#define SIO_IR_SA_RX_TIMER 0x00000008 /* port A RX timeout */ +#define SIO_IR_SA_DELTA_DCD 0x00000010 /* port A delta DCD */ +#define SIO_IR_SA_DELTA_CTS 0x00000020 /* port A delta CTS */ +#define SIO_IR_SA_INT 0x00000040 /* port A pass-thru intr */ +#define SIO_IR_SA_TX_EXPLICIT 0x00000080 /* port A explicit TX thru */ +#define SIO_IR_SA_MEMERR 0x00000100 /* port A PCI error */ +#define SIO_IR_SB_TX_MT 0x00000200 /* */ +#define SIO_IR_SB_RX_FULL 0x00000400 /* */ +#define SIO_IR_SB_RX_HIGH 0x00000800 /* */ +#define SIO_IR_SB_RX_TIMER 0x00001000 /* */ +#define SIO_IR_SB_DELTA_DCD 0x00002000 /* */ +#define SIO_IR_SB_DELTA_CTS 0x00004000 /* */ +#define SIO_IR_SB_INT 0x00008000 /* */ +#define SIO_IR_SB_TX_EXPLICIT 0x00010000 /* */ +#define SIO_IR_SB_MEMERR 0x00020000 /* */ +#define SIO_IR_PP_INT 0x00040000 /* P port pass-thru intr */ +#define SIO_IR_PP_INTA 0x00080000 /* PP context A thru */ +#define SIO_IR_PP_INTB 0x00100000 /* PP context B thru */ +#define SIO_IR_PP_MEMERR 0x00200000 /* PP PCI error */ +#define SIO_IR_KBD_INT 0x00400000 /* kbd/mouse intr */ +#define SIO_IR_RT_INT 0x08000000 /* RT output pulse */ +#define SIO_IR_GEN_INT1 0x10000000 /* RT input pulse */ +#define SIO_IR_GEN_INT_SHIFT 28 + +/* per device interrupt masks */ +#define SIO_IR_SA (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL | \ + SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER | \ + SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS | \ + SIO_IR_SA_INT | SIO_IR_SA_TX_EXPLICIT | \ + SIO_IR_SA_MEMERR) +#define SIO_IR_SB (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL | \ + SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER | \ + SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS | \ + SIO_IR_SB_INT | SIO_IR_SB_TX_EXPLICIT | \ + SIO_IR_SB_MEMERR) +#define SIO_IR_PP (SIO_IR_PP_INT | SIO_IR_PP_INTA | \ + SIO_IR_PP_INTB | SIO_IR_PP_MEMERR) +#define SIO_IR_RT (SIO_IR_RT_INT | SIO_IR_GEN_INT1) + +/* macro to load pending interrupts */ +#define IOC3_PENDING_INTRS(mem) (PCI_INW(&((mem)->sio_ir)) & \ + PCI_INW(&((mem)->sio_ies_ro))) + +/* bitmasks for SIO_CR */ +#define SIO_CR_SIO_RESET 0x00000001 /* reset the SIO */ +#define SIO_CR_SER_A_BASE 0x000000fe /* DMA poll addr port A */ +#define SIO_CR_SER_A_BASE_SHIFT 1 +#define SIO_CR_SER_B_BASE 0x00007f00 /* DMA poll addr port B */ +#define SIO_CR_SER_B_BASE_SHIFT 8 +#define SIO_SR_CMD_PULSE 0x00078000 /* byte bus strobe length */ +#define SIO_CR_CMD_PULSE_SHIFT 15 +#define SIO_CR_ARB_DIAG 0x00380000 /* cur !enet PCI requet (ro) */ +#define SIO_CR_ARB_DIAG_TXA 0x00000000 +#define SIO_CR_ARB_DIAG_RXA 0x00080000 +#define SIO_CR_ARB_DIAG_TXB 0x00100000 +#define SIO_CR_ARB_DIAG_RXB 0x00180000 +#define SIO_CR_ARB_DIAG_PP 0x00200000 +#define SIO_CR_ARB_DIAG_IDLE 0x00400000 /* 0 -> active request (ro) */ + +/* bitmasks for INT_OUT */ +#define INT_OUT_COUNT 0x0000ffff /* pulse interval timer */ +#define INT_OUT_MODE 0x00070000 /* mode mask */ +#define INT_OUT_MODE_0 0x00000000 /* set output to 0 */ +#define INT_OUT_MODE_1 0x00040000 /* set output to 1 */ +#define INT_OUT_MODE_1PULSE 0x00050000 /* send 1 pulse */ +#define INT_OUT_MODE_PULSES 0x00060000 /* send 1 pulse every interval */ +#define INT_OUT_MODE_SQW 0x00070000 /* toggle output every interval */ +#define INT_OUT_DIAG 0x40000000 /* diag mode */ +#define INT_OUT_INT_OUT 0x80000000 /* current state of INT_OUT */ + +/* time constants for INT_OUT */ +#define INT_OUT_NS_PER_TICK (30 * 260) /* 30 ns PCI clock, divisor=260 */ +#define INT_OUT_TICKS_PER_PULSE 3 /* outgoing pulse lasts 3 ticks */ +#define INT_OUT_US_TO_COUNT(x) /* convert uS to a count value */ \ + (((x) * 10 + INT_OUT_NS_PER_TICK / 200) * \ + 100 / INT_OUT_NS_PER_TICK - 1) +#define INT_OUT_COUNT_TO_US(x) /* convert count value to uS */ \ + (((x) + 1) * INT_OUT_NS_PER_TICK / 1000) +#define INT_OUT_MIN_TICKS 3 /* min period is width of pulse in "ticks" */ +#define INT_OUT_MAX_TICKS INT_OUT_COUNT /* largest possible count */ + +/* bitmasks for GPCR */ +#define GPCR_DIR 0x000000ff /* tristate pin input or output */ +#define GPCR_DIR_PIN(x) (1<<(x)) /* access one of the DIR bits */ +#define GPCR_EDGE 0x000f0000 /* extint edge or level sensitive */ +#define GPCR_EDGE_PIN(x) (1<<((x)+15)) /* access one of the EDGE bits */ + +/* values for GPCR */ +#define GPCR_INT_OUT_EN 0x00100000 /* enable INT_OUT to pin 0 */ +#define GPCR_MLAN_EN 0x00200000 /* enable MCR to pin 8 */ +#define GPCR_DIR_SERA_XCVR 0x00000080 /* Port A Transceiver select enable */ +#define GPCR_DIR_SERB_XCVR 0x00000040 /* Port B Transceiver select enable */ +#define GPCR_DIR_PHY_RST 0x00000020 /* ethernet PHY reset enable */ + +/* defs for some of the generic I/O pins */ +#define GPCR_PHY_RESET 0x20 /* pin is output to PHY reset */ +#define GPCR_UARTB_MODESEL 0x40 /* pin is output to port B mode sel */ +#define GPCR_UARTA_MODESEL 0x80 /* pin is output to port A mode sel */ + +#define GPPR_PHY_RESET_PIN 5 /* GIO pin controlling phy reset */ +#define GPPR_UARTB_MODESEL_PIN 6 /* GIO pin controlling uart b mode select */ +#define GPPR_UARTA_MODESEL_PIN 7 /* GIO pin controlling uart a mode select */ + +#define EMCR_DUPLEX 0x00000001 +#define EMCR_PROMISC 0x00000002 +#define EMCR_PADEN 0x00000004 +#define EMCR_RXOFF_MASK 0x000001f8 +#define EMCR_RXOFF_SHIFT 3 +#define EMCR_RAMPAR 0x00000200 +#define EMCR_BADPAR 0x00000800 +#define EMCR_BUFSIZ 0x00001000 +#define EMCR_TXDMAEN 0x00002000 +#define EMCR_TXEN 0x00004000 +#define EMCR_RXDMAEN 0x00008000 +#define EMCR_RXEN 0x00010000 +#define EMCR_LOOPBACK 0x00020000 +#define EMCR_ARB_DIAG 0x001c0000 +#define EMCR_ARB_DIAG_IDLE 0x00200000 +#define EMCR_RST 0x80000000 + +#define EISR_RXTIMERINT 0x00000001 +#define EISR_RXTHRESHINT 0x00000002 +#define EISR_RXOFLO 0x00000004 +#define EISR_RXBUFOFLO 0x00000008 +#define EISR_RXMEMERR 0x00000010 +#define EISR_RXPARERR 0x00000020 +#define EISR_TXEMPTY 0x00010000 +#define EISR_TXRTRY 0x00020000 +#define EISR_TXEXDEF 0x00040000 +#define EISR_TXLCOL 0x00080000 +#define EISR_TXGIANT 0x00100000 +#define EISR_TXBUFUFLO 0x00200000 +#define EISR_TXEXPLICIT 0x00400000 +#define EISR_TXCOLLWRAP 0x00800000 +#define EISR_TXDEFERWRAP 0x01000000 +#define EISR_TXMEMERR 0x02000000 +#define EISR_TXPARERR 0x04000000 + +#define ERCSR_THRESH_MASK 0x000001ff /* enet RX threshold */ +#define ERCSR_RX_TMR 0x40000000 /* simulation only */ +#define ERCSR_DIAG_OFLO 0x80000000 /* simulation only */ + +#define ERBR_ALIGNMENT 4096 +#define ERBR_L_RXRINGBASE_MASK 0xfffff000 + +#define ERBAR_BARRIER_BIT 0x0100 +#define ERBAR_RXBARR_MASK 0xffff0000 +#define ERBAR_RXBARR_SHIFT 16 + +#define ERCIR_RXCONSUME_MASK 0x00000fff + +#define ERPIR_RXPRODUCE_MASK 0x00000fff +#define ERPIR_ARM 0x80000000 + +#define ERTR_CNT_MASK 0x000007ff + +#define ETCSR_IPGT_MASK 0x0000007f +#define ETCSR_IPGR1_MASK 0x00007f00 +#define ETCSR_IPGR1_SHIFT 8 +#define ETCSR_IPGR2_MASK 0x007f0000 +#define ETCSR_IPGR2_SHIFT 16 +#define ETCSR_NOTXCLK 0x80000000 + +#define ETCDC_COLLCNT_MASK 0x0000ffff +#define ETCDC_DEFERCNT_MASK 0xffff0000 +#define ETCDC_DEFERCNT_SHIFT 16 + +#define ETBR_ALIGNMENT (64*1024) +#define ETBR_L_RINGSZ_MASK 0x00000001 +#define ETBR_L_RINGSZ128 0 +#define ETBR_L_RINGSZ512 1 +#define ETBR_L_TXRINGBASE_MASK 0xffffc000 + +#define ETCIR_TXCONSUME_MASK 0x0000ffff +#define ETCIR_IDLE 0x80000000 + +#define ETPIR_TXPRODUCE_MASK 0x0000ffff + +#define EBIR_TXBUFPROD_MASK 0x0000001f +#define EBIR_TXBUFCONS_MASK 0x00001f00 +#define EBIR_TXBUFCONS_SHIFT 8 +#define EBIR_RXBUFPROD_MASK 0x007fc000 +#define EBIR_RXBUFPROD_SHIFT 14 +#define EBIR_RXBUFCONS_MASK 0xff800000 +#define EBIR_RXBUFCONS_SHIFT 23 + +#define MICR_REGADDR_MASK 0x0000001f +#define MICR_PHYADDR_MASK 0x000003e0 +#define MICR_PHYADDR_SHIFT 5 +#define MICR_READTRIG 0x00000400 +#define MICR_BUSY 0x00000800 + +#define MIDR_DATA_MASK 0x0000ffff + +#define ERXBUF_IPCKSUM_MASK 0x0000ffff +#define ERXBUF_BYTECNT_MASK 0x07ff0000 +#define ERXBUF_BYTECNT_SHIFT 16 +#define ERXBUF_V 0x80000000 + +#define ERXBUF_CRCERR 0x00000001 /* aka RSV15 */ +#define ERXBUF_FRAMERR 0x00000002 /* aka RSV14 */ +#define ERXBUF_CODERR 0x00000004 /* aka RSV13 */ +#define ERXBUF_INVPREAMB 0x00000008 /* aka RSV18 */ +#define ERXBUF_LOLEN 0x00007000 /* aka RSV2_0 */ +#define ERXBUF_HILEN 0x03ff0000 /* aka RSV12_3 */ +#define ERXBUF_MULTICAST 0x04000000 /* aka RSV16 */ +#define ERXBUF_BROADCAST 0x08000000 /* aka RSV17 */ +#define ERXBUF_LONGEVENT 0x10000000 /* aka RSV19 */ +#define ERXBUF_BADPKT 0x20000000 /* aka RSV20 */ +#define ERXBUF_GOODPKT 0x40000000 /* aka RSV21 */ +#define ERXBUF_CARRIER 0x80000000 /* aka RSV22 */ + +#define ETXD_BYTECNT_MASK 0x000007ff /* total byte count */ +#define ETXD_INTWHENDONE 0x00001000 /* intr when done */ +#define ETXD_D0V 0x00010000 /* data 0 valid */ +#define ETXD_B1V 0x00020000 /* buf 1 valid */ +#define ETXD_B2V 0x00040000 /* buf 2 valid */ +#define ETXD_DOCHECKSUM 0x00080000 /* insert ip cksum */ +#define ETXD_CHKOFF_MASK 0x07f00000 /* cksum byte offset */ +#define ETXD_CHKOFF_SHIFT 20 + +#define ETXD_D0CNT_MASK 0x0000007f +#define ETXD_B1CNT_MASK 0x0007ff00 +#define ETXD_B1CNT_SHIFT 8 +#define ETXD_B2CNT_MASK 0x7ff00000 +#define ETXD_B2CNT_SHIFT 20 + +typedef enum ioc3_subdevs_e { + ioc3_subdev_ether, + ioc3_subdev_generic, + ioc3_subdev_nic, + ioc3_subdev_kbms, + ioc3_subdev_ttya, + ioc3_subdev_ttyb, + ioc3_subdev_ecpp, + ioc3_subdev_rt, + ioc3_nsubdevs +} ioc3_subdev_t; + +/* subdevice disable bits, + * from the standard INFO_LBL_SUBDEVS + */ +#define IOC3_SDB_ETHER (1<ie_v.iev_a = 0; } while (0) +#define IOERROR_SETVALUE(e,f,v) do { (e)->ie_ ## f = (v); (e)->ie_v.iev_b.ievb_ ## f = 1; } while (0) +#define IOERROR_FIELDVALID(e,f) (((e)->ie_v.iev_b.ievb_ ## f) != 0) +#define IOERROR_GETVALUE(e,f) (ASSERT(IOERROR_FIELDVALID(e,f)),((e)->ie_ ## f)) + +#if IP27 || IP35 +/* hub code likes to call the SysAD address "hubaddr" ... */ +#define ie_hubaddr ie_sysioaddr +#define ievb_hubaddr ievb_sysioaddr +#endif + +/* + * Error handling Modes. + */ +typedef enum { + MODE_DEVPROBE, /* Probing mode. Errors not fatal */ + MODE_DEVERROR, /* Error while system is running */ + MODE_DEVUSERERROR, /* Device Error created due to user mode access */ + MODE_DEVREENABLE /* Reenable pass */ +} ioerror_mode_t; + + +typedef int error_handler_f(void *, int, ioerror_mode_t, ioerror_t *); +typedef void *error_handler_arg_t; + +extern void ioerror_dump(char *, int, int, ioerror_t *); + +#ifdef ERROR_DEBUG +#define IOERROR_DUMP(x, y, z, t) ioerror_dump((x), (y), (z), (t)) +#define IOERR_PRINTF(x) (x) +#else +#define IOERROR_DUMP(x, y, z, t) +#define IOERR_PRINTF(x) +#endif /* ERROR_DEBUG */ + +#endif /* _ASM_SN_IOERROR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/ioerror_handling.h linux-2.4.0-test12-lia/include/asm-ia64/sn/ioerror_handling.h --- linux-2.4.0-test12/include/asm-ia64/sn/ioerror_handling.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/ioerror_handling.h Wed Dec 6 21:56:08 2000 @@ -0,0 +1,317 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_IOERROR_HANDLING_H +#define _ASM_SN_IOERROR_HANDLING_H + +#if __KERNEL__ + +/* + * Basic types required for io error handling interfaces. + */ + +/* + * Return code from the io error handling interfaces. + */ + +enum error_return_code_e { + /* Success */ + ERROR_RETURN_CODE_SUCCESS, + + /* Unknown failure */ + ERROR_RETURN_CODE_GENERAL_FAILURE, + + /* Nth error noticed while handling the first error */ + ERROR_RETURN_CODE_NESTED_CALL, + + /* State of the vertex is invalid */ + ERROR_RETURN_CODE_INVALID_STATE, + + /* Invalid action */ + ERROR_RETURN_CODE_INVALID_ACTION, + + /* Valid action but not cannot set it */ + ERROR_RETURN_CODE_CANNOT_SET_ACTION, + + /* Valid action but not possible for the current state */ + ERROR_RETURN_CODE_CANNOT_PERFORM_ACTION, + + /* Valid state but cannot change the state of the vertex to it */ + ERROR_RETURN_CODE_CANNOT_SET_STATE, + + /* ??? */ + ERROR_RETURN_CODE_DUPLICATE, + + /* Reached the root of the system critical graph */ + ERROR_RETURN_CODE_SYS_CRITICAL_GRAPH_BEGIN, + + /* Reached the leaf of the system critical graph */ + ERROR_RETURN_CODE_SYS_CRITICAL_GRAPH_ADD, + + /* Cannot shutdown the device in hw/sw */ + ERROR_RETURN_CODE_SHUTDOWN_FAILED, + + /* Cannot restart the device in hw/sw */ + ERROR_RETURN_CODE_RESET_FAILED, + + /* Cannot failover the io subsystem */ + ERROR_RETURN_CODE_FAILOVER_FAILED, + + /* No Jump Buffer exists */ + ERROR_RETURN_CODE_NO_JUMP_BUFFER +}; + +typedef uint64_t error_return_code_t; + +/* + * State of the vertex during error handling. + */ +enum error_state_e { + /* Ignore state */ + ERROR_STATE_IGNORE, + + /* Invalid state */ + ERROR_STATE_NONE, + + /* Trying to decipher the error bits */ + ERROR_STATE_LOOKUP, + + /* Trying to carryout the action decided upon after + * looking at the error bits + */ + ERROR_STATE_ACTION, + + /* Donot allow any other operations to this vertex from + * other parts of the kernel. This is also used to indicate + * that the device has been software shutdown. + */ + ERROR_STATE_SHUTDOWN, + + /* This is a transitory state when no new requests are accepted + * on behalf of the device. This is usually used when trying to + * quiesce all the outstanding operations and preparing the + * device for a failover / shutdown etc. + */ + ERROR_STATE_SHUTDOWN_IN_PROGRESS, + + /* This is the state when there is absolutely no activity going + * on wrt device. + */ + ERROR_STATE_SHUTDOWN_COMPLETE, + + /* This is the state when the device has issued a retry. */ + ERROR_STATE_RETRY, + + /* This is the normal state. This can also be used to indicate + * that the device has been software-enabled after software- + * shutting down previously. + */ + ERROR_STATE_NORMAL + +}; + +typedef uint64_t error_state_t; + +/* + * Generic error classes. This is used to classify errors after looking + * at the error bits and helpful in deciding on the action. + */ +enum error_class_e { + /* Unclassified error */ + ERROR_CLASS_UNKNOWN, + + /* LLP transmit error */ + ERROR_CLASS_LLP_XMIT, + + /* LLP receive error */ + ERROR_CLASS_LLP_RECV, + + /* Credit error */ + ERROR_CLASS_CREDIT, + + /* Timeout error */ + ERROR_CLASS_TIMEOUT, + + /* Access error */ + ERROR_CLASS_ACCESS, + + /* System coherency error */ + ERROR_CLASS_SYS_COHERENCY, + + /* Bad data error (ecc / parity etc) */ + ERROR_CLASS_BAD_DATA, + + /* Illegal request packet */ + ERROR_CLASS_BAD_REQ_PKT, + + /* Illegal response packet */ + ERROR_CLASS_BAD_RESP_PKT +}; + +typedef uint64_t error_class_t; + + +/* + * Error context which the error action can use. + */ +typedef void *error_context_t; +#define ERROR_CONTEXT_IGNORE ((error_context_t)-1ll) + + +/* + * Error action type. + */ +typedef error_return_code_t (*error_action_f)( error_context_t); +#define ERROR_ACTION_IGNORE ((error_action_f)-1ll) + +/* Typical set of error actions */ +typedef struct error_action_set_s { + error_action_f eas_panic; + error_action_f eas_shutdown; + error_action_f eas_abort; + error_action_f eas_retry; + error_action_f eas_failover; + error_action_f eas_log_n_ignore; + error_action_f eas_reset; +} error_action_set_t; + + +/* Set of priorites for in case mutliple error actions/states + * are trying to be prescribed for a device. + * NOTE : The ordering below encapsulates the priorities. Highest value + * corresponds to highest priority. + */ +enum error_priority_e { + ERROR_PRIORITY_IGNORE, + ERROR_PRIORITY_NONE, + ERROR_PRIORITY_NORMAL, + ERROR_PRIORITY_LOG, + ERROR_PRIORITY_FAILOVER, + ERROR_PRIORITY_RETRY, + ERROR_PRIORITY_ABORT, + ERROR_PRIORITY_SHUTDOWN, + ERROR_PRIORITY_RESTART, + ERROR_PRIORITY_PANIC +}; + +typedef uint64_t error_priority_t; + +/* Error state interfaces */ +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) +extern error_return_code_t error_state_set(devfs_handle_t,error_state_t); +extern error_state_t error_state_get(devfs_handle_t); +#endif + +/* System critical graph interfaces */ + +extern boolean_t is_sys_critical_vertex(devfs_handle_t); +extern devfs_handle_t sys_critical_first_child_get(devfs_handle_t); +extern devfs_handle_t sys_critical_next_child_get(devfs_handle_t); +extern devfs_handle_t sys_critical_parent_get(devfs_handle_t); +extern error_return_code_t sys_critical_graph_vertex_add(devfs_handle_t, + devfs_handle_t new); + +/* Error action interfaces */ + +extern error_return_code_t error_action_set(devfs_handle_t, + error_action_f, + error_context_t, + error_priority_t); +extern error_return_code_t error_action_perform(devfs_handle_t); + + +#define INFO_LBL_ERROR_SKIP_ENV "error_skip_env" + +#define v_error_skip_env_get(v, l) \ +hwgraph_info_get_LBL(v, INFO_LBL_ERROR_SKIP_ENV, (arbitrary_info_t *)&l) + +#define v_error_skip_env_set(v, l, r) \ +(r ? \ + hwgraph_info_replace_LBL(v, INFO_LBL_ERROR_SKIP_ENV, (arbitrary_info_t)l,0) :\ + hwgraph_info_add_LBL(v, INFO_LBL_ERROR_SKIP_ENV, (arbitrary_info_t)l)) + +#define v_error_skip_env_clear(v) \ +hwgraph_info_remove_LBL(v, INFO_LBL_ERROR_SKIP_ENV, 0) + +/* Skip point interfaces */ +extern error_return_code_t error_skip_point_jump(devfs_handle_t, boolean_t); +extern error_return_code_t error_skip_point_clear(devfs_handle_t); + +/* REFERENCED */ +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) + +inline static int +error_skip_point_mark(devfs_handle_t v) +{ + label_t *error_env = NULL; + int code = 0; + + /* Check if we have a valid hwgraph vertex */ +#ifdef IRIX + if (!dev_is_vertex(v)) + return(code); +#endif + + /* There is no error jump buffer for this device vertex. Allocate + * one. + */ + if (v_error_skip_env_get(v, error_env) != GRAPH_SUCCESS) { + error_env = kmem_zalloc(sizeof(label_t), KM_NOSLEEP); + /* Unable to allocate memory for jum buffer. This should + * be a very rare occurrence. + */ + if (!error_env) + return(-1); + /* Store the jump buffer information on the vertex.*/ + if (v_error_skip_env_set(v, error_env, 0) != GRAPH_SUCCESS) + return(-2); + } + ASSERT(v_error_skip_env_get(v, error_env) == GRAPH_SUCCESS); + code = setjmp(*error_env); +#ifdef IRIX + /* NOTE: It might be OK to leave the allocated jump buffer on the + * vertex. This can be used for later purposes. + */ + if (code) { + /* This is the case where a long jump has been taken from one + * one of the error handling interfaces. + */ + if (v_error_skip_env_clear(v, error_env) == GRAPH_SUCCESS) + kfree(error_env); + } +#endif + return(code); +} +#endif /* CONFIG_SGI_IO_ERROR_HANDLING */ + +typedef uint64_t counter_t; + +extern counter_t error_retry_count_get(devfs_handle_t); +extern error_return_code_t error_retry_count_set(devfs_handle_t,counter_t); +extern counter_t error_retry_count_increment(devfs_handle_t); +extern counter_t error_retry_count_decrement(devfs_handle_t); + +/* Except for the PIO Read error typically the other errors are handled in + * the context of an asynchronous error interrupt. + */ +#define IS_ERROR_INTR_CONTEXT(_ec) ((_ec & IOECODE_DMA) || \ + (_ec == IOECODE_PIO_WRITE)) + +/* Some convenience macros on device state. This state is accessed only + * thru the calls the io error handling layer. + */ +#if defined(CONFIG_SGI_IO_ERROR_HANDLING) +#define IS_DEVICE_SHUTDOWN(_d) (error_state_get(_d) == ERROR_STATE_SHUTDOWN) +#else +extern boolean_t is_device_shutdown(devfs_handle_t); +#define IS_DEVICE_SHUTDOWN(_d) (is_device_shutdown(_d)) +#endif + +#endif /* __KERNEL__ */ +#endif /* _ASM_SN_IOERROR_HANDLING_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/iograph.h linux-2.4.0-test12-lia/include/asm-ia64/sn/iograph.h --- linux-2.4.0-test12/include/asm-ia64/sn/iograph.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/iograph.h Wed Dec 6 21:56:08 2000 @@ -0,0 +1,200 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_IOGRAPH_H +#define _ASM_SN_IOGRAPH_H + +/* + * During initialization, platform-dependent kernel code establishes some + * basic elements of the hardware graph. This file contains edge and + * info labels that are used across various platforms -- it serves as an + * ad-hoc registry. + */ + +/* edges names */ +#define EDGE_LBL_BUS "bus" +#define EDGE_LBL_CONN ".connection" +#define EDGE_LBL_ECP "ecp" /* EPP/ECP plp */ +#define EDGE_LBL_ECPP "ecpp" +#define EDGE_LBL_GUEST ".guest" /* For IOC3 */ +#define EDGE_LBL_HOST ".host" /* For IOC3 */ +#define EDGE_LBL_PERFMON "mon" +#define EDGE_LBL_USRPCI "usrpci" +#define EDGE_LBL_VME "vmebus" +#define EDGE_LBL_BLOCK "block" +#define EDGE_LBL_BOARD "board" +#define EDGE_LBL_CHAR "char" +#define EDGE_LBL_CONTROLLER "controller" +#define EDGE_LBL_CPU "cpu" +#define EDGE_LBL_CPUNUM "cpunum" +#define EDGE_LBL_DISABLED "disabled" +#define EDGE_LBL_DISK "disk" +#define EDGE_LBL_DMA_ENGINE "dma_engine" /* Only available on + VMEbus now */ +#define EDGE_LBL_NET "net" /* all nw. devs */ +#define EDGE_LBL_EF "ef" /* For if_ef ethernet */ +#define EDGE_LBL_ET "et" /* For if_ee ethernet */ +#define EDGE_LBL_EC "ec" /* For if_ec2 ether */ +#define EDGE_LBL_ECF "ec" /* For if_ecf enet */ +#define EDGE_LBL_EM "ec" /* For O2 ether */ +#define EDGE_LBL_IPG "ipg" /* For IPG FDDI */ +#define EDGE_LBL_XPI "xpi" /* For IPG FDDI */ +#define EDGE_LBL_HIP "hip" /* For HIPPI */ +#define EDGE_LBL_GSN "gsn" /* For GSN */ +#define EDGE_LBL_ATM "atm" /* For ATM */ +#define EDGE_LBL_FXP "fxp" /* For FXP ether */ +#define EDGE_LBL_EP "ep" /* For eplex ether */ +#define EDGE_LBL_VFE "vfe" /* For VFE ether */ +#define EDGE_LBL_GFE "gfe" /* For GFE ether */ +#define EDGE_LBL_RNS "rns" /* RNS PCI FDDI card */ +#define EDGE_LBL_MTR "mtr" /* MTR PCI 802.5 card */ +#define EDGE_LBL_FV "fv" /* FV VME 802.5 card */ +#define EDGE_LBL_GTR "gtr" /* GTR GIO 802.5 card */ +#define EDGE_LBL_ISDN "isdn" /* Digi PCI ISDN-BRI card */ + +#define EDGE_LBL_EISA "eisa" +#define EDGE_LBL_ENET "ethernet" +#define EDGE_LBL_FLOPPY "floppy" +#define EDGE_LBL_PFD "pfd" /* For O2 pfd floppy */ +#define EDGE_LBL_FOP "fop" /* Fetchop pseudo device */ +#define EDGE_LBL_GIO "gio" +#define EDGE_LBL_HEART "heart" /* For RACER */ +#define EDGE_LBL_HPC "hpc" +#define EDGE_LBL_GFX "gfx" +#define EDGE_LBL_HUB "hub" /* For SN0 */ +#define EDGE_LBL_IBUS "ibus" /* For EVEREST */ +#define EDGE_LBL_INTERCONNECT "link" +#define EDGE_LBL_IO "io" +#define EDGE_LBL_IO4 "io4" /* For EVEREST */ +#define EDGE_LBL_IOC3 "ioc3" +#define EDGE_LBL_LUN "lun" +#define EDGE_LBL_MACE "mace" /* O2 mace */ +#define EDGE_LBL_MACHDEP "machdep" /* Platform depedent devices */ +#define EDGE_LBL_MASTER ".master" +#define EDGE_LBL_MEMORY "memory" +#define EDGE_LBL_META_ROUTER "metarouter" +#define EDGE_LBL_MIDPLANE "midplane" +#define EDGE_LBL_MODULE "module" +#define EDGE_LBL_NODE "node" +#define EDGE_LBL_NODENUM "nodenum" +#define EDGE_LBL_NVRAM "nvram" +#define EDGE_LBL_PARTITION "partition" +#define EDGE_LBL_PCI "pci" +#define EDGE_LBL_PORT "port" +#define EDGE_LBL_PROM "prom" +#define EDGE_LBL_RACK "rack" +#define EDGE_LBL_RDISK "rdisk" +#define EDGE_LBL_ROUTER "router" +#define EDGE_LBL_RPOS "bay" /* Position in rack */ +#define EDGE_LBL_SCSI "scsi" +#define EDGE_LBL_SCSI_CTLR "scsi_ctlr" +#define EDGE_LBL_SLOT "slot" +#define EDGE_LBL_TAPE "tape" +#define EDGE_LBL_TARGET "target" +#define EDGE_LBL_UNKNOWN "unknown" +#define EDGE_LBL_VOLUME "volume" +#define EDGE_LBL_VOLUME_HEADER "volume_header" +#define EDGE_LBL_XBOW "xbow" +#define EDGE_LBL_XIO "xio" +#define EDGE_LBL_XSWITCH ".xswitch" +#define EDGE_LBL_XTALK "xtalk" +#define EDGE_LBL_XWIDGET "xwidget" +#define EDGE_LBL_ELSC "elsc" +#define EDGE_LBL_L1 "L1" +#define EDGE_LBL_MADGE_TR "Madge-tokenring" +#define EDGE_LBL_XPLINK "xplink" /* Cross partition */ +#define EDGE_LBL_XPLINK_NET "net" /* XP network devs */ +#define EDGE_LBL_XPLINK_RAW "raw" /* XP Raw devs */ +#define EDGE_LBL_XPLINK_KERNEL "kernel" /* XP kernel devs */ +#define EDGE_LBL_XPLINK_ADMIN "admin" /* Partition admin */ +#define EDGE_LBL_KAIO "kaio" /* Kernel async i/o poll */ +#define EDGE_LBL_RPS "rps" /* redundant power supply */ +#define EDGE_LBL_XBOX_RPS "xbox_rps" /* redundant power supply for xbox unit */ +#define EDGE_LBL_IOBRICK "iobrick" +#define EDGE_LBL_PBRICK "pbrick" +#define EDGE_LBL_IBRICK "ibrick" +#define EDGE_LBL_XBRICK "xbrick" +#define EDGE_LBL_CPUBUS "cpubus" /* CPU Interfaces (SysAd) */ + +/* vertex info labels in hwgraph */ +#define INFO_LBL_CNODEID "_cnodeid" +#define INFO_LBL_CONTROLLER_NAME "_controller_name" +#define INFO_LBL_CPUBUS "_cpubus" +#define INFO_LBL_CPUID "_cpuid" +#define INFO_LBL_CPU_INFO "_cpu" +#define INFO_LBL_DETAIL_INVENT "_detail_invent" /* inventory data*/ +#define INFO_LBL_DEVICE_DESC "_device_desc" +#define INFO_LBL_DIAGVAL "_diag_reason" /* Reason disabled */ +#define INFO_LBL_DKIOTIME "_dkiotime" +#define INFO_LBL_DRIVER "_driver" /* points to attached device_driver_t */ +#define INFO_LBL_ELSC "_elsc" +#define INFO_LBL_FC_PORTNAME "_fc_portname" +#define INFO_LBL_GIOIO "_gioio" +#define INFO_LBL_GFUNCS "_gioio_ops" /* ops vector for gio providers */ +#define INFO_LBL_HUB_INFO "_hubinfo" +#define INFO_LBL_HWGFSLIST "_hwgfs_list" +#define INFO_LBL_TRAVERSE "_hwg_traverse" /* hwgraph traverse function */ +#define INFO_LBL_INVENT "_invent" /* inventory data */ +#define INFO_LBL_MLRESET "_mlreset" /* present if device preinitialized */ +#define INFO_LBL_MODULE_INFO "_module" /* module data ptr */ +#define INFO_LBL_MONDATA "_mon" /* monitor data ptr */ +#define INFO_LBL_MDPERF_DATA "_mdperf" /* mdperf monitoring*/ +#define INFO_LBL_NIC "_nic" +#define INFO_LBL_NODE_INFO "_node" +#define INFO_LBL_PCIBR_HINTS "_pcibr_hints" +#define INFO_LBL_PCIIO "_pciio" +#define INFO_LBL_PFUNCS "_pciio_ops" /* ops vector for gio providers */ +#define INFO_LBL_PERMISSIONS "_permissions" /* owner, uid, gid */ +#define INFO_LBL_ROUTER_INFO "_router" +#define INFO_LBL_SUBDEVS "_subdevs" /* subdevice enable bits */ +#define INFO_LBL_VME_FUNCS "_vmeio_ops" /* ops vector for VME providers */ +#define INFO_LBL_XSWITCH "_xswitch" +#define INFO_LBL_XSWITCH_ID "_xswitch_id" +#define INFO_LBL_XSWITCH_VOL "_xswitch_volunteer" +#define INFO_LBL_XFUNCS "_xtalk_ops" /* ops vector for gio providers */ +#define INFO_LBL_XWIDGET "_xwidget" +#define INFO_LBL_GRIO_DSK "_grio_disk" /* guaranteed rate I/O */ +#define INFO_LBL_ASYNC_ATTACH "_async_attach" /* parallel attachment */ +#define INFO_LBL_GFXID "_gfxid" /* gfx pipe ID #s */ +/* Device/Driver Admin directive labels */ +#define ADMIN_LBL_INTR_TARGET "INTR_TARGET" /* Target cpu for device interrupts*/ +#define ADMIN_LBL_INTR_SWLEVEL "INTR_SWLEVEL" /* Priority level of the ithread */ + +#define ADMIN_LBL_DMATRANS_NODE "PCIBUS_DMATRANS_NODE" /* Node used for + * 32-bit Direct + * Mapping I/O + */ +#define ADMIN_LBL_DISABLED "DISABLE" /* Device has been disabled */ +#define ADMIN_LBL_DETACH "DETACH" /* Device has been detached */ + +#define ADMIN_LBL_THREAD_PRI "thread_priority" + /* Driver adminstrator + * hint parameter for + * thread priority + */ +#define ADMIN_LBL_THREAD_CLASS "thread_class" + /* Driver adminstrator + * hint parameter for + * thread priority + * default class + */ +/* Special reserved info labels (also hwgfs attributes) */ +#define _DEVNAME_ATTR "_devname" /* device name */ +#define _DRIVERNAME_ATTR "_drivername" /* driver name */ +#define _INVENT_ATTR "_inventory" /* device inventory data */ +#define _MASTERNODE_ATTR "_masternode" /* node that "controls" device */ + +/* Info labels that begin with '_' cannot be overwritten by an attr_set call */ +#define INFO_LBL_RESERVED(name) ((name)[0] == '_') + +#if defined(__KERNEL__) +void init_all_devices(void); +#endif /* __KERNEL__ */ + +#endif /* _ASM_SN_IOGRAPH_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/klconfig.h linux-2.4.0-test12-lia/include/asm-ia64/sn/klconfig.h --- linux-2.4.0-test12/include/asm-ia64/sn/klconfig.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/klconfig.h Wed Dec 13 23:52:34 2000 @@ -0,0 +1,960 @@ +/* $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. + * + * Derived from IRIX . + * + * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc. + * Copyright (C) 1999 by Ralf Baechle + */ +#ifndef _ASM_SN_KLCONFIG_H +#define _ASM_SN_KLCONFIG_H + +/* + * klconfig.h + */ + +/* + * The KLCONFIG structures store info about the various BOARDs found + * during Hardware Discovery. In addition, it stores info about the + * components found on the BOARDs. + */ + +/* + * WARNING: + * Certain assembly language routines (notably xxxxx.s) in the IP27PROM + * will depend on the format of the data structures in this file. In + * most cases, rearranging the fields can seriously break things. + * Adding fields in the beginning or middle can also break things. + * Add fields if necessary, to the end of a struct in such a way + * that offsets of existing fields do not change. + */ + +#include +#include +#include +#include +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#include +#include +#include +// #include +// #include +#include +#include +#include +#include +#include + +#endif /* CONFIG_SGI_IP35 ... */ + +#define KLCFGINFO_MAGIC 0xbeedbabe + +typedef s32 klconf_off_t; + +#define MAX_MODULE_ID 255 +#define SIZE_PAD 4096 /* 4k padding for structures */ +#if (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && defined(BRINGUP) /* MAX_SLOTS_PER_NODE??? */ +/* + * 1 NODE brick, 2 Router bricks (1 local, 1 meta), 6 XIO Widgets, + * 1 Midplane (midplane will likely become IO brick when Bruce cleans + * up IP35 klconfig) + */ +#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 1) +#else +/* + * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, + * 2 Midplanes assuming no pci card cages + */ +#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2) +#endif + +/* XXX if each node is guranteed to have some memory */ + +#define MAX_PCI_DEVS 8 + +/* lboard_t->brd_flags fields */ +/* All bits in this field are currently used. Try the pad fields if + you need more flag bits */ + +#define ENABLE_BOARD 0x01 +#define FAILED_BOARD 0x02 +#define DUPLICATE_BOARD 0x04 /* Boards like midplanes/routers which + are discovered twice. Use one of them */ +#define VISITED_BOARD 0x08 /* Used for compact hub numbering. */ +#define LOCAL_MASTER_IO6 0x10 /* master io6 for that node */ +#define GLOBAL_MASTER_IO6 0x20 +#define THIRD_NIC_PRESENT 0x40 /* for future use */ +#define SECOND_NIC_PRESENT 0x80 /* addons like MIO are present */ + +/* klinfo->flags fields */ + +#define KLINFO_ENABLE 0x01 /* This component is enabled */ +#define KLINFO_FAILED 0x02 /* This component failed */ +#define KLINFO_DEVICE 0x04 /* This component is a device */ +#define KLINFO_VISITED 0x08 /* This component has been visited */ +#define KLINFO_CONTROLLER 0x10 /* This component is a device controller */ +#define KLINFO_INSTALL 0x20 /* Install a driver */ +#define KLINFO_HEADLESS 0x40 /* Headless (or hubless) component */ +#define IS_CONSOLE_IOC3(i) ((((klinfo_t *)i)->flags) & KLINFO_INSTALL) + +#define GB2 0x80000000 + +#define MAX_RSV_PTRS 32 + +/* Structures to manage various data storage areas */ +/* The numbers must be contiguous since the array index i + is used in the code to allocate various areas. +*/ + +#define BOARD_STRUCT 0 +#define COMPONENT_STRUCT 1 +#define ERRINFO_STRUCT 2 +#define KLMALLOC_TYPE_MAX (ERRINFO_STRUCT + 1) +#define DEVICE_STRUCT 3 + + +typedef struct console_s { +#if defined(CONFIG_IA64_SGI_IO) /* FIXME */ + __psunsigned_t uart_base; + __psunsigned_t config_base; + __psunsigned_t memory_base; +#else + unsigned long uart_base; + unsigned long config_base; + unsigned long memory_base; +#endif + short baud; + short flag; + int type; + nasid_t nasid; + char wid; + char npci; + nic_t baseio_nic; +} console_t; + +typedef struct klc_malloc_hdr { + klconf_off_t km_base; + klconf_off_t km_limit; + klconf_off_t km_current; +} klc_malloc_hdr_t; + +/* Functions/macros needed to use this structure */ + +typedef struct kl_config_hdr { + u64 ch_magic; /* set this to KLCFGINFO_MAGIC */ + u32 ch_version; /* structure version number */ + klconf_off_t ch_malloc_hdr_off; /* offset of ch_malloc_hdr */ + klconf_off_t ch_cons_off; /* offset of ch_cons */ + klconf_off_t ch_board_info; /* the link list of boards */ + console_t ch_cons_info; /* address info of the console */ + klc_malloc_hdr_t ch_malloc_hdr[KLMALLOC_TYPE_MAX]; + confidence_t ch_sw_belief; /* confidence that software is bad*/ + confidence_t ch_sn0net_belief; /* confidence that sn0net is bad */ +} kl_config_hdr_t; + + +#define KL_CONFIG_HDR(_nasid) ((kl_config_hdr_t *)(KLCONFIG_ADDR(_nasid))) +#define KL_CONFIG_INFO_OFFSET(_nasid) \ + (KL_CONFIG_HDR(_nasid)->ch_board_info) +#define KL_CONFIG_INFO_SET_OFFSET(_nasid, _off) \ + (KL_CONFIG_HDR(_nasid)->ch_board_info = (_off)) + +#if !defined(SIMULATED_KLGRAPH) +#define KL_CONFIG_INFO(_nasid) \ + (lboard_t *)((KL_CONFIG_HDR(_nasid)->ch_board_info) ? \ + NODE_OFFSET_TO_K0((_nasid), KL_CONFIG_HDR(_nasid)->ch_board_info) : \ + 0) +#else +/* + * For Fake klgraph info. + */ +extern kl_config_hdr_t *linux_klcfg; +#define KL_CONFIG_INFO(_nasid) (lboard_t *)((ulong)linux_klcfg->ch_board_info | 0xe000000000000000) +#endif /* CONFIG_IA64_SGI_IO */ + +#define KL_CONFIG_MAGIC(_nasid) (KL_CONFIG_HDR(_nasid)->ch_magic) + +#define KL_CONFIG_CHECK_MAGIC(_nasid) \ + (KL_CONFIG_HDR(_nasid)->ch_magic == KLCFGINFO_MAGIC) + +#define KL_CONFIG_HDR_INIT_MAGIC(_nasid) \ + (KL_CONFIG_HDR(_nasid)->ch_magic = KLCFGINFO_MAGIC) + +/* --- New Macros for the changed kl_config_hdr_t structure --- */ + +#if defined(CONFIG_IA64_SGI_IO) +#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\ + ((__psunsigned_t)_k + (_k->ch_malloc_hdr_off))) +#else +#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\ + (unsigned long)_k + (_k->ch_malloc_hdr_off))) +#endif + +#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n)) + +#if defined(CONFIG_IA64_SGI_IO) +#define PTR_CH_CONS_INFO(_k) ((console_t *)\ + ((__psunsigned_t)_k + (_k->ch_cons_off))) +#else +#define PTR_CH_CONS_INFO(_k) ((console_t *)\ + ((unsigned long)_k + (_k->ch_cons_off))) +#endif + +#define KL_CONFIG_CH_CONS_INFO(_n) PTR_CH_CONS_INFO(KL_CONFIG_HDR(_n)) + +/* ------------------------------------------------------------- */ + +#define KL_CONFIG_INFO_START(_nasid) \ + (klconf_off_t)(KLCONFIG_OFFSET(_nasid) + sizeof(kl_config_hdr_t)) + +#define KL_CONFIG_BOARD_NASID(_brd) ((_brd)->brd_nasid) +#define KL_CONFIG_BOARD_SET_NEXT(_brd, _off) ((_brd)->brd_next = (_off)) + +#define KL_CONFIG_DUPLICATE_BOARD(_brd) ((_brd)->brd_flags & DUPLICATE_BOARD) + +#define XBOW_PORT_TYPE_HUB(_xbowp, _link) \ + ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_HUB) +#define XBOW_PORT_TYPE_IO(_xbowp, _link) \ + ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_IO) + +#define XBOW_PORT_IS_ENABLED(_xbowp, _link) \ + ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_ENABLE) +#define XBOW_PORT_NASID(_xbowp, _link) \ + ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_nasid) + +#define XBOW_PORT_IO 0x1 +#define XBOW_PORT_HUB 0x2 +#define XBOW_PORT_ENABLE 0x4 + +#define SN0_PORT_FENCE_SHFT 0 +#define SN0_PORT_FENCE_MASK (1 << SN0_PORT_FENCE_SHFT) + +/* + * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD + * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to + * the LOCAL/current NODE. REMOTE means it is attached to a different + * node.(TBD - Need a way to treat ROUTER boards.) + * + * There are 2 different structures to represent these boards - + * lboard - Local board, rboard - remote board. These 2 structures + * can be arbitrarily mixed in the LINKED LIST of BOARDs. (Refer + * Figure below). The first byte of the rboard or lboard structure + * is used to find out its type - no unions are used. + * If it is a lboard, then the config info of this board will be found + * on the local node. (LOCAL NODE BASE + offset value gives pointer to + * the structure. + * If it is a rboard, the local structure contains the node number + * and the offset of the beginning of the LINKED LIST on the remote node. + * The details of the hardware on a remote node can be built locally, + * if required, by reading the LINKED LIST on the remote node and + * ignoring all the rboards on that node. + * + * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the + * First board info on the remote node. The remote node list is + * traversed as the local list, using the REMOTE BASE ADDRESS and not + * the local base address and ignoring all rboard values. + * + * + KLCONFIG + + +------------+ +------------+ +------------+ +------------+ + | lboard | +-->| lboard | +-->| rboard | +-->| lboard | + +------------+ | +------------+ | +------------+ | +------------+ + | board info | | | board info | | |errinfo,bptr| | | board info | + +------------+ | +------------+ | +------------+ | +------------+ + | offset |--+ | offset |--+ | offset |--+ |offset=NULL | + +------------+ +------------+ +------------+ +------------+ + + + +------------+ + | board info | + +------------+ +--------------------------------+ + | compt 1 |------>| type, rev, diaginfo, size ... | (CPU) + +------------+ +--------------------------------+ + | compt 2 |--+ + +------------+ | +--------------------------------+ + | ... | +--->| type, rev, diaginfo, size ... | (MEM_BANK) + +------------+ +--------------------------------+ + | errinfo |--+ + +------------+ | +--------------------------------+ + +--->|r/l brd errinfo,compt err flags | + +--------------------------------+ + + * + * Each BOARD consists of COMPONENTs and the BOARD structure has + * pointers (offsets) to its COMPONENT structure. + * The COMPONENT structure has version info, size and speed info, revision, + * error info and the NIC info. This structure can accomodate any + * BOARD with arbitrary COMPONENT composition. + * + * The ERRORINFO part of each BOARD has error information + * that describes errors about the BOARD itself. It also has flags to + * indicate the COMPONENT(s) on the board that have errors. The error + * information specific to the COMPONENT is present in the respective + * COMPONENT structure. + * + * The ERRORINFO structure is also treated like a COMPONENT, ie. the + * BOARD has pointers(offset) to the ERRORINFO structure. The rboard + * structure also has a pointer to the ERRORINFO structure. This is + * the place to store ERRORINFO about a REMOTE NODE, if the HUB on + * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where + * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can + * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info + * which is present on the REMOTE NODE.(TBD) + * REMOTE ERRINFO can be stored on any of the nearest nodes + * or on all the nearest nodes.(TBD) + * Like BOARD structures, REMOTE ERRINFO structures can be built locally + * using the rboard errinfo pointer. + * + * In order to get useful information from this Data organization, a set of + * interface routines are provided (TBD). The important thing to remember while + * manipulating the structures, is that, the NODE number information should + * be used. If the NODE is non-zero (remote) then each offset should + * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. + * This includes offsets for BOARDS, COMPONENTS and ERRORINFO. + * + * Note that these structures do not provide much info about connectivity. + * That info will be part of HWGRAPH, which is an extension of the cfg_t + * data structure. (ref IP27prom/cfg.h) It has to be extended to include + * the IO part of the Network(TBD). + * + * The data structures below define the above concepts. + */ + +/* + * Values for CPU types + */ +#define KL_CPU_R4000 0x1 /* Standard R4000 */ +#define KL_CPU_TFP 0x2 /* TFP processor */ +#define KL_CPU_R10000 0x3 /* R10000 (T5) */ +#define KL_CPU_NONE (-1) /* no cpu present in slot */ + +/* + * IP27 BOARD classes + */ + +#define KLCLASS_MASK 0xf0 +#define KLCLASS_NONE 0x00 +#define KLCLASS_NODE 0x10 /* CPU, Memory and HUB board */ +#define KLCLASS_CPU KLCLASS_NODE +#define KLCLASS_IO 0x20 /* BaseIO, 4 ch SCSI, ethernet, FDDI + and the non-graphics widget boards */ +#define KLCLASS_ROUTER 0x30 /* Router board */ +#define KLCLASS_MIDPLANE 0x40 /* We need to treat this as a board + so that we can record error info */ +#define KLCLASS_GFX 0x50 /* graphics boards */ + +#define KLCLASS_PSEUDO_GFX 0x60 /* HDTV type cards that use a gfx + * hw ifc to xtalk and are not gfx + * class for sw purposes */ + +#define KLCLASS_IOBRICK 0x70 /* IP35 iobrick */ + +#define KLCLASS_MAX 7 /* Bump this if a new CLASS is added */ +#define KLTYPE_MAX 10 /* Bump this if a new CLASS is added */ + +#define KLCLASS_UNKNOWN 0xf0 + +#define KLCLASS(_x) ((_x) & KLCLASS_MASK) + +/* + * IP27 board types + */ + +#define KLTYPE_MASK 0x0f +#define KLTYPE_NONE 0x00 +#define KLTYPE_EMPTY 0x00 + +#define KLTYPE_WEIRDCPU (KLCLASS_CPU | 0x0) +#define KLTYPE_IP27 (KLCLASS_CPU | 0x1) /* 2 CPUs(R10K) per board */ +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define KLTYPE_IP35 KLTYPE_IP27 +#endif + +#define KLTYPE_WEIRDIO (KLCLASS_IO | 0x0) +#define KLTYPE_BASEIO (KLCLASS_IO | 0x1) /* IOC3, SuperIO, Bridge, SCSI */ +#define KLTYPE_IO6 KLTYPE_BASEIO /* Additional name */ +#define KLTYPE_4CHSCSI (KLCLASS_IO | 0x2) +#define KLTYPE_MSCSI KLTYPE_4CHSCSI /* Additional name */ +#define KLTYPE_ETHERNET (KLCLASS_IO | 0x3) +#define KLTYPE_MENET KLTYPE_ETHERNET /* Additional name */ +#define KLTYPE_FDDI (KLCLASS_IO | 0x4) +#define KLTYPE_UNUSED (KLCLASS_IO | 0x5) /* XXX UNUSED */ +#define KLTYPE_HAROLD (KLCLASS_IO | 0x6) /* PCI SHOE BOX */ +#define KLTYPE_PCI KLTYPE_HAROLD +#define KLTYPE_VME (KLCLASS_IO | 0x7) /* Any 3rd party VME card */ +#define KLTYPE_MIO (KLCLASS_IO | 0x8) +#define KLTYPE_FC (KLCLASS_IO | 0x9) +#define KLTYPE_LINC (KLCLASS_IO | 0xA) +#define KLTYPE_TPU (KLCLASS_IO | 0xB) /* Tensor Processing Unit */ +#define KLTYPE_GSN_A (KLCLASS_IO | 0xC) /* Main GSN board */ +#define KLTYPE_GSN_B (KLCLASS_IO | 0xD) /* Auxiliary GSN board */ + +#define KLTYPE_GFX (KLCLASS_GFX | 0x0) /* unknown graphics type */ +#define KLTYPE_GFX_KONA (KLCLASS_GFX | 0x1) /* KONA graphics on IP27 */ +#define KLTYPE_GFX_MGRA (KLCLASS_GFX | 0x3) /* MGRAS graphics on IP27 */ + +#define KLTYPE_WEIRDROUTER (KLCLASS_ROUTER | 0x0) +#define KLTYPE_ROUTER (KLCLASS_ROUTER | 0x1) +#define KLTYPE_ROUTER2 KLTYPE_ROUTER /* Obsolete! */ +#define KLTYPE_NULL_ROUTER (KLCLASS_ROUTER | 0x2) +#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3) + +#define KLTYPE_WEIRDMIDPLANE (KLCLASS_MIDPLANE | 0x0) +#define KLTYPE_MIDPLANE8 (KLCLASS_MIDPLANE | 0x1) /* 8 slot backplane */ +#define KLTYPE_MIDPLANE KLTYPE_MIDPLANE8 +#define KLTYPE_PBRICK_XBOW (KLCLASS_MIDPLANE | 0x2) + +#define KLTYPE_IOBRICK (KLCLASS_IOBRICK | 0x0) +#define KLTYPE_IBRICK (KLCLASS_IOBRICK | 0x1) +#define KLTYPE_PBRICK (KLCLASS_IOBRICK | 0x2) +#define KLTYPE_XBRICK (KLCLASS_IOBRICK | 0x3) + +#define KLTYPE_PBRICK_BRIDGE KLTYPE_PBRICK + +/* The value of type should be more than 8 so that hinv prints + * out the board name from the NIC string. For values less than + * 8 the name of the board needs to be hard coded in a few places. + * When bringup started nic names had not standardized and so we + * had to hard code. (For people interested in history.) + */ +#define KLTYPE_XTHD (KLCLASS_PSEUDO_GFX | 0x9) + +#define KLTYPE_UNKNOWN (KLCLASS_UNKNOWN | 0xf) + +#define KLTYPE(_x) ((_x) & KLTYPE_MASK) +#define IS_MIO_PRESENT(l) ((l->brd_type == KLTYPE_BASEIO) && \ + (l->brd_flags & SECOND_NIC_PRESENT)) +#define IS_MIO_IOC3(l,n) (IS_MIO_PRESENT(l) && (n > 2)) + +/* + * board structures + */ + +#define MAX_COMPTS_PER_BRD 24 + +#define LOCAL_BOARD 1 +#define REMOTE_BOARD 2 + +#define LBOARD_STRUCT_VERSION 2 + +typedef struct lboard_s { + klconf_off_t brd_next; /* Next BOARD */ + unsigned char struct_type; /* type of structure, local or remote */ + unsigned char brd_type; /* type+class */ + unsigned char brd_sversion; /* version of this structure */ + unsigned char brd_brevision; /* board revision */ + unsigned char brd_promver; /* board prom version, if any */ + unsigned char brd_flags; /* Enabled, Disabled etc */ + unsigned char brd_slot; /* slot number */ + unsigned short brd_debugsw; /* Debug switches */ + moduleid_t brd_module; /* module to which it belongs */ + partid_t brd_partition; /* Partition number */ + unsigned short brd_diagval; /* diagnostic value */ + unsigned short brd_diagparm; /* diagnostic parameter */ + unsigned char brd_inventory; /* inventory history */ + unsigned char brd_numcompts; /* Number of components */ + nic_t brd_nic; /* Number in CAN */ + nasid_t brd_nasid; /* passed parameter */ + klconf_off_t brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */ + klconf_off_t brd_errinfo; /* Board's error information */ + struct lboard_s *brd_parent; /* Logical parent for this brd */ + devfs_handle_t brd_graph_link; /* vertex hdl to connect extern compts */ + confidence_t brd_confidence; /* confidence that the board is bad */ + nasid_t brd_owner; /* who owns this board */ + unsigned char brd_nic_flags; /* To handle 8 more NICs */ + char brd_name[32]; +} lboard_t; + + +/* + * Make sure we pass back the calias space address for local boards. + * klconfig board traversal and error structure extraction defines. + */ + +#define BOARD_SLOT(_brd) ((_brd)->brd_slot) + +#define KLCF_CLASS(_brd) KLCLASS((_brd)->brd_type) +#define KLCF_TYPE(_brd) KLTYPE((_brd)->brd_type) +#define KLCF_REMOTE(_brd) (((_brd)->struct_type & LOCAL_BOARD) ? 0 : 1) +#define KLCF_NUM_COMPS(_brd) ((_brd)->brd_numcompts) +#define KLCF_MODULE_ID(_brd) ((_brd)->brd_module) + +#ifndef SIMULATED_KLGRAPH +#define KLCF_NEXT(_brd) ((_brd)->brd_next ? (lboard_t *)((_brd)->brd_next): NULL) +#define KLCF_COMP(_brd, _ndx) \ + (klinfo_t *)(NODE_OFFSET_TO_K0(NASID_GET(_brd), \ + (_brd)->brd_compts[(_ndx)])) +#define KLCF_COMP_ERROR(_brd, _comp) \ + (NODE_OFFSET_TO_K0(NASID_GET(_brd), (_comp)->errinfo)) + +#else +/* + * For fake klgraph info. + */ +#define KLCF_COMP(_brd, _ndx) (klinfo_t *)((ulong) 0xe000000000000000 |((_brd)->brd_compts[(_ndx)])) +#define KLCF_NEXT(_brd) ((_brd)->brd_next ? (lboard_t *)((ulong) 0xe000000000000000 | (_brd->brd_next)) : NULL) +#define KLCF_COMP_ERROR(_brd, _comp) (_brd = _brd , (_comp)->errinfo) + +#endif /* SIMULATED_KLGRAPH */ + +#define KLCF_COMP_TYPE(_comp) ((_comp)->struct_type) +#define KLCF_BRIDGE_W_ID(_comp) ((_comp)->physid) /* Widget ID */ + + + +/* + * Generic info structure. This stores common info about a + * component. + */ + +typedef struct klinfo_s { /* Generic info */ + unsigned char struct_type; /* type of this structure */ + unsigned char struct_version; /* version of this structure */ + unsigned char flags; /* Enabled, disabled etc */ + unsigned char revision; /* component revision */ + unsigned short diagval; /* result of diagnostics */ + unsigned short diagparm; /* diagnostic parameter */ + unsigned char inventory; /* previous inventory status */ + unsigned short partid; /* widget part number */ + nic_t nic; /* MUst be aligned properly */ + unsigned char physid; /* physical id of component */ + unsigned int virtid; /* virtual id as seen by system */ + unsigned char widid; /* Widget id - if applicable */ + nasid_t nasid; /* node number - from parent */ + char pad1; /* pad out structure. */ + char pad2; /* pad out structure. */ + COMPONENT *arcs_compt; /* ptr to the arcs struct for ease*/ + klconf_off_t errinfo; /* component specific errors */ + unsigned short pad3; /* pci fields have moved over to */ + unsigned short pad4; /* klbri_t */ +} klinfo_t ; + +#define KLCONFIG_INFO_ENABLED(_i) ((_i)->flags & KLINFO_ENABLE) +/* + * Component structures. + * Following are the currently identified components: + * CPU, HUB, MEM_BANK, + * XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE) + * BRIDGE, IOC3, SuperIO, SCSI, FDDI + * ROUTER + * GRAPHICS + */ +#define KLSTRUCT_UNKNOWN 0 +#define KLSTRUCT_CPU 1 +#define KLSTRUCT_HUB 2 +#define KLSTRUCT_MEMBNK 3 +#define KLSTRUCT_XBOW 4 +#define KLSTRUCT_BRI 5 +#define KLSTRUCT_IOC3 6 +#define KLSTRUCT_PCI 7 +#define KLSTRUCT_VME 8 +#define KLSTRUCT_ROU 9 +#define KLSTRUCT_GFX 10 +#define KLSTRUCT_SCSI 11 +#define KLSTRUCT_FDDI 12 +#define KLSTRUCT_MIO 13 +#define KLSTRUCT_DISK 14 +#define KLSTRUCT_TAPE 15 +#define KLSTRUCT_CDROM 16 +#define KLSTRUCT_HUB_UART 17 +#define KLSTRUCT_IOC3ENET 18 +#define KLSTRUCT_IOC3UART 19 +#define KLSTRUCT_UNUSED 20 /* XXX UNUSED */ +#define KLSTRUCT_IOC3PCKM 21 +#define KLSTRUCT_RAD 22 +#define KLSTRUCT_HUB_TTY 23 +#define KLSTRUCT_IOC3_TTY 24 + +/* Early Access IO proms are compatible + only with KLSTRUCT values upto 24. */ + +#define KLSTRUCT_FIBERCHANNEL 25 +#define KLSTRUCT_MOD_SERIAL_NUM 26 +#define KLSTRUCT_IOC3MS 27 +#define KLSTRUCT_TPU 28 +#define KLSTRUCT_GSN_A 29 +#define KLSTRUCT_GSN_B 30 +#define KLSTRUCT_XTHD 31 + +/* + * These are the indices of various components within a lboard structure. + */ + +#define IP27_CPU0_INDEX 0 +#define IP27_CPU1_INDEX 1 +#define IP27_HUB_INDEX 2 +#define IP27_MEM_INDEX 3 + +#define BASEIO_BRIDGE_INDEX 0 +#define BASEIO_IOC3_INDEX 1 +#define BASEIO_SCSI1_INDEX 2 +#define BASEIO_SCSI2_INDEX 3 + +#define MIDPLANE_XBOW_INDEX 0 +#define ROUTER_COMPONENT_INDEX 0 + +#define CH4SCSI_BRIDGE_INDEX 0 + +/* Info holders for various hardware components */ + +typedef u64 *pci_t; +typedef u64 *vmeb_t; +typedef u64 *vmed_t; +typedef u64 *fddi_t; +typedef u64 *scsi_t; +typedef u64 *mio_t; +typedef u64 *graphics_t; +typedef u64 *router_t; + +/* + * The port info in ip27_cfg area translates to a lboart_t in the + * KLCONFIG area. But since KLCONFIG does not use pointers, lboart_t + * is stored in terms of a nasid and a offset from start of KLCONFIG + * area on that nasid. + */ +typedef struct klport_s { + nasid_t port_nasid; + unsigned char port_flag; + klconf_off_t port_offset; +} klport_t; + +typedef struct klcpu_s { /* CPU */ + klinfo_t cpu_info; + unsigned short cpu_prid; /* Processor PRID value */ + unsigned short cpu_fpirr; /* FPU IRR value */ + unsigned short cpu_speed; /* Speed in MHZ */ + unsigned short cpu_scachesz; /* secondary cache size in MB */ + unsigned short cpu_scachespeed;/* secondary cache speed in MHz */ +} klcpu_t ; + +#define CPU_STRUCT_VERSION 2 + +typedef struct klhub_s { /* HUB */ + klinfo_t hub_info; + uint hub_flags; /* PCFG_HUB_xxx flags */ + klport_t hub_port; /* hub is connected to this */ + nic_t hub_box_nic; /* nic of containing box */ + klconf_off_t hub_mfg_nic; /* MFG NIC string */ + u64 hub_speed; /* Speed of hub in HZ */ +} klhub_t ; + +typedef struct klhub_uart_s { /* HUB */ + klinfo_t hubuart_info; + uint hubuart_flags; /* PCFG_HUB_xxx flags */ + nic_t hubuart_box_nic; /* nic of containing box */ +} klhub_uart_t ; + +#define MEMORY_STRUCT_VERSION 2 + +typedef struct klmembnk_s { /* MEMORY BANK */ + klinfo_t membnk_info; + short membnk_memsz; /* Total memory in megabytes */ + short membnk_dimm_select; /* bank to physical addr mapping*/ + short membnk_bnksz[MD_MEM_BANKS]; /* Memory bank sizes */ + short membnk_attr; +} klmembnk_t ; + +#define KLCONFIG_MEMBNK_SIZE(_info, _bank) \ + ((_info)->membnk_bnksz[(_bank)]) + + +#define MEMBNK_PREMIUM 1 +#define KLCONFIG_MEMBNK_PREMIUM(_info, _bank) \ + ((_info)->membnk_attr & (MEMBNK_PREMIUM << (_bank))) + +#define MAX_SERIAL_NUM_SIZE 10 + +typedef struct klmod_serial_num_s { + klinfo_t snum_info; + union { + char snum_str[MAX_SERIAL_NUM_SIZE]; + unsigned long long snum_int; + } snum; +} klmod_serial_num_t; + +/* Macros needed to access serial number structure in lboard_t. + Hard coded values are necessary since we cannot treat + serial number struct as a component without losing compatibility + between prom versions. */ + +#define GET_SNUM_COMP(_l) ((klmod_serial_num_t *)\ + KLCF_COMP(_l, _l->brd_numcompts)) + +#define MAX_XBOW_LINKS 16 + +typedef struct klxbow_s { /* XBOW */ + klinfo_t xbow_info ; + klport_t xbow_port_info[MAX_XBOW_LINKS] ; /* Module number */ + int xbow_master_hub_link; + /* type of brd connected+component struct ptr+flags */ +} klxbow_t ; + +#define MAX_PCI_SLOTS 8 + +typedef struct klpci_device_s { + s32 pci_device_id; /* 32 bits of vendor/device ID. */ + s32 pci_device_pad; /* 32 bits of padding. */ +} klpci_device_t; + +#define BRIDGE_STRUCT_VERSION 2 + +typedef struct klbri_s { /* BRIDGE */ + klinfo_t bri_info ; + unsigned char bri_eprominfo ; /* IO6prom connected to bridge */ + unsigned char bri_bustype ; /* PCI/VME BUS bridge/GIO */ + pci_t pci_specific ; /* PCI Board config info */ + klpci_device_t bri_devices[MAX_PCI_DEVS] ; /* PCI IDs */ + klconf_off_t bri_mfg_nic ; +} klbri_t ; + +#define MAX_IOC3_TTY 2 + +typedef struct klioc3_s { /* IOC3 */ + klinfo_t ioc3_info ; + unsigned char ioc3_ssram ; /* Info about ssram */ + unsigned char ioc3_nvram ; /* Info about nvram */ + klinfo_t ioc3_superio ; /* Info about superio */ + klconf_off_t ioc3_tty_off ; + klinfo_t ioc3_enet ; + klconf_off_t ioc3_enet_off ; + klconf_off_t ioc3_kbd_off ; +} klioc3_t ; + +#define MAX_VME_SLOTS 8 + +typedef struct klvmeb_s { /* VME BRIDGE - PCI CTLR */ + klinfo_t vmeb_info ; + vmeb_t vmeb_specific ; + klconf_off_t vmeb_brdinfo[MAX_VME_SLOTS] ; /* VME Board config info */ +} klvmeb_t ; + +typedef struct klvmed_s { /* VME DEVICE - VME BOARD */ + klinfo_t vmed_info ; + vmed_t vmed_specific ; + klconf_off_t vmed_brdinfo[MAX_VME_SLOTS] ; /* VME Board config info */ +} klvmed_t ; + +#define ROUTER_VECTOR_VERS 2 + +/* XXX - Don't we need the number of ports here?!? */ +typedef struct klrou_s { /* ROUTER */ + klinfo_t rou_info ; + uint rou_flags ; /* PCFG_ROUTER_xxx flags */ + nic_t rou_box_nic ; /* nic of the containing module */ + klport_t rou_port[MAX_ROUTER_PORTS + 1] ; /* array index 1 to 6 */ + klconf_off_t rou_mfg_nic ; /* MFG NIC string */ + u64 rou_vector; /* vector from master node */ +} klrou_t ; + +/* + * Graphics Controller/Device + * + * (IP27/IO6) Prom versions 6.13 (and 6.5.1 kernels) and earlier + * used a couple different structures to store graphics information. + * For compatibility reasons, the newer data structure preserves some + * of the layout so that fields that are used in the old versions remain + * in the same place (with the same info). Determination of what version + * of this structure we have is done by checking the cookie field. + */ +#define KLGFX_COOKIE 0x0c0de000 + +typedef struct klgfx_s { /* GRAPHICS Device */ + klinfo_t gfx_info; + klconf_off_t old_gndevs; /* for compatibility with older proms */ + klconf_off_t old_gdoff0; /* for compatibility with older proms */ + uint cookie; /* for compatibility with older proms */ + uint moduleslot; + struct klgfx_s *gfx_next_pipe; + graphics_t gfx_specific; + klconf_off_t pad0; /* for compatibility with older proms */ + klconf_off_t gfx_mfg_nic; +} klgfx_t; + +typedef struct klxthd_s { + klinfo_t xthd_info ; + klconf_off_t xthd_mfg_nic ; /* MFG NIC string */ +} klxthd_t ; + +typedef struct kltpu_s { /* TPU board */ + klinfo_t tpu_info ; + klconf_off_t tpu_mfg_nic ; /* MFG NIC string */ +} kltpu_t ; + +typedef struct klgsn_s { /* GSN board */ + klinfo_t gsn_info ; + klconf_off_t gsn_mfg_nic ; /* MFG NIC string */ +} klgsn_t ; + +#define MAX_SCSI_DEVS 16 + +/* + * NOTE: THis is the max sized kl* structure and is used in klmalloc.c + * to allocate space of type COMPONENT. Make sure that if the size of + * any other component struct becomes more than this, then redefine + * that as the size to be klmalloced. + */ + +typedef struct klscsi_s { /* SCSI Controller */ + klinfo_t scsi_info ; + scsi_t scsi_specific ; + unsigned char scsi_numdevs ; + klconf_off_t scsi_devinfo[MAX_SCSI_DEVS] ; +} klscsi_t ; + +typedef struct klscdev_s { /* SCSI device */ + klinfo_t scdev_info ; + struct scsidisk_data *scdev_cfg ; /* driver fills up this */ +} klscdev_t ; + +typedef struct klttydev_s { /* TTY device */ + klinfo_t ttydev_info ; + struct terminal_data *ttydev_cfg ; /* driver fills up this */ +} klttydev_t ; + +typedef struct klenetdev_s { /* ENET device */ + klinfo_t enetdev_info ; + struct net_data *enetdev_cfg ; /* driver fills up this */ +} klenetdev_t ; + +typedef struct klkbddev_s { /* KBD device */ + klinfo_t kbddev_info ; + struct keyboard_data *kbddev_cfg ; /* driver fills up this */ +} klkbddev_t ; + +typedef struct klmsdev_s { /* mouse device */ + klinfo_t msdev_info ; + void *msdev_cfg ; +} klmsdev_t ; + +#define MAX_FDDI_DEVS 10 /* XXX Is this true */ + +typedef struct klfddi_s { /* FDDI */ + klinfo_t fddi_info ; + fddi_t fddi_specific ; + klconf_off_t fddi_devinfo[MAX_FDDI_DEVS] ; +} klfddi_t ; + +typedef struct klmio_s { /* MIO */ + klinfo_t mio_info ; + mio_t mio_specific ; +} klmio_t ; + + +typedef union klcomp_s { + klcpu_t kc_cpu; + klhub_t kc_hub; + klmembnk_t kc_mem; + klxbow_t kc_xbow; + klbri_t kc_bri; + klioc3_t kc_ioc3; + klvmeb_t kc_vmeb; + klvmed_t kc_vmed; + klrou_t kc_rou; + klgfx_t kc_gfx; + klscsi_t kc_scsi; + klscdev_t kc_scsi_dev; + klfddi_t kc_fddi; + klmio_t kc_mio; + klmod_serial_num_t kc_snum ; +} klcomp_t; + +typedef union kldev_s { /* for device structure allocation */ + klscdev_t kc_scsi_dev ; + klttydev_t kc_tty_dev ; + klenetdev_t kc_enet_dev ; + klkbddev_t kc_kbd_dev ; +} kldev_t ; + +/* Data structure interface routines. TBD */ + +/* Include launch info in this file itself? TBD */ + +/* + * TBD - Can the ARCS and device driver related info also be included in the + * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t + * structure, viz private to the IO4prom. + */ + +/* + * TBD - Allocation issues. + * + * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component, + * errinfo and allocate from them, or have a single heap and allocate all + * structures from it. Debug is easier in the former method since we can + * dump all similar structs in one command, but there will be lots of holes, + * in memory and max limits are needed for number of structures. + * Another way to make it organized, is to have a union of all components + * and allocate a aligned chunk of memory greater than the biggest + * component. + */ + +typedef union { + lboard_t *lbinfo ; +} biptr_t ; + + +#define BRI_PER_XBOW 6 +#define PCI_PER_BRI 8 +#define DEV_PER_PCI 16 + + +/* Virtual dipswitch values (starting from switch "7"): */ + +#define VDS_NOGFX 0x8000 /* Don't enable gfx and autoboot */ +#define VDS_NOMP 0x100 /* Don't start slave processors */ +#define VDS_MANUMODE 0x80 /* Manufacturing mode */ +#define VDS_NOARB 0x40 /* No bootmaster arbitration */ +#define VDS_PODMODE 0x20 /* Go straight to POD mode */ +#define VDS_NO_DIAGS 0x10 /* Don't run any diags after BM arb */ +#define VDS_DEFAULTS 0x08 /* Use default environment values */ +#define VDS_NOMEMCLEAR 0x04 /* Don't run mem cfg code */ +#define VDS_2ND_IO4 0x02 /* Boot from the second IO4 */ +#define VDS_DEBUG_PROM 0x01 /* Print PROM debugging messages */ + +/* external declarations of Linux kernel functions. */ + +extern lboard_t *find_lboard(lboard_t *start, unsigned char type); +extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type); +extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type); +extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int); + + +#if defined(CONFIG_IA64_SGI_IO) +extern xwidgetnum_t nodevertex_widgetnum_get(devfs_handle_t node_vtx); +extern devfs_handle_t nodevertex_xbow_peer_get(devfs_handle_t node_vtx); +extern lboard_t *find_gfxpipe(int pipenum); +extern void setup_gfxpipe_link(devfs_handle_t vhdl,int pipenum); +extern lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_class); +extern lboard_t *find_lboard_module_class(lboard_t *start, moduleid_t mod, + unsigned char brd_class); +extern lboard_t *find_nic_lboard(lboard_t *, nic_t); +extern lboard_t *find_nic_type_lboard(nasid_t, unsigned char, nic_t); +extern lboard_t *find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot); +extern lboard_t *find_lboard_module(lboard_t *start, moduleid_t mod); +extern lboard_t *get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name); +extern int config_find_nic_router(nasid_t, nic_t, lboard_t **, klrou_t**); +extern int config_find_nic_hub(nasid_t, nic_t, lboard_t **, klhub_t**); +extern int config_find_xbow(nasid_t, lboard_t **, klxbow_t**); +extern klcpu_t *get_cpuinfo(cpuid_t cpu); +extern int update_klcfg_cpuinfo(nasid_t, int); +extern void board_to_path(lboard_t *brd, char *path); +extern moduleid_t get_module_id(nasid_t nasid); +extern void nic_name_convert(char *old_name, char *new_name); +extern int module_brds(nasid_t nasid, lboard_t **module_brds, int n); +extern lboard_t *brd_from_key(uint64_t key); +extern void device_component_canonical_name_get(lboard_t *,klinfo_t *, + char *); +extern int board_serial_number_get(lboard_t *,char *); +extern int is_master_baseio(nasid_t,moduleid_t,slotid_t); +extern nasid_t get_actual_nasid(lboard_t *brd) ; +extern net_vec_t klcfg_discover_route(lboard_t *, lboard_t *, int); +#else /* CONFIG_IA64_SGI_IO */ +extern klcpu_t *sn_get_cpuinfo(cpuid_t cpu); +#endif /* CONFIG_IA64_SGI_IO */ + +#endif /* _ASM_SN_KLCONFIG_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/kldir.h linux-2.4.0-test12-lia/include/asm-ia64/sn/kldir.h --- linux-2.4.0-test12/include/asm-ia64/sn/kldir.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/kldir.h Wed Dec 13 23:51:58 2000 @@ -0,0 +1,245 @@ +/* $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. + * + * Derived from IRIX , revision 1.21. + * + * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc. + * Copyright (C) 1999 by Ralf Baechle + */ +#ifndef _ASM_SN_KLDIR_H +#define _ASM_SN_KLDIR_H + +#if defined(CONFIG_IA64_SGI_IO) +#include +#endif + +/* + * The kldir memory area resides at a fixed place in each node's memory and + * provides pointers to most other IP27 memory areas. This allows us to + * resize and/or relocate memory areas at a later time without breaking all + * firmware and kernels that use them. Indices in the array are + * permanently dedicated to areas listed below. Some memory areas (marked + * below) reside at a permanently fixed location, but are included in the + * directory for completeness. + */ + +#define KLDIR_MAGIC 0x434d5f53505f5357 + +/* + * The upper portion of the memory map applies during boot + * only and is overwritten by IRIX/SYMMON. + * + * MEMORY MAP PER NODE + * + * 0x2000000 (32M) +-----------------------------------------+ + * | IO6 BUFFERS FOR FLASH ENET IOC3 | + * 0x1F80000 (31.5M) +-----------------------------------------+ + * | IO6 TEXT/DATA/BSS/stack | + * 0x1C00000 (30M) +-----------------------------------------+ + * | IO6 PROM DEBUG TEXT/DATA/BSS/stack | + * 0x0800000 (28M) +-----------------------------------------+ + * | IP27 PROM TEXT/DATA/BSS/stack | + * 0x1B00000 (27M) +-----------------------------------------+ + * | IP27 CFG | + * 0x1A00000 (26M) +-----------------------------------------+ + * | Graphics PROM | + * 0x1800000 (24M) +-----------------------------------------+ + * | 3rd Party PROM drivers | + * 0x1600000 (22M) +-----------------------------------------+ + * | | + * | Free | + * | | + * +-----------------------------------------+ + * | UNIX DEBUG Version | + * 0x190000 (2M--) +-----------------------------------------+ + * | SYMMON | + * | (For UNIX Debug only) | + * 0x34000 (208K) +-----------------------------------------+ + * | SYMMON STACK [NUM_CPU_PER_NODE] | + * | (For UNIX Debug only) | + * 0x25000 (148K) +-----------------------------------------+ + * | KLCONFIG - II (temp) | + * | | + * | ---------------------------- | + * | | + * | UNIX NON-DEBUG Version | + * 0x19000 (100K) +-----------------------------------------+ + * + * + * The lower portion of the memory map contains information that is + * permanent and is used by the IP27PROM, IO6PROM and IRIX. + * + * 0x19000 (100K) +-----------------------------------------+ + * | | + * | PI Error Spools (32K) | + * | | + * 0x12000 (72K) +-----------------------------------------+ + * | Unused | + * 0x11c00 (71K) +-----------------------------------------+ + * | CPU 1 NMI Eframe area | + * 0x11a00 (70.5K) +-----------------------------------------+ + * | CPU 0 NMI Eframe area | + * 0x11800 (70K) +-----------------------------------------+ + * | CPU 1 NMI Register save area | + * 0x11600 (69.5K) +-----------------------------------------+ + * | CPU 0 NMI Register save area | + * 0x11400 (69K) +-----------------------------------------+ + * | GDA (1k) | + * 0x11000 (68K) +-----------------------------------------+ + * | Early cache Exception stack | + * | and/or | + * | kernel/io6prom nmi registers | + * 0x10800 (66k) +-----------------------------------------+ + * | cache error eframe | + * 0x10400 (65K) +-----------------------------------------+ + * | Exception Handlers (UALIAS copy) | + * 0x10000 (64K) +-----------------------------------------+ + * | | + * | | + * | KLCONFIG - I (permanent) (48K) | + * | | + * | | + * | | + * 0x4000 (16K) +-----------------------------------------+ + * | NMI Handler (Protected Page) | + * 0x3000 (12K) +-----------------------------------------+ + * | ARCS PVECTORS (master node only) | + * 0x2c00 (11K) +-----------------------------------------+ + * | ARCS TVECTORS (master node only) | + * 0x2800 (10K) +-----------------------------------------+ + * | LAUNCH [NUM_CPU] | + * 0x2400 (9K) +-----------------------------------------+ + * | Low memory directory (KLDIR) | + * 0x2000 (8K) +-----------------------------------------+ + * | ARCS SPB (1K) | + * 0x1000 (4K) +-----------------------------------------+ + * | Early cache Exception stack | + * | and/or | + * | kernel/io6prom nmi registers | + * 0x800 (2k) +-----------------------------------------+ + * | cache error eframe | + * 0x400 (1K) +-----------------------------------------+ + * | Exception Handlers | + * 0x0 (0K) +-----------------------------------------+ + */ + +#ifdef LANGUAGE_ASSEMBLY +#define KLDIR_OFF_MAGIC 0x00 +#define KLDIR_OFF_OFFSET 0x08 +#define KLDIR_OFF_POINTER 0x10 +#define KLDIR_OFF_SIZE 0x18 +#define KLDIR_OFF_COUNT 0x20 +#define KLDIR_OFF_STRIDE 0x28 +#endif /* LANGUAGE_ASSEMBLY */ + +#if !defined(CONFIG_IA64_SGI_IO) + +/* + * This is defined here because IP27_SYMMON_STK_SIZE must be at least what + * we define here. Since it's set up in the prom. We can't redefine it later + * and expect more space to be allocated. The way to find out the true size + * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE + * for a particular node. + */ +#define SYMMON_STACK_SIZE 0x8000 + +#if defined (PROM) || defined (SABLE) + +/* + * These defines are prom version dependent. No code other than the IP27 + * prom should attempt to use these values. + */ +#define IP27_LAUNCH_OFFSET 0x2400 +#define IP27_LAUNCH_SIZE 0x400 +#define IP27_LAUNCH_COUNT 2 +#define IP27_LAUNCH_STRIDE 0x200 + +#define IP27_KLCONFIG_OFFSET 0x4000 +#define IP27_KLCONFIG_SIZE 0xc000 +#define IP27_KLCONFIG_COUNT 1 +#define IP27_KLCONFIG_STRIDE 0 + +#define IP27_NMI_OFFSET 0x3000 +#define IP27_NMI_SIZE 0x40 +#define IP27_NMI_COUNT 2 +#define IP27_NMI_STRIDE 0x40 + +#define IP27_PI_ERROR_OFFSET 0x12000 +#define IP27_PI_ERROR_SIZE 0x4000 +#define IP27_PI_ERROR_COUNT 1 +#define IP27_PI_ERROR_STRIDE 0 + +#define IP27_SYMMON_STK_OFFSET 0x25000 +#define IP27_SYMMON_STK_SIZE 0xe000 +#define IP27_SYMMON_STK_COUNT 2 +/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */ +#define IP27_SYMMON_STK_STRIDE 0x7000 + +#define IP27_FREEMEM_OFFSET 0x19000 +#define IP27_FREEMEM_SIZE -1 +#define IP27_FREEMEM_COUNT 1 +#define IP27_FREEMEM_STRIDE 0 + +#endif /* PROM || SABLE*/ +/* + * There will be only one of these in a partition so the IO6 must set it up. + */ +#define IO6_GDA_OFFSET 0x11000 +#define IO6_GDA_SIZE 0x400 +#define IO6_GDA_COUNT 1 +#define IO6_GDA_STRIDE 0 + +/* + * save area of kernel nmi regs in the prom format + */ +#define IP27_NMI_KREGS_OFFSET 0x11400 +#define IP27_NMI_KREGS_CPU_SIZE 0x200 +/* + * save area of kernel nmi regs in eframe format + */ +#define IP27_NMI_EFRAME_OFFSET 0x11800 +#define IP27_NMI_EFRAME_SIZE 0x200 + +#define KLDIR_ENT_SIZE 0x40 +#define KLDIR_MAX_ENTRIES (0x400 / 0x40) + +#endif /* !CONFIG_IA64_SGI_IO */ + +#ifdef _LANGUAGE_C +typedef struct kldir_ent_s { + u64 magic; /* Indicates validity of entry */ + off_t offset; /* Offset from start of node space */ +#if defined(CONFIG_IA64_SGI_IO) /* FIXME */ + __psunsigned_t pointer; /* Pointer to area in some cases */ +#else + unsigned long pointer; /* Pointer to area in some cases */ +#endif + size_t size; /* Size in bytes */ + u64 count; /* Repeat count if array, 1 if not */ + size_t stride; /* Stride if array, 0 if not */ + char rsvd[16]; /* Pad entry to 0x40 bytes */ + /* NOTE: These 16 bytes are used in the Partition KLDIR + entry to store partition info. Refer to klpart.h for this. */ +} kldir_ent_t; +#endif /* _LANGUAGE_C */ + +#if defined(CONFIG_IA64_SGI_IO) + +#define KLDIR_ENT_SIZE 0x40 +#define KLDIR_MAX_ENTRIES (0x400 / 0x40) + +/* + * The actual offsets of each memory area are machine-dependent + */ +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#else +#error "kldir.h is currently defined for IP27 and IP35 platforms only" +#endif + +#endif /* CONFIG_IA64_SGI_IO */ + +#endif /* _ASM_SN_KLDIR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/ksys/elsc.h linux-2.4.0-test12-lia/include/asm-ia64/sn/ksys/elsc.h --- linux-2.4.0-test12/include/asm-ia64/sn/ksys/elsc.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/ksys/elsc.h Wed Dec 13 23:52:35 2000 @@ -0,0 +1,162 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_KSYS_ELSC_H +#define _ASM_SN_KSYS_ELSC_H + +#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif + +// #include + +#define ELSC_I2C_ADDR 0x08 +#define ELSC_I2C_HUB0 0x09 +#define ELSC_I2C_HUB1 0x0a +#define ELSC_I2C_HUB2 0x0b +#define ELSC_I2C_HUB3 0x0c + +#define ELSC_PACKET_MAX 96 +#define ELSC_ACP_MAX 86 /* 84+cr+lf */ +#define ELSC_LINE_MAX (ELSC_ACP_MAX - 2) + +/* + * ELSC character queue type for I/O + */ + +#define ELSC_QSIZE 128 /* Power of 2 is more efficient */ + +typedef sc_cq_t elsc_cq_t; + +/* + * ELSC structure passed around as handle + */ + +typedef l1sc_t elsc_t; + +void elsc_init(elsc_t *e, nasid_t nasid); + +int elsc_process(elsc_t *e); +int elsc_msg_check(elsc_t *e, char *msg, int msg_max); +int elsc_msg_callback(elsc_t *e, + void (*callback)(void *callback_data, char *msg), + void *callback_data); +#if 0 +char *elsc_errmsg(int code); + +int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len); +int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len); +int elsc_nvram_magic(elsc_t *e); +#endif + +int elsc_command(elsc_t *e, int only_if_message); +int elsc_parse(elsc_t *e, char *p1, char *p2, char *p3); +int elsc_ust_write(elsc_t *e, uchar_t c); +int elsc_ust_read(elsc_t *e, char *c); + + + +/* + * System controller commands + */ + +int elsc_version(elsc_t *e, char *result); +#if 0 +int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2); +int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2); +#endif +int elsc_module_set(elsc_t *e, int module); +int elsc_module_get(elsc_t *e); +int elsc_partition_set(elsc_t *e, int partition); +int elsc_partition_get(elsc_t *e); +int elsc_domain_set(elsc_t *e, int domain); +int elsc_domain_get(elsc_t *e); +int elsc_cluster_set(elsc_t *e, int cluster); +int elsc_cluster_get(elsc_t *e); +int elsc_cell_set(elsc_t *e, int cell); +int elsc_cell_get(elsc_t *e); +int elsc_bist_set(elsc_t *e, char bist_status); +char elsc_bist_get(elsc_t *e); +int elsc_lock(elsc_t *e, + int retry_interval_usec, + int timeout_usec, u_char lock_val); +int elsc_unlock(elsc_t *e); +int elsc_display_char(elsc_t *e, int led, int chr); +int elsc_display_digit(elsc_t *e, int led, int num, int l_case); +#if 0 +int elsc_display_mesg(elsc_t *e, char *chr); /* 8-char input */ +int elsc_password_set(elsc_t *e, char *password); /* 4-char input */ +int elsc_password_get(elsc_t *e, char *password); /* 4-char output */ +int elsc_rpwr_query(elsc_t *e, int is_master); +int elsc_power_query(elsc_t *e); +int elsc_power_down(elsc_t *e, int sec); +int elsc_power_cycle(elsc_t *e); +int elsc_system_reset(elsc_t *e); +int elsc_dip_switches(elsc_t *e); +int elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose); +#endif + +int _elsc_hbt(elsc_t *e, int ival, int rdly); + +#define elsc_hbt_enable(e, ival, rdly) _elsc_hbt(e, ival, rdly) +#define elsc_hbt_disable(e) _elsc_hbt(e, 0, 0) +#define elsc_hbt_send(e) _elsc_hbt(e, 0, 1) + +/* + * Routines for using the ELSC as a UART. There's a version of each + * routine that takes a pointer to an elsc_t, and another version that + * gets the pointer by calling a user-supplied global routine "get_elsc". + * The latter version is useful when the elsc is employed for stdio. + */ + +#define ELSCUART_FLASH 0x3c /* LED pattern */ + +elsc_t *get_elsc(void); + +int elscuart_probe(void); +void elscuart_init(void *); +int elscuart_poll(void); +int elscuart_readc(void); +int elscuart_getc(void); +int elscuart_putc(int); +int elscuart_puts(char *); +char *elscuart_gets(char *, int); +int elscuart_flush(void); + + + +/* + * Error codes + * + * The possible ELSC error codes are a superset of the I2C error codes, + * so ELSC error codes begin at -100. + */ + +#define ELSC_ERROR_NONE 0 + +#define ELSC_ERROR_CMD_SEND -100 /* Error sending command */ +#define ELSC_ERROR_CMD_CHECKSUM -101 /* Command checksum bad */ +#define ELSC_ERROR_CMD_UNKNOWN -102 /* Unknown command */ +#define ELSC_ERROR_CMD_ARGS -103 /* Invalid argument(s) */ +#define ELSC_ERROR_CMD_PERM -104 /* Permission denied */ +#define ELSC_ERROR_CMD_STATE -105 /* not allowed in this state*/ + +#define ELSC_ERROR_RESP_TIMEOUT -110 /* ELSC response timeout */ +#define ELSC_ERROR_RESP_CHECKSUM -111 /* Response checksum bad */ +#define ELSC_ERROR_RESP_FORMAT -112 /* Response format error */ +#define ELSC_ERROR_RESP_DIR -113 /* Response direction error */ + +#define ELSC_ERROR_MSG_LOST -120 /* Queue full; msg. lost */ +#define ELSC_ERROR_LOCK_TIMEOUT -121 /* ELSC response timeout */ +#define ELSC_ERROR_DATA_SEND -122 /* Error sending data */ +#define ELSC_ERROR_NIC -123 /* NIC processing error */ +#define ELSC_ERROR_NVMAGIC -124 /* Bad magic no. in NVRAM */ +#define ELSC_ERROR_MODULE -125 /* Moduleid processing err */ + +#endif /* _ASM_SN_KSYS_ELSC_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/ksys/i2c.h linux-2.4.0-test12-lia/include/asm-ia64/sn/ksys/i2c.h --- linux-2.4.0-test12/include/asm-ia64/sn/ksys/i2c.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/ksys/i2c.h Wed Dec 6 21:56:09 2000 @@ -0,0 +1,77 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_KSYS_I2C_H +#define _ASM_SN_KSYS_I2C_H + +#if _STANDALONE +# include "rtc.h" +#else +# define rtc_time() (GET_LOCAL_RTC * NSEC_PER_CYCLE / 1000) +# define rtc_sleep us_delay +# define rtc_time_t uint64_t +#endif + +typedef u_char i2c_addr_t; /* 7-bit address */ + +int i2c_init(nasid_t); + +int i2c_probe(nasid_t nasid, rtc_time_t timeout); + +int i2c_arb(nasid_t, rtc_time_t timeout, rtc_time_t *token_start); + +int i2c_master_xmit(nasid_t, + i2c_addr_t addr, + u_char *buf, + int len_max, + int *len_ptr, + rtc_time_t timeout, + int only_if_message); + +int i2c_master_recv(nasid_t, + i2c_addr_t addr, + u_char *buf, + int len_max, + int *len_ptr, + int emblen, + rtc_time_t timeout, + int only_if_message); + +int i2c_master_xmit_recv(nasid_t, + i2c_addr_t addr, + u_char *xbuf, + int xlen_max, + int *xlen_ptr, + u_char *rbuf, + int rlen_max, + int *rlen_ptr, + int emblen, + rtc_time_t timeout, + int only_if_message); + +char *i2c_errmsg(int code); + +/* + * Error codes + */ + +#define I2C_ERROR_NONE 0 +#define I2C_ERROR_INIT -1 /* Initialization error */ +#define I2C_ERROR_STATE -2 /* Unexpected chip state */ +#define I2C_ERROR_NAK -3 /* Addressed slave not responding */ +#define I2C_ERROR_TO_ARB -4 /* Timeout waiting for sysctlr arb */ +#define I2C_ERROR_TO_BUSY -5 /* Timeout waiting for busy bus */ +#define I2C_ERROR_TO_SENDA -6 /* Timeout sending address byte */ +#define I2C_ERROR_TO_SENDD -7 /* Timeout sending data byte */ +#define I2C_ERROR_TO_RECVA -8 /* Timeout receiving address byte */ +#define I2C_ERROR_TO_RECVD -9 /* Timeout receiving data byte */ +#define I2C_ERROR_NO_MESSAGE -10 /* No message was waiting */ +#define I2C_ERROR_NO_ELSC -11 /* ELSC is disabled for access */ + +#endif /* _ASM_SN_KSYS_I2C_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/ksys/l1.h linux-2.4.0-test12-lia/include/asm-ia64/sn/ksys/l1.h --- linux-2.4.0-test12/include/asm-ia64/sn/ksys/l1.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/ksys/l1.h Wed Dec 13 23:52:14 2000 @@ -0,0 +1,375 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_KSYS_L1_H +#define _ASM_SN_KSYS_L1_H + +#include +#include +#include + +#define BRL1_QSIZE 128 /* power of 2 is more efficient */ +#define BRL1_BUFSZ 264 /* needs to be large enough + * to hold 2 flags, escaped + * CRC, type/subchannel byte, + * and escaped payload + */ + +#define BRL1_IQS 32 +#define BRL1_OQS 4 + + +typedef struct sc_cq_s { + u_char buf[BRL1_QSIZE]; + int ipos, opos, tent_next; +} sc_cq_t; + +/* An l1sc_t struct can be associated with the local (C-brick) L1 or an L1 + * on an R-brick. In the R-brick case, the l1sc_t records a vector path + * to the R-brick's junk bus UART. In the C-brick case, we just use the + * following flag to denote the local uart. + * + * This value can't be confused with a network vector because the least- + * significant nibble of a network vector cannot be greater than 8. + */ +#define BRL1_LOCALUART ((net_vec_t)0xf) + +/* L1<->Bedrock reserved subchannels */ + +/* console channels */ +#define SC_CONS_CPU0 0x00 +#define SC_CONS_CPU1 0x01 +#define SC_CONS_CPU2 0x02 +#define SC_CONS_CPU3 0x03 + +#define L1_ELSCUART_SUBCH(p) (p) +#define L1_ELSCUART_CPU(ch) (ch) + +#define SC_CONS_SYSTEM CPUS_PER_NODE + +/* mapping subchannels to queues */ +#define MAP_IQ(s) (s) +#define MAP_OQ(s) (s) + +#define BRL1_NUM_SUBCHANS 32 +#define BRL1_CMD_SUBCH 16 +#define BRL1_EVENT_SUBCH (BRL1_NUM_SUBCHANS - 1) +#define BRL1_SUBCH_RSVD 0 +#define BRL1_SUBCH_FREE (-1) + +/* constants for L1 hwgraph vertex info */ +#define CBRICK_L1 (__psint_t)1 +#define IOBRICK_L1 (__psint_t)2 +#define RBRICK_L1 (__psint_t)3 + + +struct l1sc_s; +typedef void (*brl1_notif_t)(struct l1sc_s *, int); +typedef int (*brl1_uartf_t)(struct l1sc_s *); + +/* structure for controlling a subchannel */ +typedef struct brl1_sch_s { + int use; /* if this subchannel is free, + * use == BRL1_SUBCH_FREE */ + uint target; /* type, rack and slot of component to + * which this subchannel is directed */ + int packet_arrived; /* true if packet arrived on + * this subchannel */ + sc_cq_t * iqp; /* input queue for this subchannel */ + sv_t arrive_sv; /* used to wait for a packet */ + lock_t data_lock; /* synchronize access to input queues and + * other fields of the brl1_sch_s struct */ + brl1_notif_t tx_notify; /* notify higher layer that transmission may + * continue */ + brl1_notif_t rx_notify; /* notify higher layer that a packet has been + * received */ +} brl1_sch_t; + +/* br<->l1 protocol states */ +#define BRL1_IDLE 0 +#define BRL1_FLAG 1 +#define BRL1_HDR 2 +#define BRL1_BODY 3 +#define BRL1_ESC 4 +#define BRL1_RESET 7 + + +#ifndef _LANGUAGE_ASSEMBLY + +/* + * l1sc_t structure-- tracks protocol state, open subchannels, etc. + */ +typedef struct l1sc_s { + nasid_t nasid; /* nasid with which this instance + * of the structure is associated */ + moduleid_t modid; /* module id of this brick */ + u_char verbose; /* non-zero if elscuart routines should + * prefix output */ + net_vec_t uart; /* vector path to UART, or BRL1_LOCALUART */ + int sent; /* number of characters sent */ + int send_len; /* number of characters in send buf */ + brl1_uartf_t putc_f; /* pointer to UART putc function */ + brl1_uartf_t getc_f; /* pointer to UART getc function */ + + lock_t send_lock; /* arbitrates send synchronization */ + lock_t recv_lock; /* arbitrates uart receive access */ + lock_t subch_lock; /* arbitrates subchannel allocation */ + cpuid_t intr_cpu; /* cpu that receives L1 interrupts */ + + u_char send_in_use; /* non-zero if send buffer contains an + * unsent or partially-sent packet */ + u_char fifo_space; /* current depth of UART send FIFO */ + + u_char brl1_state; /* current state of the receive side */ + u_char brl1_last_hdr; /* last header byte received */ + + char send[BRL1_BUFSZ]; /* send buffer */ + + int sol; /* "start of line" (see elscuart routines) */ + int cons_listen; /* non-zero if the elscuart interface should + * also check the system console subchannel */ + brl1_sch_t subch[BRL1_NUM_SUBCHANS]; + /* subchannels provided by link */ + + sc_cq_t garbage_q; /* a place to put unsolicited packets */ + sc_cq_t oq[BRL1_OQS]; /* elscuart output queues */ + +} l1sc_t; + + +/* error codes */ +#define BRL1_VALID 0 +#define BRL1_FULL_Q (-1) +#define BRL1_CRC (-2) +#define BRL1_PROTOCOL (-3) +#define BRL1_NO_MESSAGE (-4) +#define BRL1_LINK (-5) +#define BRL1_BUSY (-6) + +#define SC_SUCCESS BRL1_VALID +#define SC_NMSG BRL1_NO_MESSAGE +#define SC_BUSY BRL1_BUSY +#define SC_NOPEN (-7) +#define SC_BADSUBCH (-8) +#define SC_TIMEDOUT (-9) +#define SC_NSUBCH (-10) + + +/* L1 Target Addresses */ +/* + * L1 commands and responses use source/target addresses that are + * 32 bits long. These are broken up into multiple bitfields that + * specify the type of the target controller (could actually be L2 + * L3, not just L1), the rack and bay of the target, and the task + * id (L1 functionality is divided into several independent "tasks" + * that can each receive command requests and transmit responses) + */ +#define L1_ADDR_TYPE_SHFT 28 +#define L1_ADDR_TYPE_MASK 0xF0000000 +#define L1_ADDR_TYPE_L1 0x00 /* L1 system controller */ +#define L1_ADDR_TYPE_L2 0x01 /* L2 system controller */ +#define L1_ADDR_TYPE_L3 0x02 /* L3 system controller */ +#define L1_ADDR_TYPE_CBRICK 0x03 /* attached C brick */ +#define L1_ADDR_TYPE_IOBRICK 0x04 /* attached I/O brick */ + +#define L1_ADDR_RACK_SHFT 18 +#define L1_ADDR_RACK_MASK 0x0FFC0000 +#define L1_ADDR_RACK_LOCAL 0x3ff /* local brick's rack */ + +#define L1_ADDR_BAY_SHFT 12 +#define L1_ADDR_BAY_MASK 0x0003F000 +#define L1_ADDR_BAY_LOCAL 0x3f /* local brick's bay */ + +#define L1_ADDR_TASK_SHFT 0 +#define L1_ADDR_TASK_MASK 0x0000001F +#define L1_ADDR_TASK_INVALID 0x00 /* invalid task */ +#define L1_ADDR_TASK_IROUTER 0x01 /* iRouter */ +#define L1_ADDR_TASK_SYS_MGMT 0x02 /* system management port */ +#define L1_ADDR_TASK_CMD 0x03 /* command interpreter */ +#define L1_ADDR_TASK_ENV 0x04 /* environmental monitor */ +#define L1_ADDR_TASK_BEDROCK 0x05 /* bedrock */ +#define L1_ADDR_TASK_GENERAL 0x06 /* general requests */ + +#define L1_ADDR_LOCAL \ + (L1_ADDR_TYPE_L1 << L1_ADDR_TYPE_SHFT) | \ + (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) | \ + (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT) + +#define L1_ADDR_LOCALIO \ + (L1_ADDR_TYPE_IOBRICK << L1_ADDR_TYPE_SHFT) | \ + (L1_ADDR_RACK_LOCAL << L1_ADDR_RACK_SHFT) | \ + (L1_ADDR_BAY_LOCAL << L1_ADDR_BAY_SHFT) + +#define L1_ADDR_LOCAL_SHFT L1_ADDR_BAY_SHFT + +/* response argument types */ +#define L1_ARG_INT 0x00 /* 4-byte integer (big-endian) */ +#define L1_ARG_ASCII 0x01 /* null-terminated ASCII string */ +#define L1_ARG_UNKNOWN 0x80 /* unknown data type. The low + * 7 bits will contain the data + * length. */ + +/* response codes */ +#define L1_RESP_OK 0 /* no problems encountered */ +#define L1_RESP_IROUTER (- 1) /* iRouter error */ +#define L1_RESP_ARGC (-100) /* arg count mismatch */ +#define L1_RESP_REQC (-101) /* bad request code */ +#define L1_RESP_NAVAIL (-104) /* requested data not available */ +#define L1_RESP_ARGVAL (-105) /* arg value out of range */ + +/* L1 general requests */ + +/* request codes */ +#define L1_REQ_RDBG 0x0001 /* read debug switches */ +#define L1_REQ_RRACK 0x0002 /* read brick rack & bay */ +#define L1_REQ_RRBT 0x0003 /* read brick rack, bay & type */ +#define L1_REQ_SER_NUM 0x0004 /* read brick serial number */ +#define L1_REQ_FW_REV 0x0005 /* read L1 firmware revision */ +#define L1_REQ_EEPROM 0x0006 /* read EEPROM info */ +#define L1_REQ_EEPROM_FMT 0x0007 /* get EEPROM data format & size */ +#define L1_REQ_SYS_SERIAL 0x0008 /* read system serial number */ +#define L1_REQ_PARTITION_GET 0x0009 /* read partition id */ +#define L1_REQ_PORTSPEED 0x000a /* get ioport speed */ + +#define L1_REQ_CONS_SUBCH 0x1002 /* select this node's console + * subchannel */ +#define L1_REQ_CONS_NODE 0x1003 /* volunteer to be the master + * (console-hosting) node */ +#define L1_REQ_DISP1 0x1004 /* write line 1 of L1 display */ +#define L1_REQ_DISP2 0x1005 /* write line 2 of L1 display */ +#define L1_REQ_PARTITION_SET 0x1006 /* set partition id */ +#define L1_REQ_EVENT_SUBCH 0x1007 /* set the subchannel for system + controller event transmission */ + +#define L1_REQ_RESET 0x2001 /* request a full system reset */ + +/* L1 command interpreter requests */ + +/* request codes */ +#define L1_REQ_EXEC_CMD 0x0000 /* interpret and execute an ASCII + command string */ + + +/* brick type response codes */ +#define L1_BRICKTYPE_C 0x43 +#define L1_BRICKTYPE_I 0x49 +#define L1_BRICKTYPE_P 0x50 +#define L1_BRICKTYPE_R 0x52 +#define L1_BRICKTYPE_X 0x58 + +/* EEPROM codes (for the "read EEPROM" request) */ +/* c brick */ +#define L1_EEP_NODE 0x00 /* node board */ +#define L1_EEP_PIMM0 0x01 +#define L1_EEP_PIMM(x) (L1_EEP_PIMM0+(x)) +#define L1_EEP_DIMM0 0x03 +#define L1_EEP_DIMM(x) (L1_EEP_DIMM0+(x)) + +/* other brick types */ +#define L1_EEP_POWER 0x00 /* power board */ +#define L1_EEP_LOGIC 0x01 /* logic board */ + +/* info area types */ +#define L1_EEP_CHASSIS 1 /* chassis info area */ +#define L1_EEP_BOARD 2 /* board info area */ +#define L1_EEP_IUSE 3 /* internal use area */ +#define L1_EEP_SPD 4 /* serial presence detect record */ + +typedef uint32_t l1addr_t; + +#define L1_BUILD_ADDR(addr,at,r,s,t) \ + (*(l1addr_t *)(addr) = ((l1addr_t)(at) << L1_ADDR_TYPE_SHFT) | \ + ((l1addr_t)(r) << L1_ADDR_RACK_SHFT) | \ + ((l1addr_t)(s) << L1_ADDR_BAY_SHFT) | \ + ((l1addr_t)(t) << L1_ADDR_TASK_SHFT)) + +#define L1_ADDRESS_TO_TASK(addr,trb,tsk) \ + (*(l1addr_t *)(addr) = (l1addr_t)(trb) | \ + ((l1addr_t)(tsk) << L1_ADDR_TASK_SHFT)) + + +#define L1_DISPLAY_LINE_LENGTH 12 /* L1 display characters/line */ + +#ifdef L1_DISP_2LINES +#define L1_DISPLAY_LINES 2 /* number of L1 display lines */ +#else +#define L1_DISPLAY_LINES 1 /* number of L1 display lines available + * to system software */ +#endif + +#define SC_EVENT_CLASS_MASK ((unsigned short)0xff00) + +#define bzero(d, n) memset((d), 0, (n)) + +/* public interfaces to L1 system controller */ + +int sc_open( l1sc_t *sc, uint target ); +int sc_close( l1sc_t *sc, int ch ); +int sc_construct_msg( l1sc_t *sc, int ch, + char *msg, int msg_len, + uint addr_task, short req_code, + int req_nargs, ... ); +int sc_interpret_resp( char *resp, int resp_nargs, ... ); +int sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait ); +int sc_recv( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block ); +int sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ); +int sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len ); +int sc_poll( l1sc_t *sc, int ch ); +void sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart ); +void sc_intr_enable( l1sc_t *sc ); + +#if 0 +int sc_portspeed_get( l1sc_t *sc ); +#endif + +int l1_cons_poll( l1sc_t *sc ); +int l1_cons_getc( l1sc_t *sc ); +void l1_cons_init( l1sc_t *sc ); +int l1_cons_read( l1sc_t *sc, char *buf, int avail ); +int l1_cons_write( l1sc_t *sc, char *msg, int len, int wait ); +void l1_cons_tx_notif( l1sc_t *sc, brl1_notif_t func ); +void l1_cons_rx_notif( l1sc_t *sc, brl1_notif_t func ); + +int _elscuart_putc( l1sc_t *sc, int c ); +int _elscuart_getc( l1sc_t *sc ); +int _elscuart_poll( l1sc_t *sc ); +int _elscuart_readc( l1sc_t *sc ); +int _elscuart_flush( l1sc_t *sc ); +int _elscuart_probe( l1sc_t *sc ); +void _elscuart_init( l1sc_t *sc ); +void elscuart_syscon_listen( l1sc_t *sc ); + +int elsc_rack_bay_get(l1sc_t *e, uint *rack, uint *bay); +int elsc_rack_bay_type_get(l1sc_t *e, uint *rack, + uint *bay, uint *brick_type); +int elsc_cons_subch(l1sc_t *e, uint ch); +int elsc_cons_node(l1sc_t *e); +int elsc_display_line(l1sc_t *e, char *line, int lnum); + +extern l1sc_t *get_elsc( void ); +extern void set_elsc( l1sc_t *e ); + +#define get_l1sc get_elsc +#define set_l1sc(e) set_elsc(e) + +#define get_master_l1sc get_l1sc + +int router_module_get( nasid_t nasid, net_vec_t path ); + +int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, + uint *bay, uint *brick_type ); +int iobrick_module_get( l1sc_t *sc ); +int iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up ); +int iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up ); +int iobrick_sc_version( l1sc_t *sc, char *result ); + + +#endif /* !_LANGUAGE_ASSEMBLY */ +#endif /* _ASM_SN_KSYS_L1_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/labelcl.h linux-2.4.0-test12-lia/include/asm-ia64/sn/labelcl.h --- linux-2.4.0-test12/include/asm-ia64/sn/labelcl.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/labelcl.h Wed Dec 6 21:56:09 2000 @@ -0,0 +1,93 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_LABELCL_H +#define _ASM_SN_LABELCL_H + +#define LABELCL_MAGIC 0x4857434c /* 'HWLC' */ +#define LABEL_LENGTH_MAX 256 /* Includes NULL char */ +#define INFO_DESC_PRIVATE -1 /* default */ +#define INFO_DESC_EXPORT 0 /* export info itself */ + +/* + * Internal Error codes. + */ +typedef enum labelcl_error_e { LABELCL_SUCCESS, /* 0 */ + LABELCL_DUP, /* 1 */ + LABELCL_NOT_FOUND, /* 2 */ + LABELCL_BAD_PARAM, /* 3 */ + LABELCL_HIT_LIMIT, /* 4 */ + LABELCL_CANNOT_ALLOC, /* 5 */ + LABELCL_ILLEGAL_REQUEST, /* 6 */ + LABELCL_IN_USE /* 7 */ + } labelcl_error_t; + + +/* + * Description of a label entry. + */ +typedef struct label_info_s { + char *name; + arb_info_desc_t desc; + arbitrary_info_t info; +} label_info_t; + +/* + * Definition of the data structure that provides the link to + * the hwgraph fastinfo and the label entries associated with a + * particular devfs entry. + */ +typedef struct labelcl_info_s { + unsigned long hwcl_magic; + unsigned long num_labels; + void *label_list; + arbitrary_info_t IDX_list[HWGRAPH_NUM_INDEX_INFO]; +} labelcl_info_t; + +/* + * Definitions for the string table that holds the actual names + * of the labels. + */ +struct string_table_item { + struct string_table_item *next; + char string[1]; +}; + +struct string_table { + struct string_table_item *string_table_head; + long string_table_generation; +}; + + +#define STRTBL_BASIC_SIZE ((size_t)(((struct string_table_item *)0)->string)) +#define STRTBL_ITEM_SIZE(str_length) (STRTBL_BASIC_SIZE + (str_length) + 1) + +#define STRTBL_ALLOC(str_length) \ + ((struct string_table_item *)kmalloc(STRTBL_ITEM_SIZE(str_length), GFP_KERNEL)) + +#define STRTBL_FREE(ptr) kfree(ptr) + + +extern labelcl_info_t *labelcl_info_create(void); +extern int labelcl_info_destroy(labelcl_info_t *); +extern int labelcl_info_add_LBL(struct devfs_entry *, char *, arb_info_desc_t, arbitrary_info_t); +extern int labelcl_info_remove_LBL(struct devfs_entry *, char *, arb_info_desc_t *, arbitrary_info_t *); +extern int labelcl_info_replace_LBL(struct devfs_entry *, char *, arb_info_desc_t, + arbitrary_info_t, arb_info_desc_t *, arbitrary_info_t *); +extern int labelcl_info_get_LBL(struct devfs_entry *, char *, arb_info_desc_t *, + arbitrary_info_t *); +extern int labelcl_info_get_next_LBL(struct devfs_entry *, char *, arb_info_desc_t *, + arbitrary_info_t *, labelcl_info_place_t *); +extern int labelcl_info_replace_IDX(struct devfs_entry *, int, arbitrary_info_t, + arbitrary_info_t *); +extern int labelcl_info_connectpt_set(struct devfs_entry *, struct devfs_entry *); +extern int labelcl_info_get_IDX(struct devfs_entry *, int, arbitrary_info_t *); +extern struct devfs_entry *device_info_connectpt_get(struct devfs_entry *); + +#endif /* _ASM_SN_LABELCL_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/mem_refcnt.h linux-2.4.0-test12-lia/include/asm-ia64/sn/mem_refcnt.h --- linux-2.4.0-test12/include/asm-ia64/sn/mem_refcnt.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/mem_refcnt.h Wed Dec 6 21:56:09 2000 @@ -0,0 +1,26 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_MEM_REFCNT_H +#define _ASM_SN_MEM_REFCNT_H + +extern int mem_refcnt_attach(devfs_handle_t hub); +extern int mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp); +extern int mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp); +extern int mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot); +extern int mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt); +extern int mem_refcnt_ioctl(devfs_handle_t dev, + int cmd, + void *arg, + int mode, + cred_t *cred_p, + int *rvalp); + + +#endif /* _ASM_SN_MEM_REFCNT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/mmzone.h linux-2.4.0-test12-lia/include/asm-ia64/sn/mmzone.h --- linux-2.4.0-test12/include/asm-ia64/sn/mmzone.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/mmzone.h Wed Dec 13 19:35:14 2000 @@ -0,0 +1,111 @@ +/* + * Written by Kanoj Sarcar (kanoj@sgi.com) Jan 2000 + * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com + */ +#ifndef _LINUX_ASM_SN_MMZONE_H +#define _LINUX_ASM_SN_MMZONE_H + +#include +#include + +/* + * Memory is conceptually divided into chunks. A chunk is either + * completely present, or else the kernel assumes it is completely + * absent. Each node consists of a number of contiguous chunks. + */ + +#define CHUNKMASK (~(CHUNKSZ - 1)) +#define CHUNKNUM(vaddr) (__pa(vaddr) >> CHUNKSHIFT) +#define PCHUNKNUM(paddr) ((paddr) >> CHUNKSHIFT) + +#define MAXCHUNKS (MAXNODES * MAX_CHUNKS_PER_NODE) + +extern int chunktonid[]; +#define CHUNKTONID(cnum) (chunktonid[cnum]) + +typedef struct plat_pglist_data { + pg_data_t gendata; /* try to keep this first. */ + unsigned long virtstart; + unsigned long size; +} plat_pg_data_t; + +extern plat_pg_data_t plat_node_data[]; + +extern int numa_debug(void); + +/* + * The foll two will move into linux/mmzone.h RSN. + */ +#define NODE_START(n) plat_node_data[(n)].virtstart +#define NODE_SIZE(n) plat_node_data[(n)].size + +#define KVADDR_TO_NID(kaddr) \ + ((CHUNKTONID(CHUNKNUM((kaddr))) != -1) ? (CHUNKTONID(CHUNKNUM((kaddr)))) : \ + (printk("DISCONTIGBUG: %s line %d addr 0x%lx", __FILE__, __LINE__, \ + (unsigned long)(kaddr)), numa_debug())) +#if 0 +#define KVADDR_TO_NID(kaddr) CHUNKTONID(CHUNKNUM((kaddr))) +#endif + +/* These 2 macros should never be used if KVADDR_TO_NID(kaddr) is -1 */ +/* + * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory + * and returns the mem_map of that node. + */ +#define ADDR_TO_MAPBASE(kaddr) \ + NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr))) + +/* + * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory + * and returns the kaddr corresponding to first physical page in the + * node's mem_map. + */ +#define LOCAL_BASE_ADDR(kaddr) NODE_START(KVADDR_TO_NID(kaddr)) + +#ifdef CONFIG_DISCONTIGMEM + +/* + * Return a pointer to the node data for node n. + * Assume that n is the compact node id. + */ +#define NODE_DATA(n) (&((plat_node_data + (n))->gendata)) + +/* + * NODE_MEM_MAP gives the kaddr for the mem_map of the node. + */ +#define NODE_MEM_MAP(nid) (NODE_DATA((nid))->node_mem_map) + +/* This macro should never be used if KVADDR_TO_NID(kaddr) is -1 */ +#define LOCAL_MAP_NR(kvaddr) \ + (((unsigned long)(kvaddr)-LOCAL_BASE_ADDR((kvaddr))) >> PAGE_SHIFT) +#define MAP_NR_SN1(kaddr) (LOCAL_MAP_NR((kaddr)) + \ + (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \ + sizeof(mem_map_t))) +#if 0 +#define MAP_NR_VALID(kaddr) (LOCAL_MAP_NR((kaddr)) + \ + (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \ + sizeof(mem_map_t))) +#define MAP_NR_SN1(kaddr) ((KVADDR_TO_NID(kaddr) == -1) ? (max_mapnr + 1) :\ + MAP_NR_VALID(kaddr)) +#endif + +/* FIXME */ +#define sn1_pte_pagenr(x) MAP_NR_SN1(PAGE_OFFSET + (unsigned long)((pte_val(x)&_PFN_MASK) & PAGE_MASK)) +#define pte_page(pte) (mem_map + sn1_pte_pagenr(pte)) +/* FIXME */ + +#define kern_addr_valid(addr) ((KVADDR_TO_NID((unsigned long)addr) >= \ + numnodes) ? 0 : (test_bit(LOCAL_MAP_NR((addr)), \ + NODE_DATA(KVADDR_TO_NID((unsigned long)addr))->valid_addr_bitmap))) + +#define virt_to_page(kaddr) (mem_map + MAP_NR_SN1(kaddr)) + +#else /* CONFIG_DISCONTIGMEM */ + +#define MAP_NR_SN1(addr) (((unsigned long) (addr) - PAGE_OFFSET) >> PAGE_SHIFT) + +#endif /* CONFIG_DISCONTIGMEM */ + +#define numa_node_id() cpuid_to_cnodeid(smp_processor_id()) + +#endif /* !_LINUX_ASM_SN_MMZONE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/mmzone_default.h linux-2.4.0-test12-lia/include/asm-ia64/sn/mmzone_default.h --- linux-2.4.0-test12/include/asm-ia64/sn/mmzone_default.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/mmzone_default.h Wed Dec 6 21:56:09 2000 @@ -0,0 +1,15 @@ +/* + * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com + */ + +#define MAXNODES 16 +#define MAXNASIDS 16 + +#define CHUNKSZ (8*1024*1024) +#define CHUNKSHIFT 23 /* 2 ^^ CHUNKSHIFT == CHUNKSZ */ + +#define CNODEID_TO_NASID(n) n +#define NASID_TO_CNODEID(n) n + +#define MAX_CHUNKS_PER_NODE 8 + diff -urN linux-2.4.0-test12/include/asm-ia64/sn/mmzone_sn1.h linux-2.4.0-test12-lia/include/asm-ia64/sn/mmzone_sn1.h --- linux-2.4.0-test12/include/asm-ia64/sn/mmzone_sn1.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/mmzone_sn1.h Wed Dec 13 18:59:33 2000 @@ -0,0 +1,104 @@ +#ifndef _ASM_IA64_MMZONE_SN1_H +#define _ASM_IA64_MMZONE_SN1_H + +/* + * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com + */ + +/* Maximum configuration supported by SNIA hardware. There are other + * restrictions that may limit us to a smaller max configuration. + */ +#define MAXNODES 128 +#define MAXNASIDS 128 + +#define CHUNKSZ (64*1024*1024) +#define CHUNKSHIFT 26 /* 2 ^^ CHUNKSHIFT == CHUNKSZ */ + +extern int cnodeid_map[] ; +extern int nasid_map[] ; + +#define CNODEID_TO_NASID(n) (cnodeid_map[(n)]) +#define NASID_TO_CNODEID(n) (nasid_map[(n)]) + +#define MAX_CHUNKS_PER_NODE 128 + + +/* + * These are a bunch of sn1 hw specific defines. For now, keep it + * in this file. If it gets too diverse we may want to create a + * mmhwdefs_sn1.h + */ + +/* + * Structure of the mem config of the node as a SN1 MI reg + * Medusa supports this reg config. + */ + +typedef struct node_memmap_s +{ + unsigned int b0 :1, /* 0 bank 0 present */ + b1 :1, /* 1 bank 1 present */ + r01 :2, /* 2-3 reserved */ + b01size :4, /* 4-7 Size of bank 0 and 1 */ + b2 :1, /* 8 bank 2 present */ + b3 :1, /* 9 bank 3 present */ + r23 :2, /* 10-11 reserved */ + b23size :4, /* 12-15 Size of bank 2 and 3 */ + b4 :1, /* 16 bank 4 present */ + b5 :1, /* 17 bank 5 present */ + r45 :2, /* 18-19 reserved */ + b45size :4, /* 20-23 Size of bank 4 and 5 */ + b6 :1, /* 24 bank 6 present */ + b7 :1, /* 25 bank 7 present */ + r67 :2, /* 26-27 reserved */ + b67size :4; /* 28-31 Size of bank 6 and 7 */ +} node_memmap_t ; + +#define GBSHIFT 30 +#define MBSHIFT 20 + +/* + * SN1 Arch defined values + */ +#define SN1_MAX_BANK_PER_NODE 8 +#define SN1_BANK_PER_NODE_SHIFT 3 /* derived from SN1_MAX_BANK_PER_NODE */ +#define SN1_NODE_ADDR_SHIFT (GBSHIFT+3) /* 8GB */ +#define SN1_BANK_ADDR_SHIFT (SN1_NODE_ADDR_SHIFT-SN1_BANK_PER_NODE_SHIFT) + +#define SN1_BANK_SIZE_SHIFT (MBSHIFT+6) /* 64 MB */ +#define SN1_MIN_BANK_SIZE_SHIFT SN1_BANK_SIZE_SHIFT + +/* + * BankSize nibble to bank size mapping + * + * 1 - 64 MB + * 2 - 128 MB + * 3 - 256 MB + * 4 - 512 MB + * 5 - 1024 MB (1GB) + */ + +/* fixme - this macro breaks for bsize 6-8 and 0 */ + +#ifdef CONFIG_IA64_SGI_SN1_SIM +/* Support the medusa hack for 8M/16M/32M nodes */ +#define BankSizeBytes(bsize) ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\ + (1<<((bsize-9)+MBSHIFT))) +#else +#define BankSizeBytes(bsize) (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) +#endif + +#define BankSizeToEFIPages(bsize) ((BankSizeBytes(bsize)) >> 12) + +#define GetPhysAddr(n,b) (((u64)n<> SN1_NODE_ADDR_SHIFT) + +#define GetBankId(paddr) \ + (((u64)(paddr) >> SN1_BANK_ADDR_SHIFT) & 7) + +#define SN1_MAX_BANK_SIZE ((u64)BankSizeBytes(5)) +#define SN1_BANK_SIZE_MASK (~(SN1_MAX_BANK_SIZE-1)) + +#endif /* _ASM_IA64_MMZONE_SN1_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/module.h linux-2.4.0-test12-lia/include/asm-ia64/sn/module.h --- linux-2.4.0-test12/include/asm-ia64/sn/module.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/module.h Wed Dec 13 23:52:55 2000 @@ -0,0 +1,204 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_MODULE_H +#define _ASM_SN_MODULE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#ifdef BRINGUP /* max. number of modules? Should be about 300.*/ +#define MODULE_MAX 56 +#endif /* BRINGUP */ +#define MODULE_MAX_NODES 1 +#endif /* CONFIG_SGI_IP35 */ +#define MODULE_HIST_CNT 16 +#define MAX_MODULE_LEN 16 + +/* Well-known module IDs */ +#define MODULE_UNKNOWN (-2) /* initial value of klconfig brd_module */ +/* #define INVALID_MODULE (-1) ** generic invalid moduleid_t (arch.h) */ +#define MODULE_NOT_SET 0 /* module ID not set in sys ctlrs. */ + +/* parameter for format_module_id() */ +#define MODULE_FORMAT_BRIEF 1 +#define MODULE_FORMAT_LONG 2 + + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + +/* + * Module id format + * + * 15-12 Brick type (enumerated) + * 11-6 Rack ID (encoded class, group, number) + * 5-0 Brick position in rack (0-63) + */ +/* + * Macros for getting the brick type + */ +#define MODULE_BTYPE_MASK 0xf000 +#define MODULE_BTYPE_SHFT 12 +#define MODULE_GET_BTYPE(_m) (((_m) & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT) +#define MODULE_BT_TO_CHAR(_b) (brick_types[(_b)]) +#define MODULE_GET_BTCHAR(_m) (MODULE_BT_TO_CHAR(MODULE_GET_BTYPE(_m))) + +/* + * Macros for getting the rack ID. + */ +#define MODULE_RACK_MASK 0x0fc0 +#define MODULE_RACK_SHFT 6 +#define MODULE_GET_RACK(_m) (((_m) & MODULE_RACK_MASK) >> MODULE_RACK_SHFT) + +/* + * Macros for getting the brick position + */ +#define MODULE_BPOS_MASK 0x003f +#define MODULE_BPOS_SHFT 0 +#define MODULE_GET_BPOS(_m) (((_m) & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT) + +/* + * Macros for constructing moduleid_t's + */ +#define RBT_TO_MODULE(_r, _b, _t) ((_r) << MODULE_RACK_SHFT | \ + (_b) << MODULE_BPOS_SHFT | \ + (_t) << MODULE_BTYPE_SHFT) + +/* + * Macros for encoding and decoding rack IDs + * A rack number consists of three parts: + * class 1 bit, 0==CPU/mixed, 1==I/O + * group 2 bits for CPU/mixed, 3 bits for I/O + * number 3 bits for CPU/mixed, 2 bits for I/O (1 based) + */ +#define RACK_GROUP_BITS(_r) (RACK_GET_CLASS(_r) ? 3 : 2) +#define RACK_NUM_BITS(_r) (RACK_GET_CLASS(_r) ? 2 : 3) + +#define RACK_CLASS_MASK(_r) 0x20 +#define RACK_CLASS_SHFT(_r) 5 +#define RACK_GET_CLASS(_r) \ + (((_r) & RACK_CLASS_MASK(_r)) >> RACK_CLASS_SHFT(_r)) +#define RACK_ADD_CLASS(_r, _c) \ + ((_r) |= (_c) << RACK_CLASS_SHFT(_r) & RACK_CLASS_MASK(_r)) + +#define RACK_GROUP_SHFT(_r) RACK_NUM_BITS(_r) +#define RACK_GROUP_MASK(_r) \ + ( (((unsigned)1<> RACK_GROUP_SHFT(_r)) +#define RACK_ADD_GROUP(_r, _g) \ + ((_r) |= (_g) << RACK_GROUP_SHFT(_r) & RACK_GROUP_MASK(_r)) + +#define RACK_NUM_SHFT(_r) 0 +#define RACK_NUM_MASK(_r) \ + ( (((unsigned)1<> RACK_NUM_SHFT(_r)) + 1 ) +#define RACK_ADD_NUM(_r, _n) \ + ((_r) |= ((_n) - 1) << RACK_NUM_SHFT(_r) & RACK_NUM_MASK(_r)) + +/* + * Brick type definitions + */ +#define MAX_BRICK_TYPES 16 /* 1 << (MODULE_RACK_SHFT - MODULE_BTYPE_SHFT */ + +extern char brick_types[]; + +#define MODULE_CBRICK 0 +#define MODULE_RBRICK 1 +#define MODULE_IBRICK 2 +#define MODULE_KBRICK 3 +#define MODULE_XBRICK 4 +#define MODULE_DBRICK 5 +#define MODULE_PBRICK 6 + +/* + * Moduleid_t comparison macros + */ +/* Don't compare the brick type: only the position is significant */ +#define MODULE_CMP(_m1, _m2) (((_m1)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)) -\ + ((_m2)&(MODULE_RACK_MASK|MODULE_BPOS_MASK))) +#define MODULE_MATCH(_m1, _m2) (MODULE_CMP((_m1),(_m2)) == 0) + +#else + +/* + * Some code that uses this macro will not be conditionally compiled. + */ +#define MODULE_GET_BTCHAR(_m) ('?') +#define MODULE_CMP(_m1, _m2) ((_m1) - (_m2)) +#define MODULE_MATCH(_m1, _m2) (MODULE_CMP((_m1),(_m2)) == 0) + +#endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + +typedef struct module_s module_t; + +struct module_s { + moduleid_t id; /* Module ID of this module */ + + spinlock_t lock; /* Lock for this structure */ + + /* List of nodes in this module */ + cnodeid_t nodes[MODULE_MAX_NODES]; + int nodecnt; /* Number of nodes in array */ + + /* Fields for Module System Controller */ + int mesgpend; /* Message pending */ + int shutdown; /* Shutdown in progress */ + struct semaphore thdcnt; /* Threads finished counter */ + + elsc_t elsc; + spinlock_t elsclock; + + time_t intrhist[MODULE_HIST_CNT]; + int histptr; + + int hbt_active; /* MSC heartbeat monitor active */ + uint64_t hbt_last; /* RTC when last heartbeat sent */ + + /* Module serial number info */ + union { + char snum_str[MAX_SERIAL_NUM_SIZE]; /* used by CONFIG_SGI_IP27 */ + uint64_t snum_int; /* used by speedo */ + } snum; + int snum_valid; + + int disable_alert; + int count_down; +}; + +/* module.c */ +extern module_t *modules[MODULE_MAX]; /* Indexed by cmoduleid_t */ +extern int nummodules; + +#ifndef CONFIG_IA64_SGI_IO +/* Clashes with LINUX stuff */ +extern void module_init(void); +#endif +extern module_t *module_lookup(moduleid_t id); + +extern elsc_t *get_elsc(void); + +extern int get_kmod_info(cmoduleid_t cmod, + module_info_t *mod_info); + +extern void format_module_id(char *buffer, moduleid_t m, int fmt); +extern int parse_module_id(char *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASM_SN_MODULE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/nic.h linux-2.4.0-test12-lia/include/asm-ia64/sn/nic.h --- linux-2.4.0-test12/include/asm-ia64/sn/nic.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/nic.h Wed Dec 6 21:56:09 2000 @@ -0,0 +1,128 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_NIC_H +#define _ASM_SN_NIC_H + +#include + +#define MCR_DATA(x) ((int) ((x) & 1)) +#define MCR_DONE(x) ((x) & 2) +#define MCR_PACK(pulse, sample) ((pulse) << 10 | (sample) << 2) + +typedef __psunsigned_t nic_data_t; + +typedef int +nic_access_f(nic_data_t data, + int pulse, int sample, int delay); + +typedef nic_access_f *nic_access_t; + +typedef struct nic_vmce_s *nic_vmce_t; +typedef void nic_vmc_func(devfs_handle_t v); + +/* + * PRIVATE data for Dallas NIC + */ + +typedef struct nic_state_t { + nic_access_t access; + nic_data_t data; + int last_disc; + int done; + int bit_index; + int disc_marker; + uchar_t bits[64]; +} nic_state_t; + +/* + * Public interface for Dallas NIC + * + * + * Access Routine + * + * nic_setup requires an access routine that pulses the NIC line for a + * specified duration, samples the NIC line after a specified duration, + * then delays for a third specified duration (for precharge). + * + * This general scheme allows us to access NICs through any medium + * (e.g. hub regs, bridge regs, vector writes, system ctlr commands). + * + * The access routine should return the sample value 0 or 1, or if an + * error occurs, return a negative error code. Negative error codes from + * the access routine will abort the NIC operation and be propagated + * through out of the top-level NIC call. + */ + +#define NIC_OK 0 +#define NIC_DONE 1 +#define NIC_FAIL 2 +#define NIC_BAD_CRC 3 +#define NIC_NOT_PRESENT 4 +#define NIC_REDIR_LOOP 5 +#define NIC_PARAM 6 +#define NIC_NOMEM 7 + +uint64_t nic_get_phase_bits(void); + +extern int nic_setup(nic_state_t *ns, + nic_access_t access, + nic_data_t data); + +extern int nic_next(nic_state_t *ns, + char *serial, + char *family, + char *crc); + +extern int nic_read_one_page(nic_state_t *ns, + char *family, + char *serial, + char *crc, + int start, + uchar_t *redirect, + uchar_t *byte); + +extern int nic_read_mfg(nic_state_t *ns, + char *family, + char *serial, + char *crc, + uchar_t *pageA, + uchar_t *pageB); + +extern int nic_info_get(nic_access_t access, + nic_data_t data, + char *info); + +extern int nic_item_info_get(char *buf, char *item, char **item_info); + +nic_access_f nic_access_mcr32; + +extern char *nic_vertex_info_get(devfs_handle_t v); + +extern char *nic_vertex_info_set(nic_access_t access, + nic_data_t data, + devfs_handle_t v); + +extern int nic_vertex_info_match(devfs_handle_t vertex, + char *name); + +extern char *nic_bridge_vertex_info(devfs_handle_t vertex, + nic_data_t data); +extern char *nic_hq4_vertex_info(devfs_handle_t vertex, + nic_data_t data); +extern char *nic_ioc3_vertex_info(devfs_handle_t vertex, + nic_data_t data, + int32_t *gpcr_s); + +extern char *nic_hub_vertex_info(devfs_handle_t vertex); + +extern nic_vmce_t nic_vmc_add(char *, nic_vmc_func *); +extern void nic_vmc_del(nic_vmce_t); + +#endif /* _ASM_SN_NIC_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/nodemask.h linux-2.4.0-test12-lia/include/asm-ia64/sn/nodemask.h --- linux-2.4.0-test12/include/asm-ia64/sn/nodemask.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/nodemask.h Wed Dec 13 22:44:11 2000 @@ -0,0 +1,328 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_NODEMASK_H +#define _ASM_SN_NODEMASK_H + +#if defined(__KERNEL__) || defined(_KMEMUSER) + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +#include /* needed for MAX_COMPACT_NODES */ +#endif + +#define CNODEMASK_BOOTED_MASK boot_cnodemask +#define CNODEMASK_BIPW 64 + +#if !defined(SN0XXL) && !defined(CONFIG_SGI_IP35) && !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC) + /* MAXCPUS 128p (64 nodes) or less */ + +#define CNODEMASK_SIZE 1 +typedef uint64_t cnodemask_t; + +#define CNODEMASK_WORD(p,w) (p) +#define CNODEMASK_SET_WORD(p,w,val) (p) = val +#define CNODEMASK_CLRALL(p) (p) = 0 +#define CNODEMASK_SETALL(p) (p) = ~((cnodemask_t)0) +#define CNODEMASK_IS_ZERO(p) ((p) == 0) +#define CNODEMASK_IS_NONZERO(p) ((p) != 0) +#define CNODEMASK_NOTEQ(p, q) ((p) != (q)) +#define CNODEMASK_EQ(p, q) ((p) == (q)) +#define CNODEMASK_LSB_ISONE(p) ((p) & 0x1ULL) + +#define CNODEMASK_ZERO() ((cnodemask_t)0) +#define CNODEMASK_CVTB(bit) (1ULL << (bit)) +#define CNODEMASK_SETB(p, bit) ((p) |= 1ULL << (bit)) +#define CNODEMASK_CLRB(p, bit) ((p) &= ~(1ULL << (bit))) +#define CNODEMASK_TSTB(p, bit) ((p) & (1ULL << (bit))) + +#define CNODEMASK_SETM(p, q) ((p) |= (q)) +#define CNODEMASK_CLRM(p, q) ((p) &= ~(q)) +#define CNODEMASK_ANDM(p, q) ((p) &= (q)) +#define CNODEMASK_TSTM(p, q) ((p) & (q)) + +#define CNODEMASK_CPYNOTM(p, q) ((p) = ~(q)) +#define CNODEMASK_CPY(p, q) ((p) = (q)) +#define CNODEMASK_ORNOTM(p, q) ((p) |= ~(q)) +#define CNODEMASK_SHIFTL(p) ((p) <<= 1) +#define CNODEMASK_SHIFTR(p) ((p) >>= 1) +#define CNODEMASK_SHIFTL_PTR(p) (*(p) <<= 1) +#define CNODEMASK_SHIFTR_PTR(p) (*(p) >>= 1) + +/* Atomically set or clear a particular bit */ +#define CNODEMASK_ATOMSET_BIT(p, bit) atomicSetUlong((cnodemask_t *)&(p), (1ULL<<(bit))) +#define CNODEMASK_ATOMCLR_BIT(p, bit) atomicClearUlong((cnodemask_t *)&(p), (1ULL<<(bit))) + +/* Atomically set or clear a collection of bits */ +#define CNODEMASK_ATOMSET(p, q) atomicSetUlong((cnodemask_t *)&(p), q) +#define CNODEMASK_ATOMCLR(p, q) atomicClearUlong((cnodemask_t *)&(p), q) + +/* Atomically set or clear a collection of bits, returning the old value */ +#define CNODEMASK_ATOMSET_MASK(__old, p, q) { \ + (__old) = atomicSetUlong((cnodemask_t *)&(p), q); \ +} +#define CNODEMASK_ATOMCLR_MASK(__old, p, q) { \ + (__old) = atomicClearUlong((cnodemask_t *)&(p),q); \ +} + +#define CNODEMASK_FROM_NUMNODES(n) ((~(cnodemask_t)0)>>(CNODEMASK_BIPW-(n))) + +#else /* SN0XXL || SN1 - MAXCPUS > 128 */ + +#define CNODEMASK_SIZE (MAX_COMPACT_NODES / CNODEMASK_BIPW) + +typedef struct { + uint64_t _bits[CNODEMASK_SIZE]; +} cnodemask_t; + +#define CNODEMASK_WORD(p,w) \ + ((w >= 0 && w < CNODEMASK_SIZE) ? (p)._bits[(w)] : 0) +#define CNODEMASK_SET_WORD(p,w,val) { \ + if (w >= 0 && w < CNODEMASK_SIZE) \ + (p)._bits[(w)] = val; \ +} + +#define CNODEMASK_CLRALL(p) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] = 0; \ +} + +#define CNODEMASK_SETALL(p) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] = ~(0); \ +} + +#define CNODEMASK_LSB_ISONE(p) ((p)._bits[0] & 0x1ULL) + + +#define CNODEMASK_SETM(p,q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] |= ((q)._bits[i]); \ +} + +#define CNODEMASK_CLRM(p,q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] &= ~((q)._bits[i]); \ +} + +#define CNODEMASK_ANDM(p,q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] &= ((q)._bits[i]); \ +} + +#define CNODEMASK_CPY(p, q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] = (q)._bits[i]; \ +} + +#define CNODEMASK_CPYNOTM(p,q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] = ~((q)._bits[i]); \ +} + +#define CNODEMASK_ORNOTM(p,q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) \ + (p)._bits[i] |= ~((q)._bits[i]); \ +} + +#define CNODEMASK_INDEX(bit) ((bit) >> 6) +#define CNODEMASK_SHFT(bit) ((bit) & 0x3f) + + +#define CNODEMASK_SETB(p, bit) \ + (p)._bits[CNODEMASK_INDEX(bit)] |= (1ULL << CNODEMASK_SHFT(bit)) + + +#define CNODEMASK_CLRB(p, bit) \ + (p)._bits[CNODEMASK_INDEX(bit)] &= ~(1ULL << CNODEMASK_SHFT(bit)) + + +#define CNODEMASK_TSTB(p, bit) \ + ((p)._bits[CNODEMASK_INDEX(bit)] & (1ULL << CNODEMASK_SHFT(bit))) + +/** Probably should add atomic update for entire cnodemask_t struct **/ + +/* Atomically set or clear a particular bit */ +#define CNODEMASK_ATOMSET_BIT(p, bit) \ + (atomicSetUlong((unsigned long *)&(p)._bits[CNODEMASK_INDEX(bit)], (1ULL << CNODEMASK_SHFT(bit)))); +#define CNODEMASK_ATOMCLR_BIT(__old, p, bit) \ + (atomicClearUlong((unsigned long *)&(p)._bits[CNODEMASK_INDEX(bit)], (1ULL << CNODEMASK_SHFT(bit)))); + +/* Atomically set or clear a collection of bits */ +#define CNODEMASK_ATOMSET(p, q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) { \ + atomicSetUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]); \ + } \ +} +#define CNODEMASK_ATOMCLR(p, q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) { \ + atomicClearUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]); \ + } \ +} + +/* Atomically set or clear a collection of bits, returning the old value */ +#define CNODEMASK_ATOMSET_MASK(__old, p, q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) { \ + (__old)._bits[i] = \ + atomicSetUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]); \ + } \ +} +#define CNODEMASK_ATOMCLR_MASK(__old, p, q) { \ + int i; \ + \ + for (i = 0 ; i < CNODEMASK_SIZE ; i++) { \ + (__old)._bits[i] = \ + atomicClearUlong((unsigned long *)&(p)._bits[i], (q)._bits[i]); \ + } \ +} + +__inline static cnodemask_t CNODEMASK_CVTB(int bit) +{ + cnodemask_t __tmp; + CNODEMASK_CLRALL(__tmp); + CNODEMASK_SETB(__tmp,bit); + return(__tmp); +} + + +__inline static cnodemask_t CNODEMASK_ZERO(void) +{ + cnodemask_t __tmp; + CNODEMASK_CLRALL(__tmp); + return(__tmp); +} + +__inline static int CNODEMASK_IS_ZERO (cnodemask_t p) +{ + int i; + + for (i = 0 ; i < CNODEMASK_SIZE ; i++) + if (p._bits[i] != 0) + return 0; + return 1; +} + +__inline static int CNODEMASK_IS_NONZERO (cnodemask_t p) +{ + int i; + + for (i = 0 ; i < CNODEMASK_SIZE ; i++) + if (p._bits[i] != 0) + return 1; + return 0; +} + +__inline static int CNODEMASK_NOTEQ (cnodemask_t p, cnodemask_t q) +{ + int i; + + for (i = 0 ; i < CNODEMASK_SIZE ; i++) + if (p._bits[i] != q._bits[i]) + return 1; + return 0; +} + +__inline static int CNODEMASK_EQ (cnodemask_t p, cnodemask_t q) +{ + int i; + + for (i = 0 ; i < CNODEMASK_SIZE ; i++) + if (p._bits[i] != q._bits[i]) + return 0; + return 1; +} + + +__inline static int CNODEMASK_TSTM (cnodemask_t p, cnodemask_t q) +{ + int i; + + for (i = 0 ; i < CNODEMASK_SIZE ; i++) + if (p._bits[i] & q._bits[i]) + return 1; + return 0; +} + +__inline static void CNODEMASK_SHIFTL_PTR (cnodemask_t *p) +{ + int i; + uint64_t upper; + + /* + * shift words starting with the last word + * of the vector and work backward to the first + * word updating the low order bits with the + * high order bit of the prev word. + */ + for (i=(CNODEMASK_SIZE-1); i > 0; --i) { + upper = (p->_bits[i-1] & (1ULL<<(CNODEMASK_BIPW-1))) ? 1 : 0; + p->_bits[i] <<= 1; + p->_bits[i] |= upper; + } + p->_bits[i] <<= 1; +} + +__inline static void CNODEMASK_SHIFTR_PTR (cnodemask_t *p) +{ + int i; + uint64_t lower; + + /* + * shift words starting with the first word + * of the vector and work forward to the last + * word updating the high order bit with the + * low order bit of the next word. + */ + for (i=0; i < (CNODEMASK_SIZE-2); ++i) { + lower = (p->_bits[i+1] & (0x1)) ? 1 : 0; + p->_bits[i] >>= 1; + p->_bits[i] |= (lower<<((CNODEMASK_BIPW-1))); + } + p->_bits[i] >>= 1; +} + +__inline static cnodemask_t CNODEMASK_FROM_NUMNODES(int n) +{ + cnodemask_t __tmp; + int i; + CNODEMASK_CLRALL(__tmp); + for (i=0; i +#include +#include +/* #include */ +#ifdef IRIX +typedef struct module_s module_t; /* Avoids sys/SN/module.h */ +#else +#include +#endif +/* #include */ + +/* + * NUMA Node-Specific Data structures are defined in this file. + * In particular, this is the location of the node PDA. + * A pointer to the right node PDA is saved in each CPU PDA. + */ + +/* + * Subnode PDA structures. Each node needs a few data structures that + * correspond to the PIs on the HUB chip that supports the node. + * + * WARNING!!!! 6.5.x compatibility requirements prevent us from + * changing or reordering fields in the following structure for IP27. + * It is essential that the data mappings not change for IP27 platforms. + * It is OK to add fields that are IP35 specific if they are under #ifdef IP35. + */ +struct subnodepda_s { + intr_vecblk_t intr_dispatch0; + intr_vecblk_t intr_dispatch1; + uint64_t next_prof_timeout; + int prof_count; +}; + + +typedef struct subnodepda_s subnode_pda_t; + + +struct ptpool_s; + + +/* + * Node-specific data structure. + * + * One of these structures is allocated on each node of a NUMA system. + * Non-NUMA systems are considered to be systems with one node, and + * hence there will be one of this structure for the entire system. + * + * This structure provides a convenient way of keeping together + * all per-node data structures. + */ + + +#ifndef CONFIG_IA64_SGI_IO +/* + * The following structure is contained in the nodepda & contains + * a lock & queue-head for sanon pages that belong to the node. + * See the anon manager for more details. + */ +typedef struct { + lock_t sal_lock; + plist_t sal_listhead; +} sanon_list_head_t; +#endif + + + +struct nodepda_s { + +#ifdef NUMA_BASE + + /* + * Pointer to this node's copy of Nodepdaindr + */ + struct nodepda_s **pernode_pdaindr; + + /* + * Data used for migration control + */ + struct migr_control_data_s *mcd; + + /* + * Data used for replication control + */ + struct repl_control_data_s *rcd; + + /* + * Numa statistics + */ + struct numa_stats_s *numa_stats; + + /* + * Load distribution + */ + uint memfit_assign; + + /* + * New extended memory reference counters + */ + void *migr_refcnt_counterbase; + void *migr_refcnt_counterbuffer; + size_t migr_refcnt_cbsize; + int migr_refcnt_numsets; + + /* + * mem_tick quiescing lock + */ + uint mem_tick_lock; + + /* + * Migration candidate set + * by migration prologue intr handler + */ + uint64_t migr_candidate; + + /* + * Each node gets its own syswait counter to remove contention + * on the global one. + */ +#ifndef CONFIG_IA64_SGI_IO + struct syswait syswait; +#endif + +#endif /* NUMA_BASE */ + /* + * Node-specific Zone structures. + */ +#ifndef CONFIG_IA64_SGI_IO + zoneset_element_t node_zones; + pg_data_t node_pg_data; /* VM page data structures */ + plist_t error_discard_plist; +#endif + uint error_discard_count; + uint error_page_count; + uint error_cleaned_count; + spinlock_t error_discard_lock; + + /* Information needed for SN Hub chip interrupt handling. */ + subnode_pda_t snpda[NUM_SUBNODES]; + /* Distributed kernel support */ +#ifndef CONFIG_IA64_SGI_IO + kern_vars_t kern_vars; +#endif + /* Vector operation support */ + /* Change this to a sleep lock? */ + spinlock_t vector_lock; + /* State of the vector unit for this node */ + char vector_unit_busy; + cpuid_t node_first_cpu; /* Starting cpu number for node */ + ushort node_num_cpus; /* Number of cpus present */ + + /* node utlbmiss info */ + spinlock_t node_utlbswitchlock; + volatile cpumask_t node_utlbmiss_flush; + volatile signed char node_need_utlbmiss_patch; + volatile char node_utlbmiss_patched; + nodepda_router_info_t *npda_rip_first; + nodepda_router_info_t **npda_rip_last; + int dependent_routers; + devfs_handle_t xbow_vhdl; + nasid_t xbow_peer; /* NASID of our peer hub on xbow */ + struct semaphore xbow_sema; /* Sema for xbow synchronization */ + slotid_t slotdesc; + moduleid_t module_id; /* Module ID (redundant local copy) */ + module_t *module; /* Pointer to containing module */ + int hub_chip_rev; /* Rev of my Hub chip */ + char nasid_mask[NASID_MASK_BYTES]; + /* Need a copy of the nasid mask + * on every node */ + xwidgetnum_t basew_id; + devfs_handle_t basew_xc; + spinlock_t fprom_lock; + char ni_error_print; /* For printing ni error state + * only once during system panic + */ +#ifndef CONFIG_IA64_SGI_IO + md_perf_monitor_t node_md_perfmon; + hubstat_t hubstats; + int hubticks; + int huberror_ticks; + sbe_info_t *sbe_info; /* ECC single-bit error statistics */ +#endif /* !CONFIG_IA64_SGI_IO */ + + router_queue_t *visited_router_q; + router_queue_t *bfs_router_q; + /* Used for router traversal */ +#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) + router_map_ent_t router_map[MAX_RTR_BREADTH]; +#endif + int num_routers; /* Total routers in the system */ + + char membank_flavor; + /* Indicates what sort of memory + * banks are present on this node + */ + + char *hwg_node_name; /* hwgraph node name */ + + struct widget_info_t *widget_info; /* Node as xtalk widget */ + devfs_handle_t node_vertex; /* Hwgraph vertex for this node */ + + void *pdinfo; /* Platform-dependent per-node info */ + uint64_t *dump_stack; /* Dump stack during nmi handling */ + int dump_count; /* To allow only one cpu-per-node */ +#if defined BRINGUP +#ifndef CONFIG_IA64_SGI_IO + io_perf_monitor_t node_io_perfmon; +#endif +#endif + + /* + * Each node gets its own pdcount counter to remove contention + * on the global one. + */ + + int pdcount; /* count of pdinserted pages */ + +#ifdef NUMA_BASE + void *cached_global_pool; /* pointer to cached vmpool */ +#endif /* NUMA_BASE */ + +#ifndef CONFIG_IA64_SGI_IO + sanon_list_head_t sanon_list_head; /* head for sanon pages */ +#endif +#ifdef NUMA_BASE + struct ptpool_s *ptpool; /* ptpool for this node */ +#endif /* NUMA_BASE */ + + /* + * The BTEs on this node are shared by the local cpus + */ +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#ifndef CONFIG_IA64_SGI_IO + bteinfo_t *node_bte_info[BTES_PER_NODE]; +#endif +#endif +}; + +typedef struct nodepda_s nodepda_t; + + +#define NODE_MODULEID(_node) (NODEPDA(_node)->module_id) +#define NODE_SLOTID(_node) (NODEPDA(_node)->slotdesc) + +#ifdef NUMA_BASE +/* + * Access Functions for node PDA. + * Since there is one nodepda for each node, we need a convenient mechanism + * to access these nodepdas without cluttering code with #ifdefs. + * The next set of definitions provides this. + * Routines are expected to use + * + * nodepda -> to access PDA for the node on which code is running + * subnodepda -> to access subnode PDA for the node on which code is running + * + * NODEPDA(x) -> to access node PDA for cnodeid 'x' + * SUBNODEPDA(x,s) -> to access subnode PDA for cnodeid/slice 'x' + */ + +#ifndef CONFIG_IA64_SGI_IO +#define nodepda private.p_nodepda /* Ptr to this node's PDA */ +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +#define subnodepda private.p_subnodepda /* Ptr to this node's subnode PDA */ +#endif + +#else +/* + * Until we have a shared node local area defined, do it this way .. + * like in Caliase space. See above. + */ +extern nodepda_t *nodepda; +extern subnode_pda_t *subnodepda; +#endif + +/* + * Nodepdaindr[] + * This is a private data structure for use only in early initialization. + * All users of nodepda should use the macro NODEPDA(nodenum) to get + * the suitable nodepda structure. + * This macro has the advantage of not requiring #ifdefs for NUMA and + * non-NUMA code. + */ +extern nodepda_t *Nodepdaindr[]; +/* + * NODEPDA_GLOBAL(x) macro should ONLY be used during early initialization. + * Once meminit is complete, NODEPDA(x) is ready to use. + * During early init, the system fills up Nodepdaindr. By the time we + * are in meminit(), all nodepdas are initialized, and hence + * we can fill up the node_pdaindr array in each nodepda structure. + */ +#define NODEPDA_GLOBAL(x) Nodepdaindr[x] + +/* + * Returns a pointer to a given node's nodepda. + */ +#define NODEPDA(x) (nodepda->pernode_pdaindr[x]) + +/* + * Returns a pointer to a given node/slice's subnodepda. + * SUBNODEPDA(cnode, subnode) - uses cnode as first arg + * SNPDA(npda, subnode) - uses pointer to nodepda as first arg + */ +#define SUBNODEPDA(x,sn) (&nodepda->pernode_pdaindr[x]->snpda[sn]) +#define SNPDA(npda,sn) (&(npda)->snpda[sn]) + +#define NODEPDA_ERROR_FOOTPRINT(node, cpu) \ + (&(NODEPDA(node)->error_stamp[cpu])) +#define NODEPDA_MDP_MON(node) (&(NODEPDA(node)->node_md_perfmon)) +#define NODEPDA_IOP_MON(node) (&(NODEPDA(node)->node_io_perfmon)) + +/* + * Macros to access data structures inside nodepda + */ +#if NUMA_MIGR_CONTROL +#define NODEPDA_MCD(node) (NODEPDA(node)->mcd) +#endif /* NUMA_MIGR_CONTROL */ + +#if NUMA_REPL_CONTROL +#define NODEPDA_RCD(node) (NODEPDA(node)->rcd) +#endif /* NUMA_REPL_CONTROL */ + +#if (NUMA_MIGR_CONTROL || NUMA_REPL_CONTROL) +#define NODEPDA_LRS(node) (NODEPDA(node)->lrs) +#endif /* (NUMA_MIGR_CONTROL || NUMA_REPL_CONTROL) */ + +/* + * Exported functions + */ +extern nodepda_t *nodepda_alloc(void); + +#else /* !NUMA_BASE */ +/* + * For a single-node system we will just have one global nodepda pointer + * allocated at startup. The global nodepda will point to this nodepda + * structure. + */ +extern nodepda_t *Nodepdaindr; + +/* + * On non-NUMA systems, NODEPDA_GLOBAL and NODEPDA macros collapse to + * be the same. + */ +#define NODEPDA_GLOBAL(x) Nodepdaindr + +/* + * Returns a pointer to a given node's nodepda. + */ +#define NODEPDA(x) Nodepdaindr + +/* + * nodepda can also be defined as private.p_nodepda. + * But on non-NUMA systems, there is only one nodepda, and there is + * no reason to go through the PDA to access this pointer. + * Hence nodepda aliases to the global nodepda directly. + * + * Routines should use nodepda to access the local node's PDA. + */ +#define nodepda (Nodepdaindr) + +#endif /* NUMA_BASE */ + +/* Quickly convert a compact node ID into a hwgraph vertex */ +#define cnodeid_to_vertex(cnodeid) (NODEPDA(cnodeid)->node_vertex) + + +/* Check if given a compact node id the corresponding node has all the + * cpus disabled. + */ +#define is_headless_node(_cnode) ((_cnode == CNODEID_NONE) || \ + (CNODE_NUM_CPUS(_cnode) == 0)) +/* Check if given a node vertex handle the corresponding node has all the + * cpus disabled. + */ +#define is_headless_node_vertex(_nodevhdl) \ + is_headless_node(nodevertex_to_cnodeid(_nodevhdl)) + +#ifdef __cplusplus +} +#endif + +#ifdef NUMA_BASE +/* + * To remove contention on the global syswait counter each node will have + * its own. Each clock tick the clock cpu will re-calculate the global + * syswait counter by summing from each of the nodes. The other cpus will + * continue to read the global one during their clock ticks. This does + * present a problem when a thread increments the count on one node and wakes + * up on a different node and decrements it there. Eventually the count could + * overflow if this happens continually for a long period. To prevent this + * second_thread() periodically preserves the current syswait state and + * resets the counters. + */ +#define ADD_SYSWAIT(_field) atomicAddInt(&nodepda->syswait._field, 1) +#define SUB_SYSWAIT(_field) atomicAddInt(&nodepda->syswait._field, -1) +#else +#define ADD_SYSWAIT(_field) \ +{ \ + ASSERT(syswait._field >= 0); \ + atomicAddInt(&syswait._field, 1); \ +} +#define SUB_SYSWAIT(_field) \ +{ \ + ASSERT(syswait._field > 0); \ + atomicAddInt(&syswait._field, -1); \ +} +#endif /* NUMA_BASE */ + +#ifdef NUMA_BASE +/* + * Another global variable to remove contention from: pdcount. + * See above comments for SYSWAIT. + */ +#define ADD_PDCOUNT(_n) \ +{ \ + atomicAddInt(&nodepda->pdcount, _n); \ + if (_n > 0 && !pdflag) \ + pdflag = 1; \ +} +#else +#define ADD_PDCOUNT(_n) \ +{ \ + ASSERT(&pdcount >= 0); \ + atomicAddInt(&pdcount, _n); \ + if (_n > 0 && !pdflag) \ + pdflag = 1; \ +} +#endif /* NUMA_BASE */ + +#endif /* _ASM_SN_NODEPDA_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/bridge.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/bridge.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/bridge.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/bridge.h Wed Dec 13 23:52:14 2000 @@ -0,0 +1,1729 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_BRIDGE_H +#define _ASM_SN_PCI_BRIDGE_H + + +/* + * bridge.h - header file for bridge chip and bridge portion of xbridge chip + */ + +#include + +/* I/O page size */ + +#if _PAGESZ == 4096 +#define IOPFNSHIFT 12 /* 4K per mapped page */ +#else +#define IOPFNSHIFT 14 /* 16K per mapped page */ +#endif /* _PAGESZ */ + +#define IOPGSIZE (1 << IOPFNSHIFT) +#define IOPG(x) ((x) >> IOPFNSHIFT) +#define IOPGOFF(x) ((x) & (IOPGSIZE-1)) + +/* Bridge RAM sizes */ + +#define BRIDGE_INTERNAL_ATES 128 +#define XBRIDGE_INTERNAL_ATES 1024 + +#define BRIDGE_ATE_RAM_SIZE (BRIDGE_INTERNAL_ATES<<3) /* 1kB ATE */ +#define XBRIDGE_ATE_RAM_SIZE (XBRIDGE_INTERNAL_ATES<<3) /* 8kB ATE */ + +#define BRIDGE_CONFIG_BASE 0x20000 /* start of bridge's */ + /* map to each device's */ + /* config space */ +#define BRIDGE_CONFIG1_BASE 0x28000 /* type 1 device config space */ +#define BRIDGE_CONFIG_END 0x30000 +#define BRIDGE_CONFIG_SLOT_SIZE 0x1000 /* each map == 4k */ + +#define BRIDGE_SSRAM_512K 0x00080000 /* 512kB */ +#define BRIDGE_SSRAM_128K 0x00020000 /* 128kB */ +#define BRIDGE_SSRAM_64K 0x00010000 /* 64kB */ +#define BRIDGE_SSRAM_0K 0x00000000 /* 0kB */ + +/* ======================================================================== + * Bridge address map + */ + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * All accesses to bridge hardware registers must be done + * using 32-bit loads and stores. + */ +typedef uint32_t bridgereg_t; + +typedef uint64_t bridge_ate_t; + +/* pointers to bridge ATEs + * are always "pointer to volatile" + */ +typedef volatile bridge_ate_t *bridge_ate_p; + +/* + * It is generally preferred that hardware registers on the bridge + * are located from C code via this structure. + * + * Generated from Bridge spec dated 04oct95 + */ + +#ifdef LITTLE_ENDIAN + +typedef volatile struct bridge_s { + + /* Local Registers 0x000000-0x00FFFF */ + + /* standard widget configuration 0x000000-0x000057 */ + widget_cfg_t b_widget; /* 0x000000 */ + + /* helper fieldnames for accessing bridge widget */ + +#define b_wid_id b_widget.w_id +#define b_wid_stat b_widget.w_status +#define b_wid_err_upper b_widget.w_err_upper_addr +#define b_wid_err_lower b_widget.w_err_lower_addr +#define b_wid_control b_widget.w_control +#define b_wid_req_timeout b_widget.w_req_timeout +#define b_wid_int_upper b_widget.w_intdest_upper_addr +#define b_wid_int_lower b_widget.w_intdest_lower_addr +#define b_wid_err_cmdword b_widget.w_err_cmd_word +#define b_wid_llp b_widget.w_llp_cfg +#define b_wid_tflush b_widget.w_tflush + + /* + * we access these through synergy unswizzled space, so the address + * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) + * That's why we put the register first and filler second. + */ + /* bridge-specific widget configuration 0x000058-0x00007F */ + bridgereg_t b_wid_aux_err; /* 0x00005C */ + bridgereg_t _pad_000058; + + bridgereg_t b_wid_resp_upper; /* 0x000064 */ + bridgereg_t _pad_000060; + + bridgereg_t b_wid_resp_lower; /* 0x00006C */ + bridgereg_t _pad_000068; + + bridgereg_t b_wid_tst_pin_ctrl; /* 0x000074 */ + bridgereg_t _pad_000070; + + bridgereg_t _pad_000078[2]; + + /* PMU & Map 0x000080-0x00008F */ + bridgereg_t b_dir_map; /* 0x000084 */ + bridgereg_t _pad_000080; + bridgereg_t _pad_000088[2]; + + /* SSRAM 0x000090-0x00009F */ + bridgereg_t b_ram_perr_or_map_fault;/* 0x000094 */ + bridgereg_t _pad_000090; +#define b_ram_perr b_ram_perr_or_map_fault /* Bridge */ +#define b_map_fault b_ram_perr_or_map_fault /* Xbridge */ + bridgereg_t _pad_000098[2]; + + /* Arbitration 0x0000A0-0x0000AF */ + bridgereg_t b_arb; /* 0x0000A4 */ + bridgereg_t _pad_0000A0; + bridgereg_t _pad_0000A8[2]; + + /* Number In A Can 0x0000B0-0x0000BF */ + bridgereg_t b_nic; /* 0x0000B4 */ + bridgereg_t _pad_0000B0; + bridgereg_t _pad_0000B8[2]; + + /* PCI/GIO 0x0000C0-0x0000FF */ + bridgereg_t b_bus_timeout; /* 0x0000C4 */ + bridgereg_t _pad_0000C0; +#define b_pci_bus_timeout b_bus_timeout + + bridgereg_t b_pci_cfg; /* 0x0000CC */ + bridgereg_t _pad_0000C8; + + bridgereg_t b_pci_err_upper; /* 0x0000D4 */ + bridgereg_t _pad_0000D0; + + bridgereg_t b_pci_err_lower; /* 0x0000DC */ + bridgereg_t _pad_0000D8; + bridgereg_t _pad_0000E0[8]; +#define b_gio_err_lower b_pci_err_lower +#define b_gio_err_upper b_pci_err_upper + + /* Interrupt 0x000100-0x0001FF */ + bridgereg_t b_int_status; /* 0x000104 */ + bridgereg_t _pad_000100; + + bridgereg_t b_int_enable; /* 0x00010C */ + bridgereg_t _pad_000108; + + bridgereg_t b_int_rst_stat; /* 0x000114 */ + bridgereg_t _pad_000110; + + bridgereg_t b_int_mode; /* 0x00011C */ + bridgereg_t _pad_000118; + + bridgereg_t b_int_device; /* 0x000124 */ + bridgereg_t _pad_000120; + + bridgereg_t b_int_host_err; /* 0x00012C */ + bridgereg_t _pad_000128; + + struct { + bridgereg_t addr; /* 0x0001{34,,,6C} */ + bridgereg_t __pad; /* 0x0001{30,,,68} */ + } b_int_addr[8]; /* 0x000130 */ + + bridgereg_t b_err_int_view; /* 0x000174 */ + bridgereg_t _pad_000170; + + bridgereg_t b_mult_int; /* 0x00017c */ + bridgereg_t _pad_000178; + + struct { + bridgereg_t intr; /* 0x0001{84,,,BC} */ + bridgereg_t __pad; /* 0x0001{80,,,B8} */ + } b_force_always[8]; /* 0x000180 */ + + struct { + bridgereg_t intr; /* 0x0001{C4,,,FC} */ + bridgereg_t __pad; /* 0x0001{C0,,,F8} */ + } b_force_pin[8]; /* 0x0001C0 */ + + /* Device 0x000200-0x0003FF */ + struct { + bridgereg_t reg; /* 0x0002{04,,,3C} */ + bridgereg_t __pad; /* 0x0002{00,,,38} */ + } b_device[8]; /* 0x000200 */ + + struct { + bridgereg_t reg; /* 0x0002{44,,,7C} */ + bridgereg_t __pad; /* 0x0002{40,,,78} */ + } b_wr_req_buf[8]; /* 0x000240 */ + + struct { + bridgereg_t reg; /* 0x0002{84,,,8C} */ + bridgereg_t __pad; /* 0x0002{80,,,88} */ + } b_rrb_map[2]; /* 0x000280 */ +#define b_even_resp b_rrb_map[0].reg /* 0x000284 */ +#define b_odd_resp b_rrb_map[1].reg /* 0x00028C */ + + bridgereg_t b_resp_status; /* 0x000294 */ + bridgereg_t _pad_000290; + + bridgereg_t b_resp_clear; /* 0x00029C */ + bridgereg_t _pad_000298; + + bridgereg_t _pad_0002A0[24]; + + /* Xbridge only */ + struct { + bridgereg_t upper; /* 0x0003{04,,,F4} */ + bridgereg_t __pad1; /* 0x0003{00,,,F0} */ + bridgereg_t lower; /* 0x0003{0C,,,FC} */ + bridgereg_t __pad2; /* 0x0003{08,,,F8} */ + } b_buf_addr_match[16]; + + /* Performance Monitor Registers (even only) */ + struct { + bridgereg_t flush_w_touch; /* 0x000404,,,5C4 */ + bridgereg_t __pad1; /* 0x000400,,,5C0 */ + + bridgereg_t flush_wo_touch; /* 0x00040C,,,5CC */ + bridgereg_t __pad2; /* 0x000408,,,5C8 */ + + bridgereg_t inflight; /* 0x000414,,,5D4 */ + bridgereg_t __pad3; /* 0x000410,,,5D0 */ + + bridgereg_t prefetch; /* 0x00041C,,,5DC */ + bridgereg_t __pad4; /* 0x000418,,,5D8 */ + + bridgereg_t total_pci_retry; /* 0x000424,,,5E4 */ + bridgereg_t __pad5; /* 0x000420,,,5E0 */ + + bridgereg_t max_pci_retry; /* 0x00042C,,,5EC */ + bridgereg_t __pad6; /* 0x000428,,,5E8 */ + + bridgereg_t max_latency; /* 0x000434,,,5F4 */ + bridgereg_t __pad7; /* 0x000430,,,5F0 */ + + bridgereg_t clear_all; /* 0x00043C,,,5FC */ + bridgereg_t __pad8; /* 0x000438,,,5F8 */ + } b_buf_count[8]; + + char _pad_000600[0x010000 - 0x000600]; + + /* + * The Xbridge has 1024 internal ATE's and the Bridge has 128. + * Make enough room for the Xbridge ATE's and depend on runtime + * checks to limit access to bridge ATE's. + */ + + /* Internal Address Translation Entry RAM 0x010000-0x011fff */ + union { + bridge_ate_t wr; /* write-only */ + struct { + bridgereg_t rd; /* read-only */ + bridgereg_t _p_pad; + } hi; + } b_int_ate_ram[XBRIDGE_INTERNAL_ATES]; + +#define b_int_ate_ram_lo(idx) b_int_ate_ram[idx+512].hi.rd + + /* the xbridge read path for internal ates starts at 0x12000. + * I don't believe we ever try to read the ates. + */ + /* Internal Address Translation Entry RAM LOW 0x012000-0x013fff */ + struct { + bridgereg_t rd; + bridgereg_t _p_pad; + } xb_int_ate_ram_lo[XBRIDGE_INTERNAL_ATES]; + + char _pad_014000[0x20000 - 0x014000]; + + /* PCI Device Configuration Spaces 0x020000-0x027FFF */ + union { /* make all access sizes available. */ + uchar_t c[0x1000 / 1]; + uint16_t s[0x1000 / 2]; + uint32_t l[0x1000 / 4]; + uint64_t d[0x1000 / 8]; + union { + uchar_t c[0x100 / 1]; + uint16_t s[0x100 / 2]; + uint32_t l[0x100 / 4]; + uint64_t d[0x100 / 8]; + } f[8]; + } b_type0_cfg_dev[8]; /* 0x020000 */ + + /* PCI Type 1 Configuration Space 0x028000-0x028FFF */ + union { /* make all access sizes available. */ + uchar_t c[0x1000 / 1]; + uint16_t s[0x1000 / 2]; + uint32_t l[0x1000 / 4]; + uint64_t d[0x1000 / 8]; + } b_type1_cfg; /* 0x028000-0x029000 */ + + char _pad_029000[0x007000]; /* 0x029000-0x030000 */ + + /* PCI Interrupt Acknowledge Cycle 0x030000 */ + union { + uchar_t c[8 / 1]; + uint16_t s[8 / 2]; + uint32_t l[8 / 4]; + uint64_t d[8 / 8]; + } b_pci_iack; /* 0x030000 */ + + uchar_t _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */ + + /* External Address Translation Entry RAM 0x080000-0x0FFFFF */ + bridge_ate_t b_ext_ate_ram[0x10000]; + + /* Reserved 0x100000-0x1FFFFF */ + char _pad_100000[0x200000-0x100000]; + + /* PCI/GIO Device Spaces 0x200000-0xBFFFFF */ + union { /* make all access sizes available. */ + uchar_t c[0x100000 / 1]; + uint16_t s[0x100000 / 2]; + uint32_t l[0x100000 / 4]; + uint64_t d[0x100000 / 8]; + } b_devio_raw[10]; /* 0x200000 */ + + /* b_devio macro is a bit strange; it reflects the + * fact that the Bridge ASIC provides 2M for the + * first two DevIO windows and 1M for the other six. + */ +#define b_devio(n) b_devio_raw[((n)<2)?(n*2):(n+2)] + + /* External Flash Proms 1,0 0xC00000-0xFFFFFF */ + union { /* make all access sizes available. */ + uchar_t c[0x400000 / 1]; /* read-only */ + uint16_t s[0x400000 / 2]; /* read-write */ + uint32_t l[0x400000 / 4]; /* read-only */ + uint64_t d[0x400000 / 8]; /* read-only */ + } b_external_flash; /* 0xC00000 */ +} bridge_t; + +#else + +/* + * Field formats for Error Command Word and Auxillary Error Command Word + * of bridge. + */ +typedef struct bridge_err_cmdword_s { + union { + uint32_t cmd_word; + struct { + uint32_t didn:4, /* Destination ID */ + sidn:4, /* SOurce ID */ + pactyp:4, /* Packet type */ + tnum:5, /* Trans Number */ + coh:1, /* Coh Transacti */ + ds:2, /* Data size */ + gbr:1, /* GBR enable */ + vbpm:1, /* VBPM message */ + error:1, /* Error occured */ + barr:1, /* Barrier op */ + rsvd:8; + } berr_st; + } berr_un; +} bridge_err_cmdword_t; + +typedef volatile struct bridge_s { + + /* Local Registers 0x000000-0x00FFFF */ + + /* standard widget configuration 0x000000-0x000057 */ + widget_cfg_t b_widget; /* 0x000000 */ + + /* helper fieldnames for accessing bridge widget */ + +#define b_wid_id b_widget.w_id +#define b_wid_stat b_widget.w_status +#define b_wid_err_upper b_widget.w_err_upper_addr +#define b_wid_err_lower b_widget.w_err_lower_addr +#define b_wid_control b_widget.w_control +#define b_wid_req_timeout b_widget.w_req_timeout +#define b_wid_int_upper b_widget.w_intdest_upper_addr +#define b_wid_int_lower b_widget.w_intdest_lower_addr +#define b_wid_err_cmdword b_widget.w_err_cmd_word +#define b_wid_llp b_widget.w_llp_cfg +#define b_wid_tflush b_widget.w_tflush + + /* bridge-specific widget configuration 0x000058-0x00007F */ + bridgereg_t _pad_000058; + bridgereg_t b_wid_aux_err; /* 0x00005C */ + bridgereg_t _pad_000060; + bridgereg_t b_wid_resp_upper; /* 0x000064 */ + bridgereg_t _pad_000068; + bridgereg_t b_wid_resp_lower; /* 0x00006C */ + bridgereg_t _pad_000070; + bridgereg_t b_wid_tst_pin_ctrl; /* 0x000074 */ + bridgereg_t _pad_000078[2]; + + /* PMU & Map 0x000080-0x00008F */ + bridgereg_t _pad_000080; + bridgereg_t b_dir_map; /* 0x000084 */ + bridgereg_t _pad_000088[2]; + + /* SSRAM 0x000090-0x00009F */ + bridgereg_t _pad_000090; + bridgereg_t b_ram_perr_or_map_fault;/* 0x000094 */ +#define b_ram_perr b_ram_perr_or_map_fault /* Bridge */ +#define b_map_fault b_ram_perr_or_map_fault /* Xbridge */ + bridgereg_t _pad_000098[2]; + + /* Arbitration 0x0000A0-0x0000AF */ + bridgereg_t _pad_0000A0; + bridgereg_t b_arb; /* 0x0000A4 */ + bridgereg_t _pad_0000A8[2]; + + /* Number In A Can 0x0000B0-0x0000BF */ + bridgereg_t _pad_0000B0; + bridgereg_t b_nic; /* 0x0000B4 */ + bridgereg_t _pad_0000B8[2]; + + /* PCI/GIO 0x0000C0-0x0000FF */ + bridgereg_t _pad_0000C0; + bridgereg_t b_bus_timeout; /* 0x0000C4 */ +#define b_pci_bus_timeout b_bus_timeout + + bridgereg_t _pad_0000C8; + bridgereg_t b_pci_cfg; /* 0x0000CC */ + bridgereg_t _pad_0000D0; + bridgereg_t b_pci_err_upper; /* 0x0000D4 */ + bridgereg_t _pad_0000D8; + bridgereg_t b_pci_err_lower; /* 0x0000DC */ + bridgereg_t _pad_0000E0[8]; +#define b_gio_err_lower b_pci_err_lower +#define b_gio_err_upper b_pci_err_upper + + /* Interrupt 0x000100-0x0001FF */ + bridgereg_t _pad_000100; + bridgereg_t b_int_status; /* 0x000104 */ + bridgereg_t _pad_000108; + bridgereg_t b_int_enable; /* 0x00010C */ + bridgereg_t _pad_000110; + bridgereg_t b_int_rst_stat; /* 0x000114 */ + bridgereg_t _pad_000118; + bridgereg_t b_int_mode; /* 0x00011C */ + bridgereg_t _pad_000120; + bridgereg_t b_int_device; /* 0x000124 */ + bridgereg_t _pad_000128; + bridgereg_t b_int_host_err; /* 0x00012C */ + + struct { + bridgereg_t __pad; /* 0x0001{30,,,68} */ + bridgereg_t addr; /* 0x0001{34,,,6C} */ + } b_int_addr[8]; /* 0x000130 */ + + bridgereg_t _pad_000170; + bridgereg_t b_err_int_view; /* 0x000174 */ + bridgereg_t _pad_000178; + bridgereg_t b_mult_int; /* 0x00017c */ + + struct { + bridgereg_t __pad; /* 0x0001{80,,,B8} */ + bridgereg_t intr; /* 0x0001{84,,,BC} */ + } b_force_always[8]; /* 0x000180 */ + + struct { + bridgereg_t __pad; /* 0x0001{C0,,,F8} */ + bridgereg_t intr; /* 0x0001{C4,,,FC} */ + } b_force_pin[8]; /* 0x0001C0 */ + + /* Device 0x000200-0x0003FF */ + struct { + bridgereg_t __pad; /* 0x0002{00,,,38} */ + bridgereg_t reg; /* 0x0002{04,,,3C} */ + } b_device[8]; /* 0x000200 */ + + struct { + bridgereg_t __pad; /* 0x0002{40,,,78} */ + bridgereg_t reg; /* 0x0002{44,,,7C} */ + } b_wr_req_buf[8]; /* 0x000240 */ + + struct { + bridgereg_t __pad; /* 0x0002{80,,,88} */ + bridgereg_t reg; /* 0x0002{84,,,8C} */ + } b_rrb_map[2]; /* 0x000280 */ +#define b_even_resp b_rrb_map[0].reg /* 0x000284 */ +#define b_odd_resp b_rrb_map[1].reg /* 0x00028C */ + + bridgereg_t _pad_000290; + bridgereg_t b_resp_status; /* 0x000294 */ + bridgereg_t _pad_000298; + bridgereg_t b_resp_clear; /* 0x00029C */ + + bridgereg_t _pad_0002A0[24]; + + /* Xbridge only */ + struct { + bridgereg_t __pad1; /* 0x0003{00,,,F0} */ + bridgereg_t upper; /* 0x0003{04,,,F4} */ + bridgereg_t __pad2; /* 0x0003{08,,,F8} */ + bridgereg_t lower; /* 0x0003{0C,,,FC} */ + } b_buf_addr_match[16]; + + /* Performance Monitor Registers (even only) */ + struct { + bridgereg_t __pad1; /* 0x000400,,,5C0 */ + bridgereg_t flush_w_touch; /* 0x000404,,,5C4 */ + bridgereg_t __pad2; /* 0x000408,,,5C8 */ + bridgereg_t flush_wo_touch; /* 0x00040C,,,5CC */ + bridgereg_t __pad3; /* 0x000410,,,5D0 */ + bridgereg_t inflight; /* 0x000414,,,5D4 */ + bridgereg_t __pad4; /* 0x000418,,,5D8 */ + bridgereg_t prefetch; /* 0x00041C,,,5DC */ + bridgereg_t __pad5; /* 0x000420,,,5E0 */ + bridgereg_t total_pci_retry; /* 0x000424,,,5E4 */ + bridgereg_t __pad6; /* 0x000428,,,5E8 */ + bridgereg_t max_pci_retry; /* 0x00042C,,,5EC */ + bridgereg_t __pad7; /* 0x000430,,,5F0 */ + bridgereg_t max_latency; /* 0x000434,,,5F4 */ + bridgereg_t __pad8; /* 0x000438,,,5F8 */ + bridgereg_t clear_all; /* 0x00043C,,,5FC */ + } b_buf_count[8]; + + char _pad_000600[0x010000 - 0x000600]; + + /* + * The Xbridge has 1024 internal ATE's and the Bridge has 128. + * Make enough room for the Xbridge ATE's and depend on runtime + * checks to limit access to bridge ATE's. + */ + + /* Internal Address Translation Entry RAM 0x010000-0x011fff */ + union { + bridge_ate_t wr; /* write-only */ + struct { + bridgereg_t _p_pad; + bridgereg_t rd; /* read-only */ + } hi; + } b_int_ate_ram[XBRIDGE_INTERNAL_ATES]; + +#define b_int_ate_ram_lo(idx) b_int_ate_ram[idx+512].hi.rd + + /* the xbridge read path for internal ates starts at 0x12000. + * I don't believe we ever try to read the ates. + */ + /* Internal Address Translation Entry RAM LOW 0x012000-0x013fff */ + struct { + bridgereg_t _p_pad; + bridgereg_t rd; /* read-only */ + } xb_int_ate_ram_lo[XBRIDGE_INTERNAL_ATES]; + + char _pad_014000[0x20000 - 0x014000]; + + /* PCI Device Configuration Spaces 0x020000-0x027FFF */ + union { /* make all access sizes available. */ + uchar_t c[0x1000 / 1]; + uint16_t s[0x1000 / 2]; + uint32_t l[0x1000 / 4]; + uint64_t d[0x1000 / 8]; + union { + uchar_t c[0x100 / 1]; + uint16_t s[0x100 / 2]; + uint32_t l[0x100 / 4]; + uint64_t d[0x100 / 8]; + } f[8]; + } b_type0_cfg_dev[8]; /* 0x020000 */ + + + /* PCI Type 1 Configuration Space 0x028000-0x028FFF */ + union { /* make all access sizes available. */ + uchar_t c[0x1000 / 1]; + uint16_t s[0x1000 / 2]; + uint32_t l[0x1000 / 4]; + uint64_t d[0x1000 / 8]; + } b_type1_cfg; /* 0x028000-0x029000 */ + + char _pad_029000[0x007000]; /* 0x029000-0x030000 */ + + /* PCI Interrupt Acknowledge Cycle 0x030000 */ + union { + uchar_t c[8 / 1]; + uint16_t s[8 / 2]; + uint32_t l[8 / 4]; + uint64_t d[8 / 8]; + } b_pci_iack; /* 0x030000 */ + + uchar_t _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */ + + /* External Address Translation Entry RAM 0x080000-0x0FFFFF */ + bridge_ate_t b_ext_ate_ram[0x10000]; + + /* Reserved 0x100000-0x1FFFFF */ + char _pad_100000[0x200000-0x100000]; + + /* PCI/GIO Device Spaces 0x200000-0xBFFFFF */ + union { /* make all access sizes available. */ + uchar_t c[0x100000 / 1]; + uint16_t s[0x100000 / 2]; + uint32_t l[0x100000 / 4]; + uint64_t d[0x100000 / 8]; + } b_devio_raw[10]; /* 0x200000 */ + + /* b_devio macro is a bit strange; it reflects the + * fact that the Bridge ASIC provides 2M for the + * first two DevIO windows and 1M for the other six. + */ +#define b_devio(n) b_devio_raw[((n)<2)?(n*2):(n+2)] + + /* External Flash Proms 1,0 0xC00000-0xFFFFFF */ + union { /* make all access sizes available. */ + uchar_t c[0x400000 / 1]; /* read-only */ + uint16_t s[0x400000 / 2]; /* read-write */ + uint32_t l[0x400000 / 4]; /* read-only */ + uint64_t d[0x400000 / 8]; /* read-only */ + } b_external_flash; /* 0xC00000 */ +} bridge_t; + +#endif + + + + + + +#define berr_field berr_un.berr_st +#endif /* LANGUAGE_C */ + +/* + * The values of these macros can and should be crosschecked + * regularly against the offsets of the like-named fields + * within the "bridge_t" structure above. + */ + +/* Byte offset macros for Bridge internal registers */ + +#define BRIDGE_WID_ID WIDGET_ID +#define BRIDGE_WID_STAT WIDGET_STATUS +#define BRIDGE_WID_ERR_UPPER WIDGET_ERR_UPPER_ADDR +#define BRIDGE_WID_ERR_LOWER WIDGET_ERR_LOWER_ADDR +#define BRIDGE_WID_CONTROL WIDGET_CONTROL +#define BRIDGE_WID_REQ_TIMEOUT WIDGET_REQ_TIMEOUT +#define BRIDGE_WID_INT_UPPER WIDGET_INTDEST_UPPER_ADDR +#define BRIDGE_WID_INT_LOWER WIDGET_INTDEST_LOWER_ADDR +#define BRIDGE_WID_ERR_CMDWORD WIDGET_ERR_CMD_WORD +#define BRIDGE_WID_LLP WIDGET_LLP_CFG +#define BRIDGE_WID_TFLUSH WIDGET_TFLUSH + +#define BRIDGE_WID_AUX_ERR 0x00005C /* Aux Error Command Word */ +#define BRIDGE_WID_RESP_UPPER 0x000064 /* Response Buf Upper Addr */ +#define BRIDGE_WID_RESP_LOWER 0x00006C /* Response Buf Lower Addr */ +#define BRIDGE_WID_TST_PIN_CTRL 0x000074 /* Test pin control */ + +#define BRIDGE_DIR_MAP 0x000084 /* Direct Map reg */ + +/* Bridge has SSRAM Parity Error and Xbridge has Map Fault here */ +#define BRIDGE_RAM_PERR 0x000094 /* SSRAM Parity Error */ +#define BRIDGE_MAP_FAULT 0x000094 /* Map Fault */ + +#define BRIDGE_ARB 0x0000A4 /* Arbitration Priority reg */ + +#define BRIDGE_NIC 0x0000B4 /* Number In A Can */ + +#define BRIDGE_BUS_TIMEOUT 0x0000C4 /* Bus Timeout Register */ +#define BRIDGE_PCI_BUS_TIMEOUT BRIDGE_BUS_TIMEOUT +#define BRIDGE_PCI_CFG 0x0000CC /* PCI Type 1 Config reg */ +#define BRIDGE_PCI_ERR_UPPER 0x0000D4 /* PCI error Upper Addr */ +#define BRIDGE_PCI_ERR_LOWER 0x0000DC /* PCI error Lower Addr */ + +#define BRIDGE_INT_STATUS 0x000104 /* Interrupt Status */ +#define BRIDGE_INT_ENABLE 0x00010C /* Interrupt Enables */ +#define BRIDGE_INT_RST_STAT 0x000114 /* Reset Intr Status */ +#define BRIDGE_INT_MODE 0x00011C /* Interrupt Mode */ +#define BRIDGE_INT_DEVICE 0x000124 /* Interrupt Device */ +#define BRIDGE_INT_HOST_ERR 0x00012C /* Host Error Field */ + +#define BRIDGE_INT_ADDR0 0x000134 /* Host Address Reg */ +#define BRIDGE_INT_ADDR_OFF 0x000008 /* Host Addr offset (1..7) */ +#define BRIDGE_INT_ADDR(x) (BRIDGE_INT_ADDR0+(x)*BRIDGE_INT_ADDR_OFF) + +#define BRIDGE_INT_VIEW 0x000174 /* Interrupt view */ +#define BRIDGE_MULTIPLE_INT 0x00017c /* Multiple interrupt occured */ + +#define BRIDGE_FORCE_ALWAYS0 0x000184 /* Force an interrupt (always)*/ +#define BRIDGE_FORCE_ALWAYS_OFF 0x000008 /* Force Always offset */ +#define BRIDGE_FORCE_ALWAYS(x) (BRIDGE_FORCE_ALWAYS0+(x)*BRIDGE_FORCE_ALWAYS_OFF) + +#define BRIDGE_FORCE_PIN0 0x0001c4 /* Force an interrupt */ +#define BRIDGE_FORCE_PIN_OFF 0x000008 /* Force Pin offset */ +#define BRIDGE_FORCE_PIN(x) (BRIDGE_FORCE_PIN0+(x)*BRIDGE_FORCE_PIN_OFF) + +#define BRIDGE_DEVICE0 0x000204 /* Device 0 */ +#define BRIDGE_DEVICE_OFF 0x000008 /* Device offset (1..7) */ +#define BRIDGE_DEVICE(x) (BRIDGE_DEVICE0+(x)*BRIDGE_DEVICE_OFF) + +#define BRIDGE_WR_REQ_BUF0 0x000244 /* Write Request Buffer 0 */ +#define BRIDGE_WR_REQ_BUF_OFF 0x000008 /* Buffer Offset (1..7) */ +#define BRIDGE_WR_REQ_BUF(x) (BRIDGE_WR_REQ_BUF0+(x)*BRIDGE_WR_REQ_BUF_OFF) + +#define BRIDGE_EVEN_RESP 0x000284 /* Even Device Response Buf */ +#define BRIDGE_ODD_RESP 0x00028C /* Odd Device Response Buf */ + +#define BRIDGE_RESP_STATUS 0x000294 /* Read Response Status reg */ +#define BRIDGE_RESP_CLEAR 0x00029C /* Read Response Clear reg */ + +#define BRIDGE_BUF_ADDR_UPPER0 0x000304 +#define BRIDGE_BUF_ADDR_UPPER_OFF 0x000010 /* PCI Buffer Upper Offset */ +#define BRIDGE_BUF_ADDR_UPPER(x) (BRIDGE_BUF_ADDR_UPPER0+(x)*BRIDGE_BUF_ADDR_UPPER_OFF) + +#define BRIDGE_BUF_ADDR_LOWER0 0x00030c +#define BRIDGE_BUF_ADDR_LOWER_OFF 0x000010 /* PCI Buffer Upper Offset */ +#define BRIDGE_BUF_ADDR_LOWER(x) (BRIDGE_BUF_ADDR_LOWER0+(x)*BRIDGE_BUF_ADDR_LOWER_OFF) + +/* + * Performance Monitor Registers. + * + * The Performance registers are those registers which are associated with + * monitoring the performance of PCI generated reads to the host environ + * ment. Because of the size of the register file only the even registers + * were instrumented. + */ + +#define BRIDGE_BUF_OFF 0x40 +#define BRIDGE_BUF_NEXT(base, off) (base+((off)*BRIDGE_BUF_OFF)) + +/* + * Buffer (x) Flush Count with Data Touch Register. + * + * This counter is incremented each time the corresponding response buffer + * is flushed after at least a single data element in the buffer is used. + * A word write to this address clears the count. + */ + +#define BRIDGE_BUF_0_FLUSH_TOUCH 0x000404 +#define BRIDGE_BUF_2_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 1) +#define BRIDGE_BUF_4_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 2) +#define BRIDGE_BUF_6_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 3) +#define BRIDGE_BUF_8_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 4) +#define BRIDGE_BUF_10_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 5) +#define BRIDGE_BUF_12_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 6) +#define BRIDGE_BUF_14_FLUSH_TOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_TOUCH, 7) + +/* + * Buffer (x) Flush Count w/o Data Touch Register + * + * This counter is incremented each time the corresponding response buffer + * is flushed without any data element in the buffer being used. A word + * write to this address clears the count. + */ + + +#define BRIDGE_BUF_0_FLUSH_NOTOUCH 0x00040c +#define BRIDGE_BUF_2_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 1) +#define BRIDGE_BUF_4_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 2) +#define BRIDGE_BUF_6_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 3) +#define BRIDGE_BUF_8_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 4) +#define BRIDGE_BUF_10_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 5) +#define BRIDGE_BUF_12_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 6) +#define BRIDGE_BUF_14_FLUSH_NOTOUCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_FLUSH_NOTOUCH, 7) + +/* + * Buffer (x) Request in Flight Count Register + * + * This counter is incremented on each bus clock while the request is in + * flight. A word write to this address clears the count. + */ + +#define BRIDGE_BUF_0_INFLIGHT 0x000414 +#define BRIDGE_BUF_2_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 1) +#define BRIDGE_BUF_4_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 2) +#define BRIDGE_BUF_6_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 3) +#define BRIDGE_BUF_8_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 4) +#define BRIDGE_BUF_10_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 5) +#define BRIDGE_BUF_12_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 6) +#define BRIDGE_BUF_14_INFLIGHT BRIDGE_BUF_NEXT(BRIDGE_BUF_0_INFLIGHT, 7) + +/* + * Buffer (x) Prefetch Request Count Register + * + * This counter is incremented each time the request using this buffer was + * generated from the prefetcher. A word write to this address clears the + * count. + */ + +#define BRIDGE_BUF_0_PREFETCH 0x00041C +#define BRIDGE_BUF_2_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 1) +#define BRIDGE_BUF_4_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 2) +#define BRIDGE_BUF_6_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 3) +#define BRIDGE_BUF_8_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 4) +#define BRIDGE_BUF_10_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 5) +#define BRIDGE_BUF_12_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 6) +#define BRIDGE_BUF_14_PREFETCH BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PREFETCH, 7) + +/* + * Buffer (x) Total PCI Retry Count Register + * + * This counter is incremented each time a PCI bus retry occurs and the ad + * dress matches the tag for the selected buffer. The buffer must also has + * this request in-flight. A word write to this address clears the count. + */ + +#define BRIDGE_BUF_0_PCI_RETRY 0x000424 +#define BRIDGE_BUF_2_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 1) +#define BRIDGE_BUF_4_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 2) +#define BRIDGE_BUF_6_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 3) +#define BRIDGE_BUF_8_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 4) +#define BRIDGE_BUF_10_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 5) +#define BRIDGE_BUF_12_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 6) +#define BRIDGE_BUF_14_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_PCI_RETRY, 7) + +/* + * Buffer (x) Max PCI Retry Count Register + * + * This counter is contains the maximum retry count for a single request + * which was in-flight for this buffer. A word write to this address + * clears the count. + */ + +#define BRIDGE_BUF_0_MAX_PCI_RETRY 0x00042C +#define BRIDGE_BUF_2_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 1) +#define BRIDGE_BUF_4_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 2) +#define BRIDGE_BUF_6_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 3) +#define BRIDGE_BUF_8_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 4) +#define BRIDGE_BUF_10_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 5) +#define BRIDGE_BUF_12_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 6) +#define BRIDGE_BUF_14_MAX_PCI_RETRY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_PCI_RETRY, 7) + +/* + * Buffer (x) Max Latency Count Register + * + * This counter is contains the maximum count (in bus clocks) for a single + * request which was in-flight for this buffer. A word write to this + * address clears the count. + */ + +#define BRIDGE_BUF_0_MAX_LATENCY 0x000434 +#define BRIDGE_BUF_2_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 1) +#define BRIDGE_BUF_4_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 2) +#define BRIDGE_BUF_6_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 3) +#define BRIDGE_BUF_8_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 4) +#define BRIDGE_BUF_10_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 5) +#define BRIDGE_BUF_12_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 6) +#define BRIDGE_BUF_14_MAX_LATENCY BRIDGE_BUF_NEXT(BRIDGE_BUF_0_MAX_LATENCY, 7) + +/* + * Buffer (x) Clear All Register + * + * Any access to this register clears all the count values for the (x) + * registers. + */ + +#define BRIDGE_BUF_0_CLEAR_ALL 0x00043C +#define BRIDGE_BUF_2_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 1) +#define BRIDGE_BUF_4_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 2) +#define BRIDGE_BUF_6_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 3) +#define BRIDGE_BUF_8_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 4) +#define BRIDGE_BUF_10_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 5) +#define BRIDGE_BUF_12_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 6) +#define BRIDGE_BUF_14_CLEAR_ALL BRIDGE_BUF_NEXT(BRIDGE_BUF_0_CLEAR_ALL, 7) + +/* end of Performance Monitor Registers */ + +/* Byte offset macros for Bridge I/O space */ + +#define BRIDGE_ATE_RAM 0x00010000 /* Internal Addr Xlat Ram */ + +#define BRIDGE_TYPE0_CFG_DEV0 0x00020000 /* Type 0 Cfg, Device 0 */ +#define BRIDGE_TYPE0_CFG_SLOT_OFF 0x00001000 /* Type 0 Cfg Slot Offset (1..7) */ +#define BRIDGE_TYPE0_CFG_FUNC_OFF 0x00000100 /* Type 0 Cfg Func Offset (1..7) */ +#define BRIDGE_TYPE0_CFG_DEV(s) (BRIDGE_TYPE0_CFG_DEV0+\ + (s)*BRIDGE_TYPE0_CFG_SLOT_OFF) +#define BRIDGE_TYPE0_CFG_DEVF(s,f) (BRIDGE_TYPE0_CFG_DEV0+\ + (s)*BRIDGE_TYPE0_CFG_SLOT_OFF+\ + (f)*BRIDGE_TYPE0_CFG_FUNC_OFF) + +#define BRIDGE_TYPE1_CFG 0x00028000 /* Type 1 Cfg space */ + +#define BRIDGE_PCI_IACK 0x00030000 /* PCI Interrupt Ack */ +#define BRIDGE_EXT_SSRAM 0x00080000 /* Extern SSRAM (ATE) */ + +/* Byte offset macros for Bridge device IO spaces */ + +#define BRIDGE_DEV_CNT 8 /* Up to 8 devices per bridge */ +#define BRIDGE_DEVIO0 0x00200000 /* Device IO 0 Addr */ +#define BRIDGE_DEVIO1 0x00400000 /* Device IO 1 Addr */ +#define BRIDGE_DEVIO2 0x00600000 /* Device IO 2 Addr */ +#define BRIDGE_DEVIO_OFF 0x00100000 /* Device IO Offset (3..7) */ + +#define BRIDGE_DEVIO_2MB 0x00200000 /* Device IO Offset (0..1) */ +#define BRIDGE_DEVIO_1MB 0x00100000 /* Device IO Offset (2..7) */ + +#if LANGUAGE_C + +#define BRIDGE_DEVIO(x) ((x)<=1 ? BRIDGE_DEVIO0+(x)*BRIDGE_DEVIO_2MB : BRIDGE_DEVIO2+((x)-2)*BRIDGE_DEVIO_1MB) +#endif /* LANGUAGE_C */ + +#define BRIDGE_EXTERNAL_FLASH 0x00C00000 /* External Flash PROMS */ + +/* ======================================================================== + * Bridge register bit field definitions + */ + +/* Widget part number of bridge */ +#define BRIDGE_WIDGET_PART_NUM 0xc002 +#define XBRIDGE_WIDGET_PART_NUM 0xd002 + +/* Manufacturer of bridge */ +#define BRIDGE_WIDGET_MFGR_NUM 0x036 +#define XBRIDGE_WIDGET_MFGR_NUM 0x024 + +/* Revision numbers for known [X]Bridge revisions */ +#define BRIDGE_REV_A 0x1 +#define BRIDGE_REV_B 0x2 +#define BRIDGE_REV_C 0x3 +#define BRIDGE_REV_D 0x4 +#define XBRIDGE_REV_A 0x1 +#define XBRIDGE_REV_B 0x2 + +/* Part + Rev numbers allows distinction and acscending sequence */ +#define BRIDGE_PART_REV_A (BRIDGE_WIDGET_PART_NUM << 4 | BRIDGE_REV_A) +#define BRIDGE_PART_REV_B (BRIDGE_WIDGET_PART_NUM << 4 | BRIDGE_REV_B) +#define BRIDGE_PART_REV_C (BRIDGE_WIDGET_PART_NUM << 4 | BRIDGE_REV_C) +#define BRIDGE_PART_REV_D (BRIDGE_WIDGET_PART_NUM << 4 | BRIDGE_REV_D) +#define XBRIDGE_PART_REV_A (XBRIDGE_WIDGET_PART_NUM << 4 | XBRIDGE_REV_A) +#define XBRIDGE_PART_REV_B (XBRIDGE_WIDGET_PART_NUM << 4 | XBRIDGE_REV_B) + +/* Bridge widget status register bits definition */ + +#define BRIDGE_STAT_LLP_REC_CNT (0xFFu << 24) +#define BRIDGE_STAT_LLP_TX_CNT (0xFF << 16) +#define BRIDGE_STAT_FLASH_SELECT (0x1 << 6) +#define BRIDGE_STAT_PCI_GIO_N (0x1 << 5) +#define BRIDGE_STAT_PENDING (0x1F << 0) + +/* Bridge widget control register bits definition */ +#define BRIDGE_CTRL_FLASH_WR_EN (0x1ul << 31) +#define BRIDGE_CTRL_EN_CLK50 (0x1 << 30) +#define BRIDGE_CTRL_EN_CLK40 (0x1 << 29) +#define BRIDGE_CTRL_EN_CLK33 (0x1 << 28) +#define BRIDGE_CTRL_RST(n) ((n) << 24) +#define BRIDGE_CTRL_RST_MASK (BRIDGE_CTRL_RST(0xF)) +#define BRIDGE_CTRL_RST_PIN(x) (BRIDGE_CTRL_RST(0x1 << (x))) +#define BRIDGE_CTRL_IO_SWAP (0x1 << 23) +#define BRIDGE_CTRL_MEM_SWAP (0x1 << 22) +#define BRIDGE_CTRL_PAGE_SIZE (0x1 << 21) +#define BRIDGE_CTRL_SS_PAR_BAD (0x1 << 20) +#define BRIDGE_CTRL_SS_PAR_EN (0x1 << 19) +#define BRIDGE_CTRL_SSRAM_SIZE(n) ((n) << 17) +#define BRIDGE_CTRL_SSRAM_SIZE_MASK (BRIDGE_CTRL_SSRAM_SIZE(0x3)) +#define BRIDGE_CTRL_SSRAM_512K (BRIDGE_CTRL_SSRAM_SIZE(0x3)) +#define BRIDGE_CTRL_SSRAM_128K (BRIDGE_CTRL_SSRAM_SIZE(0x2)) +#define BRIDGE_CTRL_SSRAM_64K (BRIDGE_CTRL_SSRAM_SIZE(0x1)) +#define BRIDGE_CTRL_SSRAM_1K (BRIDGE_CTRL_SSRAM_SIZE(0x0)) +#define BRIDGE_CTRL_F_BAD_PKT (0x1 << 16) +#define BRIDGE_CTRL_LLP_XBAR_CRD(n) ((n) << 12) +#define BRIDGE_CTRL_LLP_XBAR_CRD_MASK (BRIDGE_CTRL_LLP_XBAR_CRD(0xf)) +#define BRIDGE_CTRL_CLR_RLLP_CNT (0x1 << 11) +#define BRIDGE_CTRL_CLR_TLLP_CNT (0x1 << 10) +#define BRIDGE_CTRL_SYS_END (0x1 << 9) +#define BRIDGE_CTRL_MAX_TRANS(n) ((n) << 4) +#define BRIDGE_CTRL_MAX_TRANS_MASK (BRIDGE_CTRL_MAX_TRANS(0x1f)) +#define BRIDGE_CTRL_WIDGET_ID(n) ((n) << 0) +#define BRIDGE_CTRL_WIDGET_ID_MASK (BRIDGE_CTRL_WIDGET_ID(0xf)) + +/* Bridge Response buffer Error Upper Register bit fields definition */ +#define BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT (20) +#define BRIDGE_RESP_ERRUPPR_DEVNUM_MASK (0x7 << BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT) +#define BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT (16) +#define BRIDGE_RESP_ERRUPPR_BUFNUM_MASK (0xF << BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT) +#define BRIDGE_RESP_ERRRUPPR_BUFMASK (0xFFFF) + +#define BRIDGE_RESP_ERRUPPR_BUFNUM(x) \ + (((x) & BRIDGE_RESP_ERRUPPR_BUFNUM_MASK) >> \ + BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT) + +#define BRIDGE_RESP_ERRUPPR_DEVICE(x) \ + (((x) & BRIDGE_RESP_ERRUPPR_DEVNUM_MASK) >> \ + BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT) + +/* Bridge direct mapping register bits definition */ +#define BRIDGE_DIRMAP_W_ID_SHFT 20 +#define BRIDGE_DIRMAP_W_ID (0xf << BRIDGE_DIRMAP_W_ID_SHFT) +#define BRIDGE_DIRMAP_RMF_64 (0x1 << 18) +#define BRIDGE_DIRMAP_ADD512 (0x1 << 17) +#define BRIDGE_DIRMAP_OFF (0x1ffff << 0) +#define BRIDGE_DIRMAP_OFF_ADDRSHFT (31) /* lsbit of DIRMAP_OFF is xtalk address bit 31 */ + +/* Bridge Arbitration register bits definition */ +#define BRIDGE_ARB_REQ_WAIT_TICK(x) ((x) << 16) +#define BRIDGE_ARB_REQ_WAIT_TICK_MASK BRIDGE_ARB_REQ_WAIT_TICK(0x3) +#define BRIDGE_ARB_REQ_WAIT_EN(x) ((x) << 8) +#define BRIDGE_ARB_REQ_WAIT_EN_MASK BRIDGE_ARB_REQ_WAIT_EN(0xff) +#define BRIDGE_ARB_FREEZE_GNT (1 << 6) +#define BRIDGE_ARB_HPRI_RING_B2 (1 << 5) +#define BRIDGE_ARB_HPRI_RING_B1 (1 << 4) +#define BRIDGE_ARB_HPRI_RING_B0 (1 << 3) +#define BRIDGE_ARB_LPRI_RING_B2 (1 << 2) +#define BRIDGE_ARB_LPRI_RING_B1 (1 << 1) +#define BRIDGE_ARB_LPRI_RING_B0 (1 << 0) + +/* Bridge Bus time-out register bits definition */ +#define BRIDGE_BUS_PCI_RETRY_HLD(x) ((x) << 16) +#define BRIDGE_BUS_PCI_RETRY_HLD_MASK BRIDGE_BUS_PCI_RETRY_HLD(0x1f) +#define BRIDGE_BUS_GIO_TIMEOUT (1 << 12) +#define BRIDGE_BUS_PCI_RETRY_CNT(x) ((x) << 0) +#define BRIDGE_BUS_PCI_RETRY_MASK BRIDGE_BUS_PCI_RETRY_CNT(0x3ff) + +/* Bridge interrupt status register bits definition */ +#define BRIDGE_ISR_MULTI_ERR (0x1u << 31) /* bridge only */ +#define BRIDGE_ISR_PMU_ESIZE_FAULT (0x1 << 30) /* bridge only */ +#define BRIDGE_ISR_PAGE_FAULT (0x1 << 30) /* xbridge only */ +#define BRIDGE_ISR_UNEXP_RESP (0x1 << 29) +#define BRIDGE_ISR_BAD_XRESP_PKT (0x1 << 28) +#define BRIDGE_ISR_BAD_XREQ_PKT (0x1 << 27) +#define BRIDGE_ISR_RESP_XTLK_ERR (0x1 << 26) +#define BRIDGE_ISR_REQ_XTLK_ERR (0x1 << 25) +#define BRIDGE_ISR_INVLD_ADDR (0x1 << 24) +#define BRIDGE_ISR_UNSUPPORTED_XOP (0x1 << 23) +#define BRIDGE_ISR_XREQ_FIFO_OFLOW (0x1 << 22) +#define BRIDGE_ISR_LLP_REC_SNERR (0x1 << 21) +#define BRIDGE_ISR_LLP_REC_CBERR (0x1 << 20) +#define BRIDGE_ISR_LLP_RCTY (0x1 << 19) +#define BRIDGE_ISR_LLP_TX_RETRY (0x1 << 18) +#define BRIDGE_ISR_LLP_TCTY (0x1 << 17) +#define BRIDGE_ISR_SSRAM_PERR (0x1 << 16) +#define BRIDGE_ISR_PCI_ABORT (0x1 << 15) +#define BRIDGE_ISR_PCI_PARITY (0x1 << 14) +#define BRIDGE_ISR_PCI_SERR (0x1 << 13) +#define BRIDGE_ISR_PCI_PERR (0x1 << 12) +#define BRIDGE_ISR_PCI_MST_TIMEOUT (0x1 << 11) +#define BRIDGE_ISR_GIO_MST_TIMEOUT BRIDGE_ISR_PCI_MST_TIMEOUT +#define BRIDGE_ISR_PCI_RETRY_CNT (0x1 << 10) +#define BRIDGE_ISR_XREAD_REQ_TIMEOUT (0x1 << 9) +#define BRIDGE_ISR_GIO_B_ENBL_ERR (0x1 << 8) +#define BRIDGE_ISR_INT_MSK (0xff << 0) +#define BRIDGE_ISR_INT(x) (0x1 << (x)) + +#define BRIDGE_ISR_LINK_ERROR \ + (BRIDGE_ISR_LLP_REC_SNERR|BRIDGE_ISR_LLP_REC_CBERR| \ + BRIDGE_ISR_LLP_RCTY|BRIDGE_ISR_LLP_TX_RETRY| \ + BRIDGE_ISR_LLP_TCTY) + +#define BRIDGE_ISR_PCIBUS_PIOERR \ + (BRIDGE_ISR_PCI_MST_TIMEOUT|BRIDGE_ISR_PCI_ABORT) + +#define BRIDGE_ISR_PCIBUS_ERROR \ + (BRIDGE_ISR_PCIBUS_PIOERR|BRIDGE_ISR_PCI_PERR| \ + BRIDGE_ISR_PCI_SERR|BRIDGE_ISR_PCI_RETRY_CNT| \ + BRIDGE_ISR_PCI_PARITY) + +#define BRIDGE_ISR_XTALK_ERROR \ + (BRIDGE_ISR_XREAD_REQ_TIMEOUT|BRIDGE_ISR_XREQ_FIFO_OFLOW|\ + BRIDGE_ISR_UNSUPPORTED_XOP|BRIDGE_ISR_INVLD_ADDR| \ + BRIDGE_ISR_REQ_XTLK_ERR|BRIDGE_ISR_RESP_XTLK_ERR| \ + BRIDGE_ISR_BAD_XREQ_PKT|BRIDGE_ISR_BAD_XRESP_PKT| \ + BRIDGE_ISR_UNEXP_RESP) + +#define BRIDGE_ISR_ERRORS \ + (BRIDGE_ISR_LINK_ERROR|BRIDGE_ISR_PCIBUS_ERROR| \ + BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR| \ + BRIDGE_ISR_PMU_ESIZE_FAULT) + +/* + * List of Errors which are fatal and kill the sytem + */ +#define BRIDGE_ISR_ERROR_FATAL \ + ((BRIDGE_ISR_XTALK_ERROR & ~BRIDGE_ISR_XREAD_REQ_TIMEOUT)|\ + BRIDGE_ISR_PCI_SERR|BRIDGE_ISR_PCI_PARITY ) + +#define BRIDGE_ISR_ERROR_DUMP \ + (BRIDGE_ISR_PCIBUS_ERROR|BRIDGE_ISR_PMU_ESIZE_FAULT| \ + BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR) + +/* Bridge interrupt enable register bits definition */ +#define BRIDGE_IMR_UNEXP_RESP BRIDGE_ISR_UNEXP_RESP +#define BRIDGE_IMR_PMU_ESIZE_FAULT BRIDGE_ISR_PMU_ESIZE_FAULT +#define BRIDGE_IMR_BAD_XRESP_PKT BRIDGE_ISR_BAD_XRESP_PKT +#define BRIDGE_IMR_BAD_XREQ_PKT BRIDGE_ISR_BAD_XREQ_PKT +#define BRIDGE_IMR_RESP_XTLK_ERR BRIDGE_ISR_RESP_XTLK_ERR +#define BRIDGE_IMR_REQ_XTLK_ERR BRIDGE_ISR_REQ_XTLK_ERR +#define BRIDGE_IMR_INVLD_ADDR BRIDGE_ISR_INVLD_ADDR +#define BRIDGE_IMR_UNSUPPORTED_XOP BRIDGE_ISR_UNSUPPORTED_XOP +#define BRIDGE_IMR_XREQ_FIFO_OFLOW BRIDGE_ISR_XREQ_FIFO_OFLOW +#define BRIDGE_IMR_LLP_REC_SNERR BRIDGE_ISR_LLP_REC_SNERR +#define BRIDGE_IMR_LLP_REC_CBERR BRIDGE_ISR_LLP_REC_CBERR +#define BRIDGE_IMR_LLP_RCTY BRIDGE_ISR_LLP_RCTY +#define BRIDGE_IMR_LLP_TX_RETRY BRIDGE_ISR_LLP_TX_RETRY +#define BRIDGE_IMR_LLP_TCTY BRIDGE_ISR_LLP_TCTY +#define BRIDGE_IMR_SSRAM_PERR BRIDGE_ISR_SSRAM_PERR +#define BRIDGE_IMR_PCI_ABORT BRIDGE_ISR_PCI_ABORT +#define BRIDGE_IMR_PCI_PARITY BRIDGE_ISR_PCI_PARITY +#define BRIDGE_IMR_PCI_SERR BRIDGE_ISR_PCI_SERR +#define BRIDGE_IMR_PCI_PERR BRIDGE_ISR_PCI_PERR +#define BRIDGE_IMR_PCI_MST_TIMEOUT BRIDGE_ISR_PCI_MST_TIMEOUT +#define BRIDGE_IMR_GIO_MST_TIMEOUT BRIDGE_ISR_GIO_MST_TIMEOUT +#define BRIDGE_IMR_PCI_RETRY_CNT BRIDGE_ISR_PCI_RETRY_CNT +#define BRIDGE_IMR_XREAD_REQ_TIMEOUT BRIDGE_ISR_XREAD_REQ_TIMEOUT +#define BRIDGE_IMR_GIO_B_ENBL_ERR BRIDGE_ISR_GIO_B_ENBL_ERR +#define BRIDGE_IMR_INT_MSK BRIDGE_ISR_INT_MSK +#define BRIDGE_IMR_INT(x) BRIDGE_ISR_INT(x) + +/* Bridge interrupt reset register bits definition */ +#define BRIDGE_IRR_MULTI_CLR (0x1 << 6) +#define BRIDGE_IRR_CRP_GRP_CLR (0x1 << 5) +#define BRIDGE_IRR_RESP_BUF_GRP_CLR (0x1 << 4) +#define BRIDGE_IRR_REQ_DSP_GRP_CLR (0x1 << 3) +#define BRIDGE_IRR_LLP_GRP_CLR (0x1 << 2) +#define BRIDGE_IRR_SSRAM_GRP_CLR (0x1 << 1) +#define BRIDGE_IRR_PCI_GRP_CLR (0x1 << 0) +#define BRIDGE_IRR_GIO_GRP_CLR (0x1 << 0) +#define BRIDGE_IRR_ALL_CLR 0x7f + +#define BRIDGE_IRR_CRP_GRP (BRIDGE_ISR_UNEXP_RESP | \ + BRIDGE_ISR_XREQ_FIFO_OFLOW) +#define BRIDGE_IRR_RESP_BUF_GRP (BRIDGE_ISR_BAD_XRESP_PKT | \ + BRIDGE_ISR_RESP_XTLK_ERR | \ + BRIDGE_ISR_XREAD_REQ_TIMEOUT) +#define BRIDGE_IRR_REQ_DSP_GRP (BRIDGE_ISR_UNSUPPORTED_XOP | \ + BRIDGE_ISR_BAD_XREQ_PKT | \ + BRIDGE_ISR_REQ_XTLK_ERR | \ + BRIDGE_ISR_INVLD_ADDR) +#define BRIDGE_IRR_LLP_GRP (BRIDGE_ISR_LLP_REC_SNERR | \ + BRIDGE_ISR_LLP_REC_CBERR | \ + BRIDGE_ISR_LLP_RCTY | \ + BRIDGE_ISR_LLP_TX_RETRY | \ + BRIDGE_ISR_LLP_TCTY) +#define BRIDGE_IRR_SSRAM_GRP (BRIDGE_ISR_SSRAM_PERR | \ + BRIDGE_ISR_PMU_ESIZE_FAULT) +#define BRIDGE_IRR_PCI_GRP (BRIDGE_ISR_PCI_ABORT | \ + BRIDGE_ISR_PCI_PARITY | \ + BRIDGE_ISR_PCI_SERR | \ + BRIDGE_ISR_PCI_PERR | \ + BRIDGE_ISR_PCI_MST_TIMEOUT | \ + BRIDGE_ISR_PCI_RETRY_CNT) + +#define BRIDGE_IRR_GIO_GRP (BRIDGE_ISR_GIO_B_ENBL_ERR | \ + BRIDGE_ISR_GIO_MST_TIMEOUT) + +/* Bridge INT_DEV register bits definition */ +#define BRIDGE_INT_DEV_SHFT(n) ((n)*3) +#define BRIDGE_INT_DEV_MASK(n) (0x7 << BRIDGE_INT_DEV_SHFT(n)) +#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line)) + +/* Bridge interrupt(x) register bits definition */ +#define BRIDGE_INT_ADDR_HOST 0x0003FF00 +#define BRIDGE_INT_ADDR_FLD 0x000000FF + +#define BRIDGE_TMO_PCI_RETRY_HLD_MASK 0x1f0000 +#define BRIDGE_TMO_GIO_TIMEOUT_MASK 0x001000 +#define BRIDGE_TMO_PCI_RETRY_CNT_MASK 0x0003ff + +#define BRIDGE_TMO_PCI_RETRY_CNT_MAX 0x3ff + +#ifdef SN0 +/* + * The NASID should be shifted by this amount and stored into the + * interrupt(x) register. + */ +#define BRIDGE_INT_ADDR_NASID_SHFT 8 + +/* + * The BRIDGE_INT_ADDR_DEST_IO bit should be set to send an interrupt to + * memory. + */ +#define BRIDGE_INT_ADDR_DEST_IO (1 << 17) +#define BRIDGE_INT_ADDR_DEST_MEM 0 +#define BRIDGE_INT_ADDR_MASK (1 << 17) +#endif + +/* Bridge device(x) register bits definition */ +#define BRIDGE_DEV_ERR_LOCK_EN (1ull << 28) +#define BRIDGE_DEV_PAGE_CHK_DIS (1ull << 27) +#define BRIDGE_DEV_FORCE_PCI_PAR (1ull << 26) +#define BRIDGE_DEV_VIRTUAL_EN (1ull << 25) +#define BRIDGE_DEV_PMU_WRGA_EN (1ull << 24) +#define BRIDGE_DEV_DIR_WRGA_EN (1ull << 23) +#define BRIDGE_DEV_DEV_SIZE (1ull << 22) +#define BRIDGE_DEV_RT (1ull << 21) +#define BRIDGE_DEV_SWAP_PMU (1ull << 20) +#define BRIDGE_DEV_SWAP_DIR (1ull << 19) +#define BRIDGE_DEV_PREF (1ull << 18) +#define BRIDGE_DEV_PRECISE (1ull << 17) +#define BRIDGE_DEV_COH (1ull << 16) +#define BRIDGE_DEV_BARRIER (1ull << 15) +#define BRIDGE_DEV_GBR (1ull << 14) +#define BRIDGE_DEV_DEV_SWAP (1ull << 13) +#define BRIDGE_DEV_DEV_IO_MEM (1ull << 12) +#define BRIDGE_DEV_OFF_MASK 0x00000fff +#define BRIDGE_DEV_OFF_ADDR_SHFT 20 + +#define XBRIDGE_DEV_PMU_BITS BRIDGE_DEV_PMU_WRGA_EN +#define BRIDGE_DEV_PMU_BITS (BRIDGE_DEV_PMU_WRGA_EN | \ + BRIDGE_DEV_SWAP_PMU) +#define BRIDGE_DEV_D32_BITS (BRIDGE_DEV_DIR_WRGA_EN | \ + BRIDGE_DEV_SWAP_DIR | \ + BRIDGE_DEV_PREF | \ + BRIDGE_DEV_PRECISE | \ + BRIDGE_DEV_COH | \ + BRIDGE_DEV_BARRIER) +#define XBRIDGE_DEV_D64_BITS (BRIDGE_DEV_DIR_WRGA_EN | \ + BRIDGE_DEV_COH | \ + BRIDGE_DEV_BARRIER) +#define BRIDGE_DEV_D64_BITS (BRIDGE_DEV_DIR_WRGA_EN | \ + BRIDGE_DEV_SWAP_DIR | \ + BRIDGE_DEV_COH | \ + BRIDGE_DEV_BARRIER) + +/* Bridge Error Upper register bit field definition */ +#define BRIDGE_ERRUPPR_DEVMASTER (0x1 << 20) /* Device was master */ +#define BRIDGE_ERRUPPR_PCIVDEV (0x1 << 19) /* Virtual Req value */ +#define BRIDGE_ERRUPPR_DEVNUM_SHFT (16) +#define BRIDGE_ERRUPPR_DEVNUM_MASK (0x7 << BRIDGE_ERRUPPR_DEVNUM_SHFT) +#define BRIDGE_ERRUPPR_DEVICE(err) (((err) >> BRIDGE_ERRUPPR_DEVNUM_SHFT) & 0x7) +#define BRIDGE_ERRUPPR_ADDRMASK (0xFFFF) + +/* Bridge interrupt mode register bits definition */ +#define BRIDGE_INTMODE_CLR_PKT_EN(x) (0x1 << (x)) + +/* this should be written to the xbow's link_control(x) register */ +#define BRIDGE_CREDIT 3 + +/* RRB assignment register */ +#define BRIDGE_RRB_EN 0x8 /* after shifting down */ +#define BRIDGE_RRB_DEV 0x7 /* after shifting down */ +#define BRIDGE_RRB_VDEV 0x4 /* after shifting down */ +#define BRIDGE_RRB_PDEV 0x3 /* after shifting down */ + +/* RRB status register */ +#define BRIDGE_RRB_VALID(r) (0x00010000<<(r)) +#define BRIDGE_RRB_INUSE(r) (0x00000001<<(r)) + +/* RRB clear register */ +#define BRIDGE_RRB_CLEAR(r) (0x00000001<<(r)) + +/* xbox system controller declarations */ +#define XBOX_BRIDGE_WID 8 +#define FLASH_PROM1_BASE 0xE00000 /* To read the xbox sysctlr status */ +#define XBOX_RPS_EXISTS 1 << 6 /* RPS bit in status register */ +#define XBOX_RPS_FAIL 1 << 4 /* RPS status bit in register */ + +/* ======================================================================== + */ +/* + * Macros for Xtalk to Bridge bus (PCI/GIO) PIO + * refer to section 4.2.1 of Bridge Spec for xtalk to PCI/GIO PIO mappings + */ +/* XTALK addresses that map into Bridge Bus addr space */ +#define BRIDGE_PIO32_XTALK_ALIAS_BASE 0x000040000000L +#define BRIDGE_PIO32_XTALK_ALIAS_LIMIT 0x00007FFFFFFFL +#define BRIDGE_PIO64_XTALK_ALIAS_BASE 0x000080000000L +#define BRIDGE_PIO64_XTALK_ALIAS_LIMIT 0x0000BFFFFFFFL +#define BRIDGE_PCIIO_XTALK_ALIAS_BASE 0x000100000000L +#define BRIDGE_PCIIO_XTALK_ALIAS_LIMIT 0x0001FFFFFFFFL + +/* Ranges of PCI bus space that can be accessed via PIO from xtalk */ +#define BRIDGE_MIN_PIO_ADDR_MEM 0x00000000 /* 1G PCI memory space */ +#define BRIDGE_MAX_PIO_ADDR_MEM 0x3fffffff +#define BRIDGE_MIN_PIO_ADDR_IO 0x00000000 /* 4G PCI IO space */ +#define BRIDGE_MAX_PIO_ADDR_IO 0xffffffff + +/* XTALK addresses that map into PCI addresses */ +#define BRIDGE_PCI_MEM32_BASE BRIDGE_PIO32_XTALK_ALIAS_BASE +#define BRIDGE_PCI_MEM32_LIMIT BRIDGE_PIO32_XTALK_ALIAS_LIMIT +#define BRIDGE_PCI_MEM64_BASE BRIDGE_PIO64_XTALK_ALIAS_BASE +#define BRIDGE_PCI_MEM64_LIMIT BRIDGE_PIO64_XTALK_ALIAS_LIMIT +#define BRIDGE_PCI_IO_BASE BRIDGE_PCIIO_XTALK_ALIAS_BASE +#define BRIDGE_PCI_IO_LIMIT BRIDGE_PCIIO_XTALK_ALIAS_LIMIT + +/* + * Macros for Bridge bus (PCI/GIO) to Xtalk DMA + */ +/* Bridge Bus DMA addresses */ +#define BRIDGE_LOCAL_BASE 0 +#define BRIDGE_DMA_MAPPED_BASE 0x40000000 +#define BRIDGE_DMA_MAPPED_SIZE 0x40000000 /* 1G Bytes */ +#define BRIDGE_DMA_DIRECT_BASE 0x80000000 +#define BRIDGE_DMA_DIRECT_SIZE 0x80000000 /* 2G Bytes */ + +#define PCI32_LOCAL_BASE BRIDGE_LOCAL_BASE + +/* PCI addresses of regions decoded by Bridge for DMA */ +#define PCI32_MAPPED_BASE BRIDGE_DMA_MAPPED_BASE +#define PCI32_DIRECT_BASE BRIDGE_DMA_DIRECT_BASE + +#if LANGUAGE_C + +#define IS_PCI32_LOCAL(x) ((uint64_t)(x) < PCI32_MAPPED_BASE) +#define IS_PCI32_MAPPED(x) ((uint64_t)(x) < PCI32_DIRECT_BASE && \ + (uint64_t)(x) >= PCI32_MAPPED_BASE) +#define IS_PCI32_DIRECT(x) ((uint64_t)(x) >= PCI32_MAPPED_BASE) +#define IS_PCI64(x) ((uint64_t)(x) >= PCI64_BASE) +#endif /* LANGUAGE_C */ + +/* + * The GIO address space. + */ +/* Xtalk to GIO PIO */ +#define BRIDGE_GIO_MEM32_BASE BRIDGE_PIO32_XTALK_ALIAS_BASE +#define BRIDGE_GIO_MEM32_LIMIT BRIDGE_PIO32_XTALK_ALIAS_LIMIT + +#define GIO_LOCAL_BASE BRIDGE_LOCAL_BASE + +/* GIO addresses of regions decoded by Bridge for DMA */ +#define GIO_MAPPED_BASE BRIDGE_DMA_MAPPED_BASE +#define GIO_DIRECT_BASE BRIDGE_DMA_DIRECT_BASE + +#if LANGUAGE_C + +#define IS_GIO_LOCAL(x) ((uint64_t)(x) < GIO_MAPPED_BASE) +#define IS_GIO_MAPPED(x) ((uint64_t)(x) < GIO_DIRECT_BASE && \ + (uint64_t)(x) >= GIO_MAPPED_BASE) +#define IS_GIO_DIRECT(x) ((uint64_t)(x) >= GIO_MAPPED_BASE) +#endif /* LANGUAGE_C */ + +/* PCI to xtalk mapping */ + +/* given a DIR_OFF value and a pci/gio 32 bits direct address, determine + * which xtalk address is accessed + */ +#define BRIDGE_DIRECT_32_SEG_SIZE BRIDGE_DMA_DIRECT_SIZE +#define BRIDGE_DIRECT_32_TO_XTALK(dir_off,adr) \ + ((dir_off) * BRIDGE_DIRECT_32_SEG_SIZE + \ + ((adr) & (BRIDGE_DIRECT_32_SEG_SIZE - 1)) + PHYS_RAMBASE) + +/* 64-bit address attribute masks */ +#define PCI64_ATTR_TARG_MASK 0xf000000000000000 +#define PCI64_ATTR_TARG_SHFT 60 +#define PCI64_ATTR_PREF (1ull << 59) +#define PCI64_ATTR_PREC (1ull << 58) +#define PCI64_ATTR_VIRTUAL (1ull << 57) +#define PCI64_ATTR_BAR (1ull << 56) +#define PCI64_ATTR_SWAP (1ull << 55) +#define PCI64_ATTR_RMF_MASK 0x00ff000000000000 +#define PCI64_ATTR_RMF_SHFT 48 + +#if LANGUAGE_C +/* Address translation entry for mapped pci32 accesses */ +typedef union ate_u { + uint64_t ent; + struct xb_ate_s { /* xbridge */ + uint64_t :16; + uint64_t addr:36; + uint64_t targ:4; + uint64_t reserved:2; + uint64_t swap:1; + uint64_t barrier:1; + uint64_t prefetch:1; + uint64_t precise:1; + uint64_t coherent:1; + uint64_t valid:1; + } xb_field; + struct ate_s { /* bridge */ + uint64_t rmf:16; + uint64_t addr:36; + uint64_t targ:4; + uint64_t reserved:3; + uint64_t barrier:1; + uint64_t prefetch:1; + uint64_t precise:1; + uint64_t coherent:1; + uint64_t valid:1; + } field; +} ate_t; +#endif /* LANGUAGE_C */ + +#define ATE_V (1 << 0) +#define ATE_CO (1 << 1) +#define ATE_PREC (1 << 2) +#define ATE_PREF (1 << 3) +#define ATE_BAR (1 << 4) +#define ATE_SWAP (1 << 5) + +#define ATE_PFNSHIFT 12 +#define ATE_TIDSHIFT 8 +#define ATE_RMFSHIFT 48 + +#define mkate(xaddr, xid, attr) ((xaddr) & 0x0000fffffffff000ULL) | \ + ((xid)<b_wid_id) == XBRIDGE_WIDGET_PART_NUM) + +#if LANGUAGE_C + +/* ======================================================================== + */ + +#ifdef MACROFIELD_LINE +/* + * This table forms a relation between the byte offset macros normally + * used for ASM coding and the calculated byte offsets of the fields + * in the C structure. + * + * See bridge_check.c and bridge_html.c for further details. + */ +#ifndef MACROFIELD_LINE_BITFIELD +#define MACROFIELD_LINE_BITFIELD(m) /* ignored */ +#endif + +struct macrofield_s bridge_macrofield[] = +{ + + MACROFIELD_LINE(BRIDGE_WID_ID, b_wid_id) + MACROFIELD_LINE_BITFIELD(WIDGET_REV_NUM) + MACROFIELD_LINE_BITFIELD(WIDGET_PART_NUM) + MACROFIELD_LINE_BITFIELD(WIDGET_MFG_NUM) + MACROFIELD_LINE(BRIDGE_WID_STAT, b_wid_stat) + MACROFIELD_LINE_BITFIELD(BRIDGE_STAT_LLP_REC_CNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_STAT_LLP_TX_CNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_STAT_FLASH_SELECT) + MACROFIELD_LINE_BITFIELD(BRIDGE_STAT_PCI_GIO_N) + MACROFIELD_LINE_BITFIELD(BRIDGE_STAT_PENDING) + MACROFIELD_LINE(BRIDGE_WID_ERR_UPPER, b_wid_err_upper) + MACROFIELD_LINE(BRIDGE_WID_ERR_LOWER, b_wid_err_lower) + MACROFIELD_LINE(BRIDGE_WID_CONTROL, b_wid_control) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_FLASH_WR_EN) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_EN_CLK50) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_EN_CLK40) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_EN_CLK33) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_RST_MASK) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_IO_SWAP) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_MEM_SWAP) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_PAGE_SIZE) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_SS_PAR_BAD) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_SS_PAR_EN) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_SSRAM_SIZE_MASK) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_F_BAD_PKT) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_LLP_XBAR_CRD_MASK) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_CLR_RLLP_CNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_CLR_TLLP_CNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_SYS_END) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_MAX_TRANS_MASK) + MACROFIELD_LINE_BITFIELD(BRIDGE_CTRL_WIDGET_ID_MASK) + MACROFIELD_LINE(BRIDGE_WID_REQ_TIMEOUT, b_wid_req_timeout) + MACROFIELD_LINE(BRIDGE_WID_INT_UPPER, b_wid_int_upper) + MACROFIELD_LINE_BITFIELD(WIDGET_INT_VECTOR) + MACROFIELD_LINE_BITFIELD(WIDGET_TARGET_ID) + MACROFIELD_LINE_BITFIELD(WIDGET_UPP_ADDR) + MACROFIELD_LINE(BRIDGE_WID_INT_LOWER, b_wid_int_lower) + MACROFIELD_LINE(BRIDGE_WID_ERR_CMDWORD, b_wid_err_cmdword) + MACROFIELD_LINE_BITFIELD(WIDGET_DIDN) + MACROFIELD_LINE_BITFIELD(WIDGET_SIDN) + MACROFIELD_LINE_BITFIELD(WIDGET_PACTYP) + MACROFIELD_LINE_BITFIELD(WIDGET_TNUM) + MACROFIELD_LINE_BITFIELD(WIDGET_COHERENT) + MACROFIELD_LINE_BITFIELD(WIDGET_DS) + MACROFIELD_LINE_BITFIELD(WIDGET_GBR) + MACROFIELD_LINE_BITFIELD(WIDGET_VBPM) + MACROFIELD_LINE_BITFIELD(WIDGET_ERROR) + MACROFIELD_LINE_BITFIELD(WIDGET_BARRIER) + MACROFIELD_LINE(BRIDGE_WID_LLP, b_wid_llp) + MACROFIELD_LINE_BITFIELD(WIDGET_LLP_MAXRETRY) + MACROFIELD_LINE_BITFIELD(WIDGET_LLP_NULLTIMEOUT) + MACROFIELD_LINE_BITFIELD(WIDGET_LLP_MAXBURST) + MACROFIELD_LINE(BRIDGE_WID_TFLUSH, b_wid_tflush) + MACROFIELD_LINE(BRIDGE_WID_AUX_ERR, b_wid_aux_err) + MACROFIELD_LINE(BRIDGE_WID_RESP_UPPER, b_wid_resp_upper) + MACROFIELD_LINE(BRIDGE_WID_RESP_LOWER, b_wid_resp_lower) + MACROFIELD_LINE(BRIDGE_WID_TST_PIN_CTRL, b_wid_tst_pin_ctrl) + MACROFIELD_LINE(BRIDGE_DIR_MAP, b_dir_map) + MACROFIELD_LINE_BITFIELD(BRIDGE_DIRMAP_W_ID) + MACROFIELD_LINE_BITFIELD(BRIDGE_DIRMAP_RMF_64) + MACROFIELD_LINE_BITFIELD(BRIDGE_DIRMAP_ADD512) + MACROFIELD_LINE_BITFIELD(BRIDGE_DIRMAP_OFF) + MACROFIELD_LINE(BRIDGE_RAM_PERR, b_ram_perr) + MACROFIELD_LINE(BRIDGE_ARB, b_arb) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_REQ_WAIT_TICK_MASK) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_REQ_WAIT_EN_MASK) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_FREEZE_GNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_HPRI_RING_B2) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_HPRI_RING_B1) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_HPRI_RING_B0) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_LPRI_RING_B2) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_LPRI_RING_B1) + MACROFIELD_LINE_BITFIELD(BRIDGE_ARB_LPRI_RING_B0) + MACROFIELD_LINE(BRIDGE_NIC, b_nic) + MACROFIELD_LINE(BRIDGE_PCI_BUS_TIMEOUT, b_pci_bus_timeout) + MACROFIELD_LINE(BRIDGE_PCI_CFG, b_pci_cfg) + MACROFIELD_LINE(BRIDGE_PCI_ERR_UPPER, b_pci_err_upper) + MACROFIELD_LINE(BRIDGE_PCI_ERR_LOWER, b_pci_err_lower) + MACROFIELD_LINE(BRIDGE_INT_STATUS, b_int_status) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_MULTI_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PMU_ESIZE_FAULT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_UNEXP_RESP) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_BAD_XRESP_PKT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_BAD_XREQ_PKT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_RESP_XTLK_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_REQ_XTLK_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_INVLD_ADDR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_UNSUPPORTED_XOP) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_XREQ_FIFO_OFLOW) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_LLP_REC_SNERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_LLP_REC_CBERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_LLP_RCTY) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_LLP_TX_RETRY) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_LLP_TCTY) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_SSRAM_PERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PCI_ABORT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PCI_PARITY) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PCI_SERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PCI_PERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PCI_MST_TIMEOUT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_PCI_RETRY_CNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_XREAD_REQ_TIMEOUT) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_GIO_B_ENBL_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_ISR_INT_MSK) + MACROFIELD_LINE(BRIDGE_INT_ENABLE, b_int_enable) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_UNEXP_RESP) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PMU_ESIZE_FAULT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_BAD_XRESP_PKT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_BAD_XREQ_PKT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_RESP_XTLK_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_REQ_XTLK_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_INVLD_ADDR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_UNSUPPORTED_XOP) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_XREQ_FIFO_OFLOW) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_LLP_REC_SNERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_LLP_REC_CBERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_LLP_RCTY) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_LLP_TX_RETRY) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_LLP_TCTY) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_SSRAM_PERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PCI_ABORT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PCI_PARITY) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PCI_SERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PCI_PERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PCI_MST_TIMEOUT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_PCI_RETRY_CNT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_XREAD_REQ_TIMEOUT) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_GIO_B_ENBL_ERR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IMR_INT_MSK) + MACROFIELD_LINE(BRIDGE_INT_RST_STAT, b_int_rst_stat) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_ALL_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_MULTI_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_CRP_GRP_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_RESP_BUF_GRP_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_REQ_DSP_GRP_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_LLP_GRP_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_SSRAM_GRP_CLR) + MACROFIELD_LINE_BITFIELD(BRIDGE_IRR_PCI_GRP_CLR) + MACROFIELD_LINE(BRIDGE_INT_MODE, b_int_mode) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(7)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(6)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(5)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(4)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(3)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(2)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(1)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INTMODE_CLR_PKT_EN(0)) + MACROFIELD_LINE(BRIDGE_INT_DEVICE, b_int_device) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(7)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(6)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(5)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(4)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(3)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(2)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(1)) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_DEV_MASK(0)) + MACROFIELD_LINE(BRIDGE_INT_HOST_ERR, b_int_host_err) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_ADDR_HOST) + MACROFIELD_LINE_BITFIELD(BRIDGE_INT_ADDR_FLD) + MACROFIELD_LINE(BRIDGE_INT_ADDR0, b_int_addr[0].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(0), b_int_addr[0].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(1), b_int_addr[1].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(2), b_int_addr[2].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(3), b_int_addr[3].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(4), b_int_addr[4].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(5), b_int_addr[5].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(6), b_int_addr[6].addr) + MACROFIELD_LINE(BRIDGE_INT_ADDR(7), b_int_addr[7].addr) + MACROFIELD_LINE(BRIDGE_DEVICE0, b_device[0].reg) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_ERR_LOCK_EN) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_PAGE_CHK_DIS) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_FORCE_PCI_PAR) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_VIRTUAL_EN) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_PMU_WRGA_EN) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_DIR_WRGA_EN) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_DEV_SIZE) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_RT) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_SWAP_PMU) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_SWAP_DIR) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_PREF) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_PRECISE) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_COH) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_BARRIER) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_GBR) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_DEV_SWAP) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_DEV_IO_MEM) + MACROFIELD_LINE_BITFIELD(BRIDGE_DEV_OFF_MASK) + MACROFIELD_LINE(BRIDGE_DEVICE(0), b_device[0].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(1), b_device[1].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(2), b_device[2].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(3), b_device[3].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(4), b_device[4].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(5), b_device[5].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(6), b_device[6].reg) + MACROFIELD_LINE(BRIDGE_DEVICE(7), b_device[7].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF0, b_wr_req_buf[0].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(0), b_wr_req_buf[0].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(1), b_wr_req_buf[1].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(2), b_wr_req_buf[2].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(3), b_wr_req_buf[3].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(4), b_wr_req_buf[4].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(5), b_wr_req_buf[5].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(6), b_wr_req_buf[6].reg) + MACROFIELD_LINE(BRIDGE_WR_REQ_BUF(7), b_wr_req_buf[7].reg) + MACROFIELD_LINE(BRIDGE_EVEN_RESP, b_even_resp) + MACROFIELD_LINE(BRIDGE_ODD_RESP, b_odd_resp) + MACROFIELD_LINE(BRIDGE_RESP_STATUS, b_resp_status) + MACROFIELD_LINE(BRIDGE_RESP_CLEAR, b_resp_clear) + MACROFIELD_LINE(BRIDGE_ATE_RAM, b_int_ate_ram) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV0, b_type0_cfg_dev[0]) + + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(0), b_type0_cfg_dev[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,0), b_type0_cfg_dev[0].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,1), b_type0_cfg_dev[0].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,2), b_type0_cfg_dev[0].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,3), b_type0_cfg_dev[0].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,4), b_type0_cfg_dev[0].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,5), b_type0_cfg_dev[0].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,6), b_type0_cfg_dev[0].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(0,7), b_type0_cfg_dev[0].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(1), b_type0_cfg_dev[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,0), b_type0_cfg_dev[1].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,1), b_type0_cfg_dev[1].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,2), b_type0_cfg_dev[1].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,3), b_type0_cfg_dev[1].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,4), b_type0_cfg_dev[1].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,5), b_type0_cfg_dev[1].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,6), b_type0_cfg_dev[1].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(1,7), b_type0_cfg_dev[1].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(2), b_type0_cfg_dev[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,0), b_type0_cfg_dev[2].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,1), b_type0_cfg_dev[2].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,2), b_type0_cfg_dev[2].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,3), b_type0_cfg_dev[2].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,4), b_type0_cfg_dev[2].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,5), b_type0_cfg_dev[2].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,6), b_type0_cfg_dev[2].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(2,7), b_type0_cfg_dev[2].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(3), b_type0_cfg_dev[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,0), b_type0_cfg_dev[3].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,1), b_type0_cfg_dev[3].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,2), b_type0_cfg_dev[3].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,3), b_type0_cfg_dev[3].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,4), b_type0_cfg_dev[3].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,5), b_type0_cfg_dev[3].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,6), b_type0_cfg_dev[3].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(3,7), b_type0_cfg_dev[3].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(4), b_type0_cfg_dev[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,0), b_type0_cfg_dev[4].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,1), b_type0_cfg_dev[4].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,2), b_type0_cfg_dev[4].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,3), b_type0_cfg_dev[4].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,4), b_type0_cfg_dev[4].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,5), b_type0_cfg_dev[4].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,6), b_type0_cfg_dev[4].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(4,7), b_type0_cfg_dev[4].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(5), b_type0_cfg_dev[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,0), b_type0_cfg_dev[5].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,1), b_type0_cfg_dev[5].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,2), b_type0_cfg_dev[5].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,3), b_type0_cfg_dev[5].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,4), b_type0_cfg_dev[5].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,5), b_type0_cfg_dev[5].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,6), b_type0_cfg_dev[5].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(5,7), b_type0_cfg_dev[5].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(6), b_type0_cfg_dev[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,0), b_type0_cfg_dev[6].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,1), b_type0_cfg_dev[6].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,2), b_type0_cfg_dev[6].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,3), b_type0_cfg_dev[6].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,4), b_type0_cfg_dev[6].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,5), b_type0_cfg_dev[6].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,6), b_type0_cfg_dev[6].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(6,7), b_type0_cfg_dev[6].f[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEV(7), b_type0_cfg_dev[7]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,0), b_type0_cfg_dev[7].f[0]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,1), b_type0_cfg_dev[7].f[1]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,2), b_type0_cfg_dev[7].f[2]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,3), b_type0_cfg_dev[7].f[3]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,4), b_type0_cfg_dev[7].f[4]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,5), b_type0_cfg_dev[7].f[5]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,6), b_type0_cfg_dev[7].f[6]) + MACROFIELD_LINE(BRIDGE_TYPE0_CFG_DEVF(7,7), b_type0_cfg_dev[7].f[7]) + + MACROFIELD_LINE(BRIDGE_TYPE1_CFG, b_type1_cfg) + MACROFIELD_LINE(BRIDGE_PCI_IACK, b_pci_iack) + MACROFIELD_LINE(BRIDGE_EXT_SSRAM, b_ext_ate_ram) + MACROFIELD_LINE(BRIDGE_DEVIO0, b_devio(0)) + MACROFIELD_LINE(BRIDGE_DEVIO(0), b_devio(0)) + MACROFIELD_LINE(BRIDGE_DEVIO(1), b_devio(1)) + MACROFIELD_LINE(BRIDGE_DEVIO(2), b_devio(2)) + MACROFIELD_LINE(BRIDGE_DEVIO(3), b_devio(3)) + MACROFIELD_LINE(BRIDGE_DEVIO(4), b_devio(4)) + MACROFIELD_LINE(BRIDGE_DEVIO(5), b_devio(5)) + MACROFIELD_LINE(BRIDGE_DEVIO(6), b_devio(6)) + MACROFIELD_LINE(BRIDGE_DEVIO(7), b_devio(7)) + MACROFIELD_LINE(BRIDGE_EXTERNAL_FLASH, b_external_flash) +}; +#endif + +#ifdef __cplusplus +}; +#endif +#endif /* C or C++ */ + +#endif /* _ASM_SN_PCI_BRIDGE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/pci_bus_cvlink.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pci_bus_cvlink.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/pci_bus_cvlink.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pci_bus_cvlink.h Wed Dec 13 18:59:33 2000 @@ -0,0 +1,29 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_CVLINK_H +#define _ASM_SN_PCI_CVLINK_H + +#define SET_PCIA64(dev) \ + (((struct sn1_device_sysdata *)((dev)->sysdata))->isa64) = 1 +#define IS_PCIA64(dev) (((dev)->dma_mask == 0xffffffffffffffffUL) || \ + (((struct sn1_device_sysdata *)((dev)->sysdata))->isa64)) +#define IS_PCI32G(dev) ((dev)->dma_mask >= 0xffffffff) +#define IS_PCI32L(dev) ((dev)->dma_mask < 0xffffffff) + +struct sn1_widget_sysdata { + devfs_handle_t vhdl; +}; + +struct sn1_device_sysdata { + devfs_handle_t vhdl; + int isa64; +}; + +#endif /* _ASM_SN_PCI_CVLINK_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/pci_defs.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pci_defs.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/pci_defs.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pci_defs.h Wed Dec 6 21:56:10 2000 @@ -0,0 +1,242 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_PCI_DEFS_H +#define _ASM_SN_PCI_PCI_DEFS_H + +/* defines for the PCI bus architecture */ + +/* Bit layout of address fields for Type-1 + * Configuration Space cycles. + */ +#define PCI_TYPE0_SLOT_MASK 0xFFFFF800 +#define PCI_TYPE0_FUNC_MASK 0x00000700 +#define PCI_TYPE0_REG_MASK 0x000000FF + +#define PCI_TYPE0_SLOT_SHFT 11 +#define PCI_TYPE0_FUNC_SHFT 8 +#define PCI_TYPE0_REG_SHFT 0 + +#define PCI_TYPE0_FUNC(a) (((a) & PCI_TYPE0_FUNC_MASK) >> PCI_TYPE0_FUNC_SHFT) +#define PCI_TYPE0_REG(a) (((a) & PCI_TYPE0_REG_MASK) >> PCI_TYPE0_REG_SHFT) + +#define PCI_TYPE0(s,f,r) ((((1<<(s)) << PCI_TYPE0_SLOT_SHFT) & PCI_TYPE0_SLOT_MASK) |\ + (((f) << PCI_TYPE0_FUNC_SHFT) & PCI_TYPE0_FUNC_MASK) |\ + (((r) << PCI_TYPE0_REG_SHFT) & PCI_TYPE0_REG_MASK)) + +/* Bit layout of address fields for Type-1 + * Configuration Space cycles. + * NOTE: I'm including the byte offset within + * the 32-bit word as part of the register + * number as an extension of the layout in + * the PCI spec. + */ +#define PCI_TYPE1_BUS_MASK 0x00FF0000 +#define PCI_TYPE1_SLOT_MASK 0x0000F100 +#define PCI_TYPE1_FUNC_MASK 0x00000700 +#define PCI_TYPE1_REG_MASK 0x000000FF + +#define PCI_TYPE1_BUS_SHFT 16 +#define PCI_TYPE1_SLOT_SHFT 11 +#define PCI_TYPE1_FUNC_SHFT 8 +#define PCI_TYPE1_REG_SHFT 0 + +#define PCI_TYPE1_BUS(a) (((a) & PCI_TYPE1_BUS_MASK) >> PCI_TYPE1_BUS_SHFT) +#define PCI_TYPE1_SLOT(a) (((a) & PCI_TYPE1_SLOT_MASK) >> PCI_TYPE1_SLOT_SHFT) +#define PCI_TYPE1_FUNC(a) (((a) & PCI_TYPE1_FUNC_MASK) >> PCI_TYPE1_FUNC_SHFT) +#define PCI_TYPE1_REG(a) (((a) & PCI_TYPE1_REG_MASK) >> PCI_TYPE1_REG_SHFT) + +#define PCI_TYPE1(b,s,f,r) ((((b) << PCI_TYPE1_BUS_SHFT) & PCI_TYPE1_BUS_MASK) |\ + (((s) << PCI_TYPE1_SLOT_SHFT) & PCI_TYPE1_SLOT_MASK) |\ + (((f) << PCI_TYPE1_FUNC_SHFT) & PCI_TYPE1_FUNC_MASK) |\ + (((r) << PCI_TYPE1_REG_SHFT) & PCI_TYPE1_REG_MASK)) + +/* Byte offsets of registers in CFG space + */ +#define PCI_CFG_VENDOR_ID 0x00 /* Vendor ID (2 bytes) */ +#define PCI_CFG_DEVICE_ID 0x02 /* Device ID (2 bytes) */ + +#define PCI_CFG_COMMAND 0x04 /* Command (2 bytes) */ +#define PCI_CFG_STATUS 0x06 /* Status (2 bytes) */ + +/* NOTE: if you are using a C "switch" statement to + * differentiate between the Config space registers, be + * aware that PCI_CFG_CLASS_CODE and PCI_CFG_BASE_CLASS + * are the same offset. + */ +#define PCI_CFG_REV_ID 0x08 /* Revision Id (1 byte) */ +#define PCI_CFG_CLASS_CODE 0x09 /* Class Code (3 bytes) */ +#define PCI_CFG_BASE_CLASS 0x09 /* Base Class (1 byte) */ +#define PCI_CFG_SUB_CLASS 0x0A /* Sub Class (1 byte) */ +#define PCI_CFG_PROG_IF 0x0B /* Prog Interface (1 byte) */ + +#define PCI_CFG_CACHE_LINE 0x0C /* Cache line size (1 byte) */ +#define PCI_CFG_LATENCY_TIMER 0x0D /* Latency Timer (1 byte) */ +#define PCI_CFG_HEADER_TYPE 0x0E /* Header Type (1 byte) */ +#define PCI_CFG_BIST 0x0F /* Built In Self Test */ + +#define PCI_CFG_BASE_ADDR_0 0x10 /* Base Address (4 bytes) */ +#define PCI_CFG_BASE_ADDR_1 0x14 /* Base Address (4 bytes) */ +#define PCI_CFG_BASE_ADDR_2 0x18 /* Base Address (4 bytes) */ +#define PCI_CFG_BASE_ADDR_3 0x1C /* Base Address (4 bytes) */ +#define PCI_CFG_BASE_ADDR_4 0x20 /* Base Address (4 bytes) */ +#define PCI_CFG_BASE_ADDR_5 0x24 /* Base Address (4 bytes) */ + +#define PCI_CFG_BASE_ADDR_OFF 0x04 /* Base Address Offset (1..5)*/ +#define PCI_CFG_BASE_ADDR(n) (PCI_CFG_BASE_ADDR_0 + (n)*PCI_CFG_BASE_ADDR_OFF) +#define PCI_CFG_BASE_ADDRS 6 /* up to this many BASE regs */ + +#define PCI_CFG_CARDBUS_CIS 0x28 /* Cardbus CIS Pointer (4B) */ + +#define PCI_CFG_SUBSYS_VEND_ID 0x2C /* Subsystem Vendor ID (2B) */ +#define PCI_CFG_SUBSYS_ID 0x2E /* Subsystem ID */ + +#define PCI_EXPANSION_ROM 0x30 /* Expansion Rom Base (4B) */ + +#define PCI_INTR_LINE 0x3C /* Interrupt Line (1B) */ +#define PCI_INTR_PIN 0x3D /* Interrupt Pin (1B) */ +#define PCI_MIN_GNT 0x3E /* Minimum Grant (1B) */ +#define PCI_MAX_LAT 0x3F /* Maximum Latency (1B) */ + +#define PCI_CFG_VEND_SPECIFIC 0x40 /* first vendor specific reg */ + +/* layout for Type 0x01 headers */ + +#define PCI_CFG_PPB_BUS_PRI 0x18 /* immediate upstream bus # */ +#define PCI_CFG_PPB_BUS_SEC 0x19 /* immediate downstream bus # */ +#define PCI_CFG_PPB_BUS_SUB 0x1A /* last downstream bus # */ +#define PCI_CFG_PPB_SEC_LAT 0x1B /* latency timer for SEC bus */ +#define PCI_CFG_PPB_IOBASE 0x1C /* IO Base Addr bits 12..15 */ +#define PCI_CFG_PPB_IOLIM 0x1D /* IO Limit Addr bits 12..15 */ +#define PCI_CFG_PPB_SEC_STAT 0x1E /* Secondary Status */ +#define PCI_CFG_PPB_MEMBASE 0x20 /* MEM Base Addr bits 16..31 */ +#define PCI_CFG_PPB_MEMLIM 0x22 /* MEM Limit Addr bits 16..31 */ +#define PCI_CFG_PPB_MEMPFBASE 0x24 /* PfMEM Base Addr bits 16..31 */ +#define PCI_CFG_PPB_MEMPFLIM 0x26 /* PfMEM Limit Addr bits 16..31 */ +#define PCI_CFG_PPB_MEMPFBASEHI 0x28 /* PfMEM Base Addr bits 32..63 */ +#define PCI_CFG_PPB_MEMPFLIMHI 0x2C /* PfMEM Limit Addr bits 32..63 */ +#define PCI_CFG_PPB_IOBASEHI 0x30 /* IO Base Addr bits 16..31 */ +#define PCI_CFG_PPB_IOLIMHI 0x32 /* IO Limit Addr bits 16..31 */ +#define PCI_CFG_PPB_SUB_VENDOR 0x34 /* Subsystem Vendor ID */ +#define PCI_CFG_PPB_SUB_DEVICE 0x36 /* Subsystem Device ID */ +#define PCI_CFG_PPB_INT_PIN 0x3D /* Interrupt Pin */ +#define PCI_CFG_PPB_BRIDGE_CTRL 0x3E /* Bridge Control */ + /* XXX- these might be DEC 21152 specific */ +#define PCI_CFG_PPB_CHIP_CTRL 0x40 +#define PCI_CFG_PPB_DIAG_CTRL 0x41 +#define PCI_CFG_PPB_ARB_CTRL 0x42 +#define PCI_CFG_PPB_SERR_DISABLE 0x64 +#define PCI_CFG_PPB_CLK2_CTRL 0x68 +#define PCI_CFG_PPB_SERR_STATUS 0x6A + +/* Command Register layout (0x04) */ +#define PCI_CMD_IO_SPACE 0x001 /* I/O Space device */ +#define PCI_CMD_MEM_SPACE 0x002 /* Memory Space */ +#define PCI_CMD_BUS_MASTER 0x004 /* Bus Master */ +#define PCI_CMD_SPEC_CYCLES 0x008 /* Special Cycles */ +#define PCI_CMD_MEMW_INV_ENAB 0x010 /* Memory Write Inv Enable */ +#define PCI_CMD_VGA_PALETTE_SNP 0x020 /* VGA Palette Snoop */ +#define PCI_CMD_PAR_ERR_RESP 0x040 /* Parity Error Response */ +#define PCI_CMD_WAIT_CYCLE_CTL 0x080 /* Wait Cycle Control */ +#define PCI_CMD_SERR_ENABLE 0x100 /* SERR# Enable */ +#define PCI_CMD_F_BK_BK_ENABLE 0x200 /* Fast Back-to-Back Enable */ + +/* Status Register Layout (0x06) */ +#define PCI_STAT_PAR_ERR_DET 0x8000 /* Detected Parity Error */ +#define PCI_STAT_SYS_ERR 0x4000 /* Signaled System Error */ +#define PCI_STAT_RCVD_MSTR_ABT 0x2000 /* Received Master Abort */ +#define PCI_STAT_RCVD_TGT_ABT 0x1000 /* Received Target Abort */ +#define PCI_STAT_SGNL_TGT_ABT 0x0800 /* Signaled Target Abort */ + +#define PCI_STAT_DEVSEL_TIMING 0x0600 /* DEVSEL Timing Mask */ +#define DEVSEL_TIMING(_x) (((_x) >> 9) & 3) /* devsel tim macro */ +#define DEVSEL_FAST 0 /* Fast timing */ +#define DEVSEL_MEDIUM 1 /* Medium timing */ +#define DEVSEL_SLOW 2 /* Slow timing */ + +#define PCI_STAT_DATA_PAR_ERR 0x0100 /* Data Parity Err Detected */ +#define PCI_STAT_F_BK_BK_CAP 0x0080 /* Fast Back-to-Back Capable */ +#define PCI_STAT_UDF_SUPP 0x0040 /* UDF Supported */ +#define PCI_STAT_66MHZ_CAP 0x0020 /* 66 MHz Capable */ + +/* BIST Register Layout (0x0F) */ +#define PCI_BIST_BIST_CAP 0x80 /* BIST Capable */ +#define PCI_BIST_START_BIST 0x40 /* Start BIST */ +#define PCI_BIST_CMPLTION_MASK 0x0F /* COMPLETION MASK */ +#define PCI_BIST_CMPL_OK 0x00 /* 0 value is completion OK */ + +/* Base Address Register 0x10 */ +#define PCI_BA_IO_SPACE 0x1 /* I/O Space Marker */ +#define PCI_BA_MEM_LOCATION 0x6 /* 2 bits for location avail */ +#define PCI_BA_MEM_32BIT 0x0 /* Anywhere in 32bit space */ +#define PCI_BA_MEM_1MEG 0x2 /* Locate below 1 Meg */ +#define PCI_BA_MEM_64BIT 0x4 /* Anywhere in 64bit space */ +#define PCI_BA_PREFETCH 0x8 /* Prefetchable, no side effect */ + +/* PIO interface macros */ + +#ifndef IOC3_EMULATION + +#define PCI_INB(x) (*((volatile char*)x)) +#define PCI_INH(x) (*((volatile short*)x)) +#define PCI_INW(x) (*((volatile int*)x)) +#define PCI_OUTB(x,y) (*((volatile char*)x) = y) +#define PCI_OUTH(x,y) (*((volatile short*)x) = y) +#define PCI_OUTW(x,y) (*((volatile int*)x) = y) + +#else + +extern uint pci_read(void * address, int type); +extern void pci_write(void * address, int data, int type); + +#define BYTE 1 +#define HALF 2 +#define WORD 4 + +#define PCI_INB(x) pci_read((void *)(x),BYTE) +#define PCI_INH(x) pci_read((void *)(x),HALF) +#define PCI_INW(x) pci_read((void *)(x),WORD) +#define PCI_OUTB(x,y) pci_write((void *)(x),(y),BYTE) +#define PCI_OUTH(x,y) pci_write((void *)(x),(y),HALF) +#define PCI_OUTW(x,y) pci_write((void *)(x),(y),WORD) + +#endif /* !IOC3_EMULATION */ + /* effects on reads, merges */ + +#ifdef CONFIG_SGI_IP22 +#define BYTECOUNT_W_GIO 0xbf400000 +#endif + +/* + * Definition of address layouts for PCI Config mechanism #1 + * XXX- These largely duplicate PCI_TYPE1 constants at the top + * of the file; the two groups should probably be combined. + */ + +#define CFG1_ADDR_REGISTER_MASK 0x000000fc +#define CFG1_ADDR_FUNCTION_MASK 0x00000700 +#define CFG1_ADDR_DEVICE_MASK 0x0000f800 +#define CFG1_ADDR_BUS_MASK 0x00ff0000 + +#define CFG1_REGISTER_SHIFT 2 +#define CFG1_FUNCTION_SHIFT 8 +#define CFG1_DEVICE_SHIFT 11 +#define CFG1_BUS_SHIFT 16 + +#ifdef CONFIG_SGI_IP32 + /* Definitions related to IP32 PCI Bridge policy + * XXX- should probaly be moved to a mace-specific header + */ +#define PCI_CONFIG_BITS 0xfe0085ff +#define PCI_CONTROL_MRMRA_ENABLE 0x00000800 +#define PCI_FIRST_IO_ADDR 0x1000 +#define PCI_IO_MAP_INCR 0x1000 +#endif /* CONFIG_SGI_IP32 */ + +#endif /* _ASM_SN_PCI_PCI_DEFS_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/pcibr.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pcibr.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/pcibr.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pcibr.h Wed Dec 13 23:58:18 2000 @@ -0,0 +1,360 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_PCIBR_H +#define _ASM_SN_PCI_PCIBR_H + +#if defined(__KERNEL__) + +#include +#include +#include + +#include +#include + +/* ===================================================================== + * symbolic constants used by pcibr's xtalk bus provider + */ + +#define PCIBR_PIOMAP_BUSY 0x80000000 + +#define PCIBR_DMAMAP_BUSY 0x80000000 +#define PCIBR_DMAMAP_SSRAM 0x40000000 + +#define PCIBR_INTR_BLOCKED 0x40000000 +#define PCIBR_INTR_BUSY 0x80000000 + +#if LANGUAGE_C + +/* ===================================================================== + * opaque types used by pcibr's xtalk bus provider + */ + +typedef struct pcibr_piomap_s *pcibr_piomap_t; +typedef struct pcibr_dmamap_s *pcibr_dmamap_t; +typedef struct pcibr_intr_s *pcibr_intr_t; + +/* ===================================================================== + * primary entry points: Bridge (pcibr) device driver + * + * These functions are normal device driver entry points + * and are called along with the similar entry points from + * other device drivers. They are included here as documentation + * of their existance and purpose. + * + * pcibr_init() is called to inform us that there is a pcibr driver + * configured into the kernel; it is responsible for registering + * as a crosstalk widget and providing a routine to be called + * when a widget with the proper part number is observed. + * + * pcibr_attach() is called for each vertex in the hardware graph + * corresponding to a crosstalk widget with the manufacturer + * code and part number registered by pcibr_init(). + */ + +extern void pcibr_init(void); + +extern int pcibr_attach(devfs_handle_t); + +/* ===================================================================== + * bus provider function table + * + * Normally, this table is only handed off explicitly + * during provider initialization, and the PCI generic + * layer will stash a pointer to it in the vertex; however, + * exporting it explicitly enables a performance hack in + * the generic PCI provider where if we know at compile + * time that the only possible PCI provider is a + * pcibr, we can go directly to this ops table. + */ + +extern pciio_provider_t pcibr_provider; + +/* ===================================================================== + * secondary entry points: pcibr PCI bus provider + * + * These functions are normally exported explicitly by + * a direct call from the pcibr initialization routine + * into the generic crosstalk provider; they are included + * here to enable a more aggressive performance hack in + * the generic crosstalk layer, where if we know that the + * only possible crosstalk provider is pcibr, and we can + * guarantee that all entry points are properly named, and + * we can deal with the implicit casting properly, then + * we can turn many of the generic provider routines into + * plain brances, or even eliminate them (given sufficient + * smarts on the part of the compilation system). + */ + +extern pcibr_piomap_t pcibr_piomap_alloc(devfs_handle_t dev, + device_desc_t dev_desc, + pciio_space_t space, + iopaddr_t pci_addr, + size_t byte_count, + size_t byte_count_max, + unsigned flags); + +extern void pcibr_piomap_free(pcibr_piomap_t piomap); + +extern caddr_t pcibr_piomap_addr(pcibr_piomap_t piomap, + iopaddr_t xtalk_addr, + size_t byte_count); + +extern void pcibr_piomap_done(pcibr_piomap_t piomap); + +extern caddr_t pcibr_piotrans_addr(devfs_handle_t dev, + device_desc_t dev_desc, + pciio_space_t space, + iopaddr_t pci_addr, + size_t byte_count, + unsigned flags); + +extern iopaddr_t pcibr_piospace_alloc(devfs_handle_t dev, + device_desc_t dev_desc, + pciio_space_t space, + size_t byte_count, + size_t alignment); +extern void pcibr_piospace_free(devfs_handle_t dev, + pciio_space_t space, + iopaddr_t pciaddr, + size_t byte_count); + +extern pcibr_dmamap_t pcibr_dmamap_alloc(devfs_handle_t dev, + device_desc_t dev_desc, + size_t byte_count_max, + unsigned flags); + +extern void pcibr_dmamap_free(pcibr_dmamap_t dmamap); + +extern iopaddr_t pcibr_dmamap_addr(pcibr_dmamap_t dmamap, + paddr_t paddr, + size_t byte_count); + +extern alenlist_t pcibr_dmamap_list(pcibr_dmamap_t dmamap, + alenlist_t palenlist, + unsigned flags); + +extern void pcibr_dmamap_done(pcibr_dmamap_t dmamap); + +extern iopaddr_t pcibr_dmatrans_addr(devfs_handle_t dev, + device_desc_t dev_desc, + paddr_t paddr, + size_t byte_count, + unsigned flags); + +extern alenlist_t pcibr_dmatrans_list(devfs_handle_t dev, + device_desc_t dev_desc, + alenlist_t palenlist, + unsigned flags); + +extern void pcibr_dmamap_drain(pcibr_dmamap_t map); + +extern void pcibr_dmaaddr_drain(devfs_handle_t vhdl, + paddr_t addr, + size_t bytes); + +extern void pcibr_dmalist_drain(devfs_handle_t vhdl, + alenlist_t list); + +typedef unsigned pcibr_intr_ibit_f(pciio_info_t info, + pciio_intr_line_t lines); + +extern void pcibr_intr_ibit_set(devfs_handle_t, pcibr_intr_ibit_f *); + +extern pcibr_intr_t pcibr_intr_alloc(devfs_handle_t dev, + device_desc_t dev_desc, + pciio_intr_line_t lines, + devfs_handle_t owner_dev); + +extern void pcibr_intr_free(pcibr_intr_t intr); + +extern int pcibr_intr_connect(pcibr_intr_t intr, + intr_func_t intr_func, + intr_arg_t intr_arg, + void *thread); + +extern void pcibr_intr_disconnect(pcibr_intr_t intr); + +extern devfs_handle_t pcibr_intr_cpu_get(pcibr_intr_t intr); + +extern void pcibr_provider_startup(devfs_handle_t pcibr); + +extern void pcibr_provider_shutdown(devfs_handle_t pcibr); + +extern int pcibr_reset(devfs_handle_t dev); + +extern int pcibr_write_gather_flush(devfs_handle_t dev); + +extern pciio_endian_t pcibr_endian_set(devfs_handle_t dev, + pciio_endian_t device_end, + pciio_endian_t desired_end); + +extern pciio_priority_t pcibr_priority_set(devfs_handle_t dev, + pciio_priority_t device_prio); + +extern uint64_t pcibr_config_get(devfs_handle_t conn, + unsigned reg, + unsigned size); + +extern void pcibr_config_set(devfs_handle_t conn, + unsigned reg, + unsigned size, + uint64_t value); + +extern int pcibr_error_devenable(devfs_handle_t pconn_vhdl, + int error_code); + +extern pciio_slot_t pcibr_error_extract(devfs_handle_t pcibr_vhdl, + pciio_space_t *spacep, + iopaddr_t *addrp); + +extern int pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, + int *count_vchan0, + int *count_vchan1); + +extern int pcibr_wrb_flush(devfs_handle_t pconn_vhdl); +extern int pcibr_rrb_check(devfs_handle_t pconn_vhdl, + int *count_vchan0, + int *count_vchan1, + int *count_reserved, + int *count_pool); + +extern int pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd, + int dev_1_rrbs, int virt1, + int dev_2_rrbs, int virt2, + int dev_3_rrbs, int virt3, + int dev_4_rrbs, int virt4); + +typedef void +rrb_alloc_funct_f (devfs_handle_t xconn_vhdl, + int *vendor_list); + +typedef rrb_alloc_funct_f *rrb_alloc_funct_t; + +void pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, + rrb_alloc_funct_f *func); + +extern void pcibr_device_unregister(devfs_handle_t); +extern int pcibr_dma_enabled(devfs_handle_t); +/* + * Bridge-specific flags that can be set via pcibr_device_flags_set + * and cleared via pcibr_device_flags_clear. Other flags are + * more generic and are maniuplated through PCI-generic interfaces. + * + * Note that all PCI implementation-specific flags (Bridge flags, in + * this case) are in bits 15-31. The lower 15 bits are reserved + * for PCI-generic flags. + * + * Some of these flags have been "promoted" to the + * generic layer, so they can be used without having + * to "know" that the PCI bus is hosted by a Bridge. + * + * PCIBR_NO_ATE_ROUNDUP: Request that no rounding up be done when + * allocating ATE's. ATE count computation will assume that the + * address to be mapped will start on a page boundary. + */ +#define PCIBR_NO_ATE_ROUNDUP 0x00008000 +#define PCIBR_WRITE_GATHER 0x00010000 /* please use PCIIO version */ +#define PCIBR_NOWRITE_GATHER 0x00020000 /* please use PCIIO version */ +#define PCIBR_PREFETCH 0x00040000 /* please use PCIIO version */ +#define PCIBR_NOPREFETCH 0x00080000 /* please use PCIIO version */ +#define PCIBR_PRECISE 0x00100000 +#define PCIBR_NOPRECISE 0x00200000 +#define PCIBR_BARRIER 0x00400000 +#define PCIBR_NOBARRIER 0x00800000 +#define PCIBR_VCHAN0 0x01000000 +#define PCIBR_VCHAN1 0x02000000 +#define PCIBR_64BIT 0x04000000 +#define PCIBR_NO64BIT 0x08000000 +#define PCIBR_SWAP 0x10000000 +#define PCIBR_NOSWAP 0x20000000 + +#define PCIBR_EXTERNAL_ATES 0x40000000 /* uses external ATEs */ +#define PCIBR_ACTIVE 0x80000000 /* need a "done" */ + +/* Flags that have meaning to pcibr_device_flags_{set,clear} */ +#define PCIBR_DEVICE_FLAGS ( \ + PCIBR_WRITE_GATHER |\ + PCIBR_NOWRITE_GATHER |\ + PCIBR_PREFETCH |\ + PCIBR_NOPREFETCH |\ + PCIBR_PRECISE |\ + PCIBR_NOPRECISE |\ + PCIBR_BARRIER |\ + PCIBR_NOBARRIER \ +) + +/* Flags that have meaning to *_dmamap_alloc, *_dmatrans_{addr,list} */ +#define PCIBR_DMA_FLAGS ( \ + PCIBR_PREFETCH |\ + PCIBR_NOPREFETCH |\ + PCIBR_PRECISE |\ + PCIBR_NOPRECISE |\ + PCIBR_BARRIER |\ + PCIBR_NOBARRIER |\ + PCIBR_VCHAN0 |\ + PCIBR_VCHAN1 \ +) + +typedef int pcibr_device_flags_t; + +/* + * Set bits in the Bridge Device(x) register for this device. + * "flags" are defined above. NOTE: this includes turning + * things *OFF* as well as turning them *ON* ... + */ +extern int pcibr_device_flags_set(devfs_handle_t dev, + pcibr_device_flags_t flags); + +/* + * Allocate Read Response Buffers for use by the specified device. + * count_vchan0 is the total number of buffers desired for the + * "normal" channel. count_vchan1 is the total number of buffers + * desired for the "virtual" channel. Returns 0 on success, or + * <0 on failure, which occurs when we're unable to allocate any + * buffers to a channel that desires at least one buffer. + */ +extern int pcibr_rrb_alloc(devfs_handle_t pconn_vhdl, + int *count_vchan0, + int *count_vchan1); + +/* + * Get the starting PCIbus address out of the given DMA map. + * This function is supposed to be used by a close friend of PCI bridge + * since it relies on the fact that the starting address of the map is fixed at + * the allocation time in the current implementation of PCI bridge. + */ +extern iopaddr_t pcibr_dmamap_pciaddr_get(pcibr_dmamap_t); + +extern xwidget_intr_preset_f pcibr_xintr_preset; + +extern void pcibr_hints_fix_rrbs(devfs_handle_t); +extern void pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t); +extern void pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t); +extern void pcibr_hints_handsoff(devfs_handle_t); + +typedef unsigned pcibr_intr_bits_f(pciio_info_t, pciio_intr_line_t); +extern void pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *); + +extern int pcibr_asic_rev(devfs_handle_t); + +#endif /* _LANGUAGE_C */ +#endif /* #if defined(__KERNEL__) */ +/* + * Some useful ioctls into the pcibr driver + */ +#define PCIBR 'p' +#define _PCIBR(x) ((PCIBR << 8) | (x)) + +#define PCIBR_SLOT_POWERUP _PCIBR(1) +#define PCIBR_SLOT_SHUTDOWN _PCIBR(2) +#define PCIBR_SLOT_INQUIRY _PCIBR(3) + +#endif /* _ASM_SN_PCI_PCIBR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/pcibr_private.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pcibr_private.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/pcibr_private.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pcibr_private.h Wed Dec 6 21:56:10 2000 @@ -0,0 +1,415 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_PCIBR_PRIVATE_H +#define _ASM_SN_PCI_PCIBR_PRIVATE_H + +/* + * pcibr_private.h -- private definitions for pcibr + * only the pcibr driver (and its closest friends) + * should ever peek into this file. + */ + +#include + +/* + * convenience typedefs + */ + +typedef uint64_t pcibr_DMattr_t; +typedef uint32_t pcibr_ATEattr_t; + +typedef struct pcibr_info_s *pcibr_info_t, **pcibr_info_h; +typedef struct pcibr_soft_s *pcibr_soft_t; +typedef struct pcibr_soft_slot_s *pcibr_soft_slot_t; +typedef struct pcibr_hints_s *pcibr_hints_t; +typedef struct pcibr_intr_list_s *pcibr_intr_list_t; +typedef struct pcibr_intr_wrap_s *pcibr_intr_wrap_t; + +/* + * Bridge sets up PIO using this information. + */ +struct pcibr_piomap_s { + struct pciio_piomap_s bp_pp; /* generic stuff */ + +#define bp_flags bp_pp.pp_flags /* PCIBR_PIOMAP flags */ +#define bp_dev bp_pp.pp_dev /* associated pci card */ +#define bp_slot bp_pp.pp_slot /* which slot the card is in */ +#define bp_space bp_pp.pp_space /* which address space */ +#define bp_pciaddr bp_pp.pp_pciaddr /* starting offset of mapping */ +#define bp_mapsz bp_pp.pp_mapsz /* size of this mapping */ +#define bp_kvaddr bp_pp.pp_kvaddr /* kernel virtual address to use */ + + iopaddr_t bp_xtalk_addr; /* corresponding xtalk address */ + xtalk_piomap_t bp_xtalk_pio; /* corresponding xtalk resource */ + pcibr_piomap_t bp_next; /* Next piomap on the list */ + pcibr_soft_t bp_soft; /* backpointer to bridge soft data */ + int bp_toc[1]; /* PCI timeout counter */ + +}; + +/* + * Bridge sets up DMA using this information. + */ +struct pcibr_dmamap_s { + struct pciio_dmamap_s bd_pd; +#define bd_flags bd_pd.pd_flags /* PCIBR_DMAMAP flags */ +#define bd_dev bd_pd.pd_dev /* associated pci card */ +#define bd_slot bd_pd.pd_slot /* which slot the card is in */ + struct pcibr_soft_s *bd_soft; /* pcibr soft state backptr */ + xtalk_dmamap_t bd_xtalk; /* associated xtalk resources */ + + size_t bd_max_size; /* maximum size of mapping */ + xwidgetnum_t bd_xio_port; /* target XIO port */ + iopaddr_t bd_xio_addr; /* target XIO address */ + iopaddr_t bd_pci_addr; /* via PCI address */ + + int bd_ate_index; /* Address Translation Entry Index */ + int bd_ate_count; /* number of ATE's allocated */ + bridge_ate_p bd_ate_ptr; /* where to write first ATE */ + bridge_ate_t bd_ate_proto; /* prototype ATE (for xioaddr=0) */ + bridge_ate_t bd_ate_prime; /* value of 1st ATE written */ +}; + +/* + * Bridge sets up interrupts using this information. + */ + +struct pcibr_intr_s { + struct pciio_intr_s bi_pi; +#define bi_flags bi_pi.pi_flags /* PCIBR_INTR flags */ +#define bi_dev bi_pi.pi_dev /* associated pci card */ +#define bi_lines bi_pi.pi_lines /* which PCI interrupt line(s) */ +#define bi_func bi_pi.pi_func /* handler function (when connected) */ +#define bi_arg bi_pi.pi_arg /* handler parameter (when connected) */ +#define bi_tinfo bi_pi.pi_tinfo /* Thread info (when connected) */ +#define bi_mustruncpu bi_pi.pi_mustruncpu /* Where we must run. */ +#define bi_irq bi_pi.pi_irq /* IRQ assigned. */ +#define bi_cpu bi_pi.pi_cpu /* cpu assigned. */ + unsigned bi_ibits; /* which Bridge interrupt bit(s) */ + pcibr_soft_t bi_soft; /* shortcut to soft info */ +}; + +/* + * per-connect point pcibr data, including + * standard pciio data in-line: + */ +struct pcibr_info_s { + struct pciio_info_s f_c; /* MUST BE FIRST. */ +#define f_vertex f_c.c_vertex /* back pointer to vertex */ +#define f_bus f_c.c_bus /* which bus the card is in */ +#define f_slot f_c.c_slot /* which slot the card is in */ +#define f_func f_c.c_func /* which func (on multi-func cards) */ +#define f_vendor f_c.c_vendor /* PCI card "vendor" code */ +#define f_device f_c.c_device /* PCI card "device" code */ +#define f_master f_c.c_master /* PCI bus provider */ +#define f_mfast f_c.c_mfast /* cached fastinfo from c_master */ +#define f_pops f_c.c_pops /* cached provider from c_master */ +#define f_efunc f_c.c_efunc /* error handling function */ +#define f_einfo f_c.c_einfo /* first parameter for efunc */ +#define f_window f_c.c_window /* state of BASE regs */ +#define f_rbase f_c.c_rbase /* expansion rom base */ +#define f_rsize f_c.c_rsize /* expansion rom size */ +#define f_piospace f_c.c_piospace /* additional I/O spaces allocated */ + + /* pcibr-specific connection state */ + int f_ibit[4]; /* Bridge bit for each INTx */ + pcibr_piomap_t f_piomap; +}; + +/* ===================================================================== + * Shared Interrupt Information + */ + +struct pcibr_intr_list_s { + pcibr_intr_list_t il_next; + pcibr_intr_t il_intr; + volatile bridgereg_t *il_wrbf; /* ptr to b_wr_req_buf[] */ +}; + +/* ===================================================================== + * Interrupt Wrapper Data + */ +struct pcibr_intr_wrap_s { + pcibr_soft_t iw_soft; /* which bridge */ + volatile bridgereg_t *iw_stat; /* ptr to b_int_status */ + bridgereg_t iw_intr; /* bits in b_int_status */ + pcibr_intr_list_t iw_list; /* ghostbusters! */ +}; + +#define PCIBR_ISR_ERR_START 8 +#define PCIBR_ISR_MAX_ERRS 32 + +/* ===================================================================== + * Bridge Device State structure + * + * one instance of this structure is kept for each + * Bridge ASIC in the system. + */ + +struct pcibr_soft_s { + devfs_handle_t bs_conn; /* xtalk connection point */ + devfs_handle_t bs_vhdl; /* vertex owned by pcibr */ + int bs_int_enable; /* Mask of enabled intrs */ + bridge_t *bs_base; /* PIO pointer to Bridge chip */ + char *bs_name; /* hw graph name */ + xwidgetnum_t bs_xid; /* Bridge's xtalk ID number */ + devfs_handle_t bs_master; /* xtalk master vertex */ + xwidgetnum_t bs_mxid; /* master's xtalk ID number */ + + 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 */ + short bs_int_ate_size; /* number of internal ates */ + short bs_xbridge; /* if 1 then xbridge */ + + int bs_rev_num; /* revision number of Bridge */ + + unsigned bs_dma_flags; /* revision-implied DMA flags */ + + /* + * Lock used primarily to get mutual exclusion while managing any + * bridge resources.. + */ + lock_t bs_lock; + + devfs_handle_t bs_noslot_conn; /* NO-SLOT connection point */ + pcibr_info_t bs_noslot_info; + struct pcibr_soft_slot_s { + /* information we keep about each CFG slot */ + + /* some devices (ioc3 in non-slotted + * configurations, sometimes) make use + * of more than one REQ/GNT/INT* signal + * sets. The slot corresponding to the + * IDSEL that the device responds to is + * called the host slot; the slot + * numbers that the device is stealing + * REQ/GNT/INT bits from are known as + * the guest slots. + */ + int has_host; + pciio_slot_t host_slot; + devfs_handle_t slot_conn; + /* Potentially several connection points + * for this slot. bss_ninfo is how many, + * and bss_infos is a pointer to + * an array pcibr_info_t values (which are + * pointers to pcibr_info structs, stored + * as device_info in connection ponts). + */ + int bss_ninfo; + pcibr_info_h bss_infos; + + /* Temporary Compatibility Macros, for + * stuff that has moved out of bs_slot + * and into the info structure. These + * will go away when their users have + * converted over to multifunction- + * friendly use of bss_{ninfo,infos}. + */ +#define bss_vendor_id bss_infos[0]->f_vendor +#define bss_device_id bss_infos[0]->f_device +#define bss_window bss_infos[0]->f_window +#define bssw_space w_space +#define bssw_base w_base +#define bssw_size w_size + + /* Where is DevIO(x) pointing? */ + /* bssd_space is NONE if it is not assigned. */ + struct { + pciio_space_t bssd_space; + iopaddr_t bssd_base; + } bss_devio; + + /* Shadow value for Device(x) register, + * so we don't have to go to the chip. + */ + bridgereg_t bss_device; + + /* Number of sets on GBR/REALTIME bit outstanding + * Used by Priority I/O for tracking reservations + */ + int bss_pri_uctr; + + /* Number of "uses" of PMU, 32-bit direct, + * and 64-bit direct DMA (0:none, <0: trans, + * >0: how many dmamaps). Device(x) bits + * controlling attribute of each kind of + * channel can't be changed by dmamap_alloc + * or dmatrans if the controlling counter + * is nonzero. dmatrans is forever. + */ + int bss_pmu_uctr; + int bss_d32_uctr; + int bss_d64_uctr; + + /* When the contents of mapping configuration + * information is locked down by dmatrans, + * repeated checks of the same flags should + * be shortcircuited for efficiency. + */ + iopaddr_t bss_d64_base; + unsigned bss_d64_flags; + iopaddr_t bss_d32_base; + unsigned bss_d32_flags; + + /* Shadow information used for implementing + * Bridge Hardware WAR #484930 + */ + int bss_ext_ates_active; + volatile unsigned *bss_cmd_pointer; + unsigned bss_cmd_shadow; + + } bs_slot[8]; + + pcibr_intr_bits_f *bs_intr_bits; + + /* RRB MANAGEMENT + * bs_rrb_fixed: bitmap of slots whose RRB + * allocations we should not "automatically" change + * bs_rrb_avail: number of RRBs that have not + * been allocated or reserved for {even,odd} slots + * bs_rrb_res: number of RRBs reserved for the + * use of the index slot number + * bs_rrb_valid: number of RRBs marked valid + * for the indexed slot number; indexes 8-15 + * are for the virtual channels for slots 0-7. + */ + int bs_rrb_fixed; + int bs_rrb_avail[2]; + int bs_rrb_res[8]; + int bs_rrb_valid[16]; + + struct { + /* Each Bridge interrupt bit has a single XIO + * interrupt channel allocated. + */ + xtalk_intr_t bsi_xtalk_intr; + /* + * We do not like sharing PCI interrrupt lines + * between devices, but the Origin 200 PCI + * layout forces us to do so. + */ + pcibr_intr_list_t bsi_pcibr_intr_list; + pcibr_intr_wrap_t bsi_pcibr_intr_wrap; + int bsi_pcibr_wrap_set; + + } bs_intr[8]; + + xtalk_intr_t bsi_err_intr; + + /* + * We stash away some information in this structure on getting + * an error interrupt. This information is used during PIO read/ + * write error handling. + * + * As it stands now, we do not re-enable the error interrupt + * till the error is resolved. Error resolution happens either at + * bus error time for PIO Read errors (~100 microseconds), or at + * the scheduled timeout time for PIO write errors (~milliseconds). + * If this delay causes problems, we may need to move towards + * a different scheme.. + * + * Note that there is no locking while looking at this data structure. + * There should not be any race between bus error code and + * error interrupt code.. will look into this if needed. + */ + struct br_errintr_info { + int bserr_toutcnt; +#ifdef IRIX + toid_t bserr_toutid; /* Timeout started by errintr */ +#endif + iopaddr_t bserr_addr; /* Address where error occured */ + bridgereg_t bserr_intstat; /* interrupts active at error time */ + } bs_errinfo; + + /* + * PCI Bus Space allocation data structure. + * This info is used to satisfy the callers of pcibr_piospace_alloc + * interface. Most of these users need "large" amounts of PIO + * space (typically in Megabytes), and they generally tend to + * take once and never release.. + * For Now use a simple algorithm to manage it. On allocation, + * Update the _base field to reflect next free address. + * + * Freeing does nothing.. So, once allocated, it's gone for good. + */ + struct br_pcisp_info { + iopaddr_t pci_io_base; + iopaddr_t pci_io_last; + iopaddr_t pci_swin_base; + iopaddr_t pci_swin_last; + iopaddr_t pci_mem_base; + iopaddr_t pci_mem_last; + } bs_spinfo; + + struct bs_errintr_stat_s { + uint32_t bs_errcount_total; + uint32_t bs_lasterr_timestamp; + uint32_t bs_lasterr_snapshot; + } bs_errintr_stat[PCIBR_ISR_MAX_ERRS]; + + /* + * Bridge-wide endianness control for + * large-window PIO mappings + * + * These fields are set to PCIIO_BYTE_SWAP + * or PCIIO_WORD_VALUES once the swapper + * has been configured, one way or the other, + * for the direct windows. If they are zero, + * nobody has a PIO mapping through that window, + * and the swapper can be set either way. + */ + unsigned bs_pio_end_io; + unsigned bs_pio_end_mem; +}; + +#define PCIBR_ERRTIME_THRESHOLD (100) +#define PCIBR_ERRRATE_THRESHOLD (100) + +/* + * pcibr will respond to hints dropped in its vertex + * using the following structure. + */ +struct pcibr_hints_s { + /* ph_host_slot is actually +1 so "0" means "no host" */ + pciio_slot_t ph_host_slot[8]; /* REQ/GNT/INT in use by ... */ + unsigned ph_rrb_fixed; /* do not change RRB allocations */ + unsigned ph_hands_off; /* prevent further pcibr operations */ + rrb_alloc_funct_t rrb_alloc_funct; /* do dynamic rrb allocation */ + pcibr_intr_bits_f *ph_intr_bits; /* map PCI INT[ABCD] to Bridge Int(n) */ +}; + +extern int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev; + +/* + * Number of bridge non-fatal error interrupts we can see before + * we decide to disable that interrupt. + */ +#define PCIBR_ERRINTR_DISABLE_LEVEL 10000 + +/* ===================================================================== + * Bridge (pcibr) state management functions + * + * pcibr_soft_get is here because we do it in a lot + * of places and I want to make sure they all stay + * in step with each other. + * + * pcibr_soft_set is here because I want it to be + * closely associated with pcibr_soft_get, even + * though it is only called in one place. + */ + +#define pcibr_soft_get(v) ((pcibr_soft_t)hwgraph_fastinfo_get((v))) +#define pcibr_soft_set(v,i) (hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))) + +#endif /* _ASM_SN_PCI_PCIBR_PRIVATE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/pciio.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pciio.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/pciio.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pciio.h Wed Dec 6 21:56:10 2000 @@ -0,0 +1,717 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_PCIIO_H +#define _ASM_SN_PCI_PCIIO_H + +/* + * pciio.h -- platform-independent PCI interface + */ + +#include +#include + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int pciio_vendor_id_t; + +#define PCIIO_VENDOR_ID_NONE -1 + +typedef int pciio_device_id_t; + +#define PCIIO_DEVICE_ID_NONE -1 + +#ifdef colin +typedef char pciio_bus_t; /* PCI bus number (0..255) */ +typedef char pciio_slot_t; /* PCI slot number (0..31, 255) */ +typedef char pciio_function_t; /* PCI func number (0..7, 255) */ +#else +typedef uint8_t pciio_bus_t; /* PCI bus number (0..255) */ +typedef uint8_t pciio_slot_t; /* PCI slot number (0..31, 255) */ +typedef uint8_t pciio_function_t; /* PCI func number (0..7, 255) */ +#endif + +#define PCIIO_SLOTS ((pciio_slot_t)32) +#define PCIIO_FUNCS ((pciio_function_t)8) + +#define PCIIO_SLOT_NONE ((pciio_slot_t)255) +#define PCIIO_FUNC_NONE ((pciio_function_t)255) + +typedef int pciio_intr_line_t; /* PCI interrupt line(s) */ + +#define PCIIO_INTR_LINE(n) (0x1 << (n)) +#define PCIIO_INTR_LINE_A (0x1) +#define PCIIO_INTR_LINE_B (0x2) +#define PCIIO_INTR_LINE_C (0x4) +#define PCIIO_INTR_LINE_D (0x8) + +typedef int pciio_space_t; /* PCI address space designation */ + +#define PCIIO_SPACE_NONE (0) +#define PCIIO_SPACE_ROM (1) +#define PCIIO_SPACE_IO (2) +/* PCIIO_SPACE_ (3) */ +#define PCIIO_SPACE_MEM (4) +#define PCIIO_SPACE_MEM32 (5) +#define PCIIO_SPACE_MEM64 (6) +#define PCIIO_SPACE_CFG (7) +#define PCIIO_SPACE_WIN0 (8) +#define PCIIO_SPACE_WIN(n) (PCIIO_SPACE_WIN0+(n)) /* 8..13 */ +/* PCIIO_SPACE_ (14) */ +#define PCIIO_SPACE_BAD (15) + +#if 1 /* does anyone really use these? */ +#define PCIIO_SPACE_USER0 (20) +#define PCIIO_SPACE_USER(n) (PCIIO_SPACE_USER0+(n)) /* 20 .. ? */ +#endif + +/* + * PCI_NOWHERE is the error value returned in + * place of a PCI address when there is no + * corresponding address. + */ +#define PCI_NOWHERE (0) + +/* + * Acceptable flag bits for pciio service calls + * + * PCIIO_FIXED: require that mappings be established + * using fixed sharable resources; address + * translation results will be permanently + * available. (PIOMAP_FIXED and DMAMAP_FIXED are + * the same numeric value and are acceptable). + * PCIIO_NOSLEEP: if any part of the operation would + * sleep waiting for resoruces, return an error + * instead. (PIOMAP_NOSLEEP and DMAMAP_NOSLEEP are + * the same numeric value and are acceptable). + * PCIIO_INPLACE: when operating on alenlist structures, + * reuse the source alenlist rather than creating a + * new one. (PIOMAP_INPLACE and DMAMAP_INPLACE are + * the same numeric value and are acceptable). + * + * PCIIO_DMA_CMD: configure this stream as a + * generic "command" stream. Generally this + * means turn off prefetchers and write + * gatherers, and whatever else might be + * necessary to make command ring DMAs + * work as expected. + * PCIIO_DMA_DATA: configure this stream as a + * generic "data" stream. Generally, this + * means turning on prefetchers and write + * gatherers, and anything else that might + * increase the DMA throughput (short of + * using "high priority" or "real time" + * resources that may lower overall system + * performance). + * PCIIO_DMA_A64: this device is capable of + * using 64-bit DMA addresses. Unless this + * flag is specified, it is assumed that + * the DMA address must be in the low 4G + * of PCI space. + * PCIIO_PREFETCH: if there are prefetchers + * available, they can be turned on. + * PCIIO_NOPREFETCH: any prefetchers along + * the dma path should be turned off. + * PCIIO_WRITE_GATHER: if there are write gatherers + * available, they can be turned on. + * PCIIO_NOWRITE_GATHER: any write gatherers along + * the dma path should be turned off. + * + * PCIIO_BYTE_STREAM: the DMA stream represents a group + * of ordered bytes. Arrange all byte swapping + * hardware so that the bytes land in the correct + * order. This is a common setting for data + * channels, but is NOT implied by PCIIO_DMA_DATA. + * PCIIO_WORD_VALUES: the DMA stream is used to + * communicate quantities stored in multiple bytes, + * and the device doing the DMA is little-endian; + * arrange any swapping hardware so that + * 32-bit-wide values are maintained. This is a + * common setting for command rings that contain + * DMA addresses and counts, but is NOT implied by + * PCIIO_DMA_CMD. CPU Accesses to 16-bit fields + * must have their address xor-ed with 2, and + * accesses to individual bytes must have their + * addresses xor-ed with 3 relative to what the + * device expects. + * + * NOTE: any "provider specific" flags that + * conflict with the generic flags will + * override the generic flags, locally + * at that provider. + * + * Also, note that PCI-generic flags (PCIIO_) are + * in bits 0-14. The upper bits, 15-31, are reserved + * for PCI implementation-specific flags. + */ + +#define PCIIO_FIXED DMAMAP_FIXED +#define PCIIO_NOSLEEP DMAMAP_NOSLEEP +#define PCIIO_INPLACE DMAMAP_INPLACE + +#define PCIIO_DMA_CMD 0x0010 +#define PCIIO_DMA_DATA 0x0020 +#define PCIIO_DMA_A64 0x0040 + +#define PCIIO_WRITE_GATHER 0x0100 +#define PCIIO_NOWRITE_GATHER 0x0200 +#define PCIIO_PREFETCH 0x0400 +#define PCIIO_NOPREFETCH 0x0800 + +/* Requesting an endianness setting that the + * underlieing hardware can not support + * WILL result in a failure to allocate + * dmamaps or complete a dmatrans. + */ +#define PCIIO_BYTE_STREAM 0x1000 /* set BYTE SWAP for "byte stream" */ +#define PCIIO_WORD_VALUES 0x2000 /* set BYTE SWAP for "word values" */ + +/* + * Interface to deal with PCI endianness. + * The driver calls pciio_endian_set once, supplying the actual endianness of + * the device and the desired endianness. On SGI systems, only use LITTLE if + * dealing with a driver that does software swizzling. Most of the time, + * it's preferable to request BIG. The return value indicates the endianness + * that is actually achieved. On systems that support hardware swizzling, + * the achieved endianness will be the desired endianness. On systems without + * swizzle hardware, the achieved endianness will be the device's endianness. + */ +typedef enum pciio_endian_e { + PCIDMA_ENDIAN_BIG, + PCIDMA_ENDIAN_LITTLE +} pciio_endian_t; + +/* + * Interface to set PCI arbitration priority for devices that require + * realtime characteristics. pciio_priority_set is used to switch a + * device between the PCI high-priority arbitration ring and the low + * priority arbitration ring. + * + * (Note: this is strictly for the PCI arbitrary priority. It has + * no direct relationship to GBR.) + */ +typedef enum pciio_priority_e { + PCI_PRIO_LOW, + PCI_PRIO_HIGH +} pciio_priority_t; + +/* + * handles of various sorts + */ +typedef struct pciio_piomap_s *pciio_piomap_t; +typedef struct pciio_dmamap_s *pciio_dmamap_t; +typedef struct pciio_intr_s *pciio_intr_t; +typedef struct pciio_info_s *pciio_info_t; +typedef struct pciio_piospace_s *pciio_piospace_t; + +/* PIO MANAGEMENT */ + +/* + * A NOTE ON PCI PIO ADDRESSES + * + * PCI supports three different address spaces: CFG + * space, MEM space and I/O space. Further, each + * card always accepts CFG accesses at an address + * based on which slot it is attached to, but can + * decode up to six address ranges. + * + * Assignment of the base address registers for all + * PCI devices is handled centrally; most commonly, + * device drivers will want to talk to offsets + * within one or another of the address ranges. In + * order to do this, which of these "address + * spaces" the PIO is directed into must be encoded + * in the flag word. + * + * We reserve the right to defer allocation of PCI + * address space for a device window until the + * driver makes a piomap_alloc or piotrans_addr + * request. + * + * If a device driver mucks with its device's base + * registers through a PIO mapping to CFG space, + * results of further PIO through the corresponding + * window are UNDEFINED. + * + * Windows are named by the index in the base + * address register set for the device of the + * desired register; IN THE CASE OF 64 BIT base + * registers, the index should be to the word of + * the register that contains the mapping type + * bits; since the PCI CFG space is natively + * organized little-endian fashion, this is the + * first of the two words. + * + * AT THE MOMENT, any required corrections for + * endianness are the responsibility of the device + * driver; not all platforms support control in + * hardware of byteswapping hardware. We anticipate + * providing flag bits to the PIO and DMA + * management interfaces to request different + * configurations of byteswapping hardware. + * + * PIO Accesses to CFG space via the "Bridge" ASIC + * used in IP30 platforms preserve the native byte + * significance within the 32-bit word; byte + * addresses for single byte accesses need to be + * XORed with 3, and addresses for 16-bit accesses + * need to be XORed with 2. + * + * The IOC3 used on IP30, and other SGI PCI devices + * as well, require use of 32-bit accesses to their + * configuration space registers. Any potential PCI + * bus providers need to be aware of this requirement. + */ + +#define PCIIO_PIOMAP_CFG (0x1) +#define PCIIO_PIOMAP_MEM (0x2) +#define PCIIO_PIOMAP_IO (0x4) +#define PCIIO_PIOMAP_WIN(n) (0x8+(n)) + +typedef pciio_piomap_t +pciio_piomap_alloc_f (devfs_handle_t dev, /* set up mapping for this device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_space_t space, /* which address space */ + iopaddr_t pcipio_addr, /* starting address */ + size_t byte_count, + size_t byte_count_max, /* maximum size of a mapping */ + unsigned flags); /* defined in sys/pio.h */ + +typedef void +pciio_piomap_free_f (pciio_piomap_t pciio_piomap); + +typedef caddr_t +pciio_piomap_addr_f (pciio_piomap_t pciio_piomap, /* mapping resources */ + iopaddr_t pciio_addr, /* map for this pcipio address */ + size_t byte_count); /* map this many bytes */ + +typedef void +pciio_piomap_done_f (pciio_piomap_t pciio_piomap); + +typedef caddr_t +pciio_piotrans_addr_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_space_t space, /* which address space */ + iopaddr_t pciio_addr, /* starting address */ + size_t byte_count, /* map this many bytes */ + unsigned flags); + +typedef caddr_t +pciio_pio_addr_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_space_t space, /* which address space */ + iopaddr_t pciio_addr, /* starting address */ + size_t byte_count, /* map this many bytes */ + pciio_piomap_t *mapp, /* in case a piomap was needed */ + unsigned flags); + +typedef iopaddr_t +pciio_piospace_alloc_f (devfs_handle_t dev, /* PIO space for this device */ + device_desc_t dev_desc, /* Device descriptor */ + pciio_space_t space, /* which address space */ + size_t byte_count, /* Number of bytes of space */ + size_t alignment); /* Alignment of allocation */ + +typedef void +pciio_piospace_free_f (devfs_handle_t dev, /* Device freeing space */ + pciio_space_t space, /* Which space is freed */ + iopaddr_t pci_addr, /* Address being freed */ + size_t size); /* Size freed */ + +/* DMA MANAGEMENT */ + +typedef pciio_dmamap_t +pciio_dmamap_alloc_f (devfs_handle_t dev, /* set up mappings for this device */ + device_desc_t dev_desc, /* device descriptor */ + size_t byte_count_max, /* max size of a mapping */ + unsigned flags); /* defined in dma.h */ + +typedef void +pciio_dmamap_free_f (pciio_dmamap_t dmamap); + +typedef iopaddr_t +pciio_dmamap_addr_f (pciio_dmamap_t dmamap, /* use these mapping resources */ + paddr_t paddr, /* map for this address */ + size_t byte_count); /* map this many bytes */ + +typedef alenlist_t +pciio_dmamap_list_f (pciio_dmamap_t dmamap, /* use these mapping resources */ + alenlist_t alenlist, /* map this address/length list */ + unsigned flags); + +typedef void +pciio_dmamap_done_f (pciio_dmamap_t dmamap); + +typedef iopaddr_t +pciio_dmatrans_addr_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + unsigned flags); /* defined in dma.h */ + +typedef alenlist_t +pciio_dmatrans_list_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + alenlist_t palenlist, /* system address/length list */ + unsigned flags); /* defined in dma.h */ + +typedef void +pciio_dmamap_drain_f (pciio_dmamap_t map); + +typedef void +pciio_dmaaddr_drain_f (devfs_handle_t vhdl, + paddr_t addr, + size_t bytes); + +typedef void +pciio_dmalist_drain_f (devfs_handle_t vhdl, + alenlist_t list); + +/* INTERRUPT MANAGEMENT */ + +typedef pciio_intr_t +pciio_intr_alloc_f (devfs_handle_t dev, /* which PCI device */ + device_desc_t dev_desc, /* device descriptor */ + pciio_intr_line_t lines, /* which line(s) will be used */ + devfs_handle_t owner_dev); /* owner of this intr */ + +typedef void +pciio_intr_free_f (pciio_intr_t intr_hdl); + +typedef int +pciio_intr_connect_f (pciio_intr_t intr_hdl, /* pciio intr resource handle */ + intr_func_t intr_func, /* pciio intr handler */ + intr_arg_t intr_arg, /* arg to intr handler */ + void *thread); /* intr thread to use */ + +typedef void +pciio_intr_disconnect_f (pciio_intr_t intr_hdl); + +typedef devfs_handle_t +pciio_intr_cpu_get_f (pciio_intr_t intr_hdl); /* pciio intr resource handle */ + +/* CONFIGURATION MANAGEMENT */ + +typedef void +pciio_provider_startup_f (devfs_handle_t pciio_provider); + +typedef void +pciio_provider_shutdown_f (devfs_handle_t pciio_provider); + +typedef int +pciio_reset_f (devfs_handle_t conn); /* pci connection point */ + +typedef int +pciio_write_gather_flush_f (devfs_handle_t dev); /* Device flushing buffers */ + +typedef pciio_endian_t /* actual endianness */ +pciio_endian_set_f (devfs_handle_t dev, /* specify endianness for this device */ + pciio_endian_t device_end, /* endianness of device */ + pciio_endian_t desired_end); /* desired endianness */ + +typedef pciio_priority_t +pciio_priority_set_f (devfs_handle_t pcicard, + pciio_priority_t device_prio); + +typedef uint64_t +pciio_config_get_f (devfs_handle_t conn, /* pci connection point */ + unsigned reg, /* register byte offset */ + unsigned size); /* width in bytes (1..4) */ + +typedef void +pciio_config_set_f (devfs_handle_t conn, /* pci connection point */ + unsigned reg, /* register byte offset */ + unsigned size, /* width in bytes (1..4) */ + uint64_t value); /* value to store */ + +typedef int +pciio_error_devenable_f (devfs_handle_t pconn_vhdl, int error_code); + +typedef pciio_slot_t +pciio_error_extract_f (devfs_handle_t vhdl, + pciio_space_t *spacep, + iopaddr_t *addrp); + +/* + * Adapters that provide a PCI interface adhere to this software interface. + */ +typedef struct pciio_provider_s { + /* PIO MANAGEMENT */ + pciio_piomap_alloc_f *piomap_alloc; + pciio_piomap_free_f *piomap_free; + pciio_piomap_addr_f *piomap_addr; + pciio_piomap_done_f *piomap_done; + pciio_piotrans_addr_f *piotrans_addr; + pciio_piospace_alloc_f *piospace_alloc; + pciio_piospace_free_f *piospace_free; + + /* DMA MANAGEMENT */ + pciio_dmamap_alloc_f *dmamap_alloc; + pciio_dmamap_free_f *dmamap_free; + pciio_dmamap_addr_f *dmamap_addr; + pciio_dmamap_list_f *dmamap_list; + pciio_dmamap_done_f *dmamap_done; + pciio_dmatrans_addr_f *dmatrans_addr; + pciio_dmatrans_list_f *dmatrans_list; + pciio_dmamap_drain_f *dmamap_drain; + pciio_dmaaddr_drain_f *dmaaddr_drain; + pciio_dmalist_drain_f *dmalist_drain; + + /* INTERRUPT MANAGEMENT */ + pciio_intr_alloc_f *intr_alloc; + pciio_intr_free_f *intr_free; + pciio_intr_connect_f *intr_connect; + pciio_intr_disconnect_f *intr_disconnect; + pciio_intr_cpu_get_f *intr_cpu_get; + + /* CONFIGURATION MANAGEMENT */ + pciio_provider_startup_f *provider_startup; + pciio_provider_shutdown_f *provider_shutdown; + pciio_reset_f *reset; + pciio_write_gather_flush_f *write_gather_flush; + pciio_endian_set_f *endian_set; + pciio_priority_set_f *priority_set; + pciio_config_get_f *config_get; + pciio_config_set_f *config_set; + + /* Error handling interface */ + pciio_error_devenable_f *error_devenable; + pciio_error_extract_f *error_extract; +} pciio_provider_t; + +/* PCI devices use these standard PCI provider interfaces */ +extern pciio_piomap_alloc_f pciio_piomap_alloc; +extern pciio_piomap_free_f pciio_piomap_free; +extern pciio_piomap_addr_f pciio_piomap_addr; +extern pciio_piomap_done_f pciio_piomap_done; +extern pciio_piotrans_addr_f pciio_piotrans_addr; +extern pciio_pio_addr_f pciio_pio_addr; +extern pciio_piospace_alloc_f pciio_piospace_alloc; +extern pciio_piospace_free_f pciio_piospace_free; +extern pciio_dmamap_alloc_f pciio_dmamap_alloc; +extern pciio_dmamap_free_f pciio_dmamap_free; +extern pciio_dmamap_addr_f pciio_dmamap_addr; +extern pciio_dmamap_list_f pciio_dmamap_list; +extern pciio_dmamap_done_f pciio_dmamap_done; +extern pciio_dmatrans_addr_f pciio_dmatrans_addr; +extern pciio_dmatrans_list_f pciio_dmatrans_list; +extern pciio_dmamap_drain_f pciio_dmamap_drain; +extern pciio_dmaaddr_drain_f pciio_dmaaddr_drain; +extern pciio_dmalist_drain_f pciio_dmalist_drain; +extern pciio_intr_alloc_f pciio_intr_alloc; +extern pciio_intr_free_f pciio_intr_free; +extern pciio_intr_connect_f pciio_intr_connect; +extern pciio_intr_disconnect_f pciio_intr_disconnect; +extern pciio_intr_cpu_get_f pciio_intr_cpu_get; +extern pciio_provider_startup_f pciio_provider_startup; +extern pciio_provider_shutdown_f pciio_provider_shutdown; +extern pciio_reset_f pciio_reset; +extern pciio_write_gather_flush_f pciio_write_gather_flush; +extern pciio_endian_set_f pciio_endian_set; +extern pciio_priority_set_f pciio_priority_set; +extern pciio_config_get_f pciio_config_get; +extern pciio_config_set_f pciio_config_set; +extern pciio_error_devenable_f pciio_error_devenable; +extern pciio_error_extract_f pciio_error_extract; + +/* Widgetdev in the IOERROR structure is encoded as follows. + * +---------------------------+ + * | slot (7:3) | function(2:0)| + * +---------------------------+ + * Following are the convenience interfaces to get at form + * a widgetdev or to break it into its constituents. + */ + +#define PCIIO_WIDGETDEV_SLOT_SHFT 3 +#define PCIIO_WIDGETDEV_SLOT_MASK 0x1f +#define PCIIO_WIDGETDEV_FUNC_MASK 0x7 + +#ifdef IRIX +#define pciio_widgetdev_create(slot,func) \ + ((slot) << PCIIO_WIDGETDEV_SLOT_SHFT + (func)) +#else +#define pciio_widgetdev_create(slot,func) \ + (((slot) << PCIIO_WIDGETDEV_SLOT_SHFT) + (func)) +#endif + +#define pciio_widgetdev_slot_get(wdev) \ + (((wdev) >> PCIIO_WIDGETDEV_SLOT_SHFT) & PCIIO_WIDGETDEV_SLOT_MASK) + +#define pciio_widgetdev_func_get(wdev) \ + ((wdev) & PCIIO_WIDGETDEV_FUNC_MASK) + + +/* Generic PCI card initialization interface + */ + +extern int +pciio_driver_register (pciio_vendor_id_t vendor_id, /* card's vendor number */ + pciio_device_id_t device_id, /* card's device number */ + char *driver_prefix, /* driver prefix */ + unsigned flags); + +extern void +pciio_error_register (devfs_handle_t pconn, /* which slot */ + error_handler_f *efunc, /* function to call */ + error_handler_arg_t einfo); /* first parameter */ + +extern void pciio_driver_unregister(char *driver_prefix); + +typedef void pciio_iter_f(devfs_handle_t pconn); /* a connect point */ + +extern void pciio_iterate(char *driver_prefix, + pciio_iter_f *func); + +/* Interfaces used by PCI Bus Providers to talk to + * the Generic PCI layer. + */ +extern devfs_handle_t +pciio_device_register (devfs_handle_t connectpt, /* vertex at center of bus */ + devfs_handle_t master, /* card's master ASIC (pci provider) */ + pciio_slot_t slot, /* card's slot (0..?) */ + pciio_function_t func, /* card's func (0..?) */ + pciio_vendor_id_t vendor, /* card's vendor number */ + pciio_device_id_t device); /* card's device number */ + +extern void +pciio_device_unregister(devfs_handle_t connectpt); + +extern pciio_info_t +pciio_device_info_new (pciio_info_t pciio_info, /* preallocated info struct */ + devfs_handle_t master, /* card's master ASIC (pci provider) */ + pciio_slot_t slot, /* card's slot (0..?) */ + pciio_function_t func, /* card's func (0..?) */ + pciio_vendor_id_t vendor, /* card's vendor number */ + pciio_device_id_t device); /* card's device number */ + +extern void +pciio_device_info_free(pciio_info_t pciio_info); + +extern devfs_handle_t +pciio_device_info_register( + devfs_handle_t connectpt, /* vertex at center of bus */ + pciio_info_t pciio_info); /* details about conn point */ + +extern void +pciio_device_info_unregister( + devfs_handle_t connectpt, /* vertex at center of bus */ + pciio_info_t pciio_info); /* details about conn point */ + + +extern int pciio_device_attach(devfs_handle_t pcicard); /* vertex created by pciio_device_register */ +extern int pciio_device_detach(devfs_handle_t pcicard); /* vertex created by pciio_device_register */ + +/* + * Generic PCI interface, for use with all PCI providers + * and all PCI devices. + */ + +/* Generic PCI interrupt interfaces */ +extern devfs_handle_t pciio_intr_dev_get(pciio_intr_t pciio_intr); +extern devfs_handle_t pciio_intr_cpu_get(pciio_intr_t pciio_intr); + +/* Generic PCI pio interfaces */ +extern devfs_handle_t pciio_pio_dev_get(pciio_piomap_t pciio_piomap); +extern pciio_slot_t pciio_pio_slot_get(pciio_piomap_t pciio_piomap); +extern pciio_space_t pciio_pio_space_get(pciio_piomap_t pciio_piomap); +extern iopaddr_t pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap); +extern ulong pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap); +extern caddr_t pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap); + +#ifdef IRIX +#ifdef USE_PCI_PIO +extern uint8_t pciio_pio_read8(volatile uint8_t *addr); +extern uint16_t pciio_pio_read16(volatile uint16_t *addr); +extern uint32_t pciio_pio_read32(volatile uint32_t *addr); +extern uint64_t pciio_pio_read64(volatile uint64_t *addr); +extern void pciio_pio_write8(uint8_t val, volatile uint8_t *addr); +extern void pciio_pio_write16(uint16_t val, volatile uint16_t *addr); +extern void pciio_pio_write32(uint32_t val, volatile uint32_t *addr); +extern void pciio_pio_write64(uint64_t val, volatile uint64_t *addr); +#else /* !USE_PCI_PIO */ +__inline uint8_t pciio_pio_read8(volatile uint8_t *addr) +{ + return *addr; +} +__inline uint16_t pciio_pio_read16(volatile uint16_t *addr) +{ + return *addr; +} +__inline uint32_t pciio_pio_read32(volatile uint32_t *addr) +{ + return *addr; +} +__inline uint64_t pciio_pio_read64(volatile uint64_t *addr) +{ + return *addr; +} +__inline void pciio_pio_write8(uint8_t val, volatile uint8_t *addr) +{ + *addr = val; +} +__inline void pciio_pio_write16(uint16_t val, volatile uint16_t *addr) +{ + *addr = val; +} +__inline void pciio_pio_write32(uint32_t val, volatile uint32_t *addr) +{ + *addr = val; +} +__inline void pciio_pio_write64(uint64_t val, volatile uint64_t *addr) +{ + *addr = val; +} +#endif /* USE_PCI_PIO */ +#endif + +/* Generic PCI dma interfaces */ +extern devfs_handle_t pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap); + +/* Register/unregister PCI providers and get implementation handle */ +extern void pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns); +extern void pciio_provider_unregister(devfs_handle_t provider); +extern pciio_provider_t *pciio_provider_fns_get(devfs_handle_t provider); + +/* Generic pci slot information access interface */ +extern pciio_info_t pciio_info_chk(devfs_handle_t vhdl); +extern pciio_info_t pciio_info_get(devfs_handle_t vhdl); +extern void pciio_info_set(devfs_handle_t vhdl, pciio_info_t widget_info); +extern devfs_handle_t pciio_info_dev_get(pciio_info_t pciio_info); +extern pciio_bus_t pciio_info_bus_get(pciio_info_t pciio_info); +extern pciio_slot_t pciio_info_slot_get(pciio_info_t pciio_info); +extern pciio_function_t pciio_info_function_get(pciio_info_t pciio_info); +extern pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t pciio_info); +extern pciio_device_id_t pciio_info_device_id_get(pciio_info_t pciio_info); +extern devfs_handle_t pciio_info_master_get(pciio_info_t pciio_info); +extern arbitrary_info_t pciio_info_mfast_get(pciio_info_t pciio_info); +extern pciio_provider_t *pciio_info_pops_get(pciio_info_t pciio_info); +extern error_handler_f *pciio_info_efunc_get(pciio_info_t); +extern error_handler_arg_t *pciio_info_einfo_get(pciio_info_t); +extern pciio_space_t pciio_info_bar_space_get(pciio_info_t, int); +extern iopaddr_t pciio_info_bar_base_get(pciio_info_t, int); +extern size_t pciio_info_bar_size_get(pciio_info_t, int); +extern iopaddr_t pciio_info_rom_base_get(pciio_info_t); +extern size_t pciio_info_rom_size_get(pciio_info_t); + +extern int pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *); +extern int pciio_dma_enabled(devfs_handle_t); + +#ifdef __cplusplus +}; +#endif +#endif /* C or C++ */ +#endif /* _ASM_SN_PCI_PCIIO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pci/pciio_private.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pciio_private.h --- linux-2.4.0-test12/include/asm-ia64/sn/pci/pciio_private.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pci/pciio_private.h Wed Dec 6 21:56:10 2000 @@ -0,0 +1,100 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PCI_PCIIO_PRIVATE_H +#define _ASM_SN_PCI_PCIIO_PRIVATE_H + +#ifdef colin +#include +#endif + +/* + * pciio_private.h -- private definitions for pciio + * PCI drivers should NOT include this file. + */ + +#ident "sys/PCI/pciio_private: $Revision: 1.13 $" + +/* + * All PCI providers set up PIO using this information. + */ +struct pciio_piomap_s { + unsigned pp_flags; /* PCIIO_PIOMAP flags */ + devfs_handle_t pp_dev; /* associated pci card */ + pciio_slot_t pp_slot; /* which slot the card is in */ + pciio_space_t pp_space; /* which address space */ + iopaddr_t pp_pciaddr; /* starting offset of mapping */ + size_t pp_mapsz; /* size of this mapping */ + caddr_t pp_kvaddr; /* kernel virtual address to use */ +}; + +/* + * All PCI providers set up DMA using this information. + */ +struct pciio_dmamap_s { + unsigned pd_flags; /* PCIIO_DMAMAP flags */ + devfs_handle_t pd_dev; /* associated pci card */ + pciio_slot_t pd_slot; /* which slot the card is in */ +}; + +/* + * All PCI providers set up interrupts using this information. + */ + +struct pciio_intr_s { + unsigned pi_flags; /* PCIIO_INTR flags */ + devfs_handle_t pi_dev; /* associated pci card */ + device_desc_t pi_dev_desc; /* override device descriptor */ + pciio_intr_line_t pi_lines; /* which interrupt line(s) */ + intr_func_t pi_func; /* handler function (when connected) */ + intr_arg_t pi_arg; /* handler parameter (when connected) */ +#ifdef IRIX + thd_int_t pi_tinfo; /* Thread info (when connected) */ +#endif + cpuid_t pi_mustruncpu; /* Where we must run. */ + int pi_irq; /* IRQ assigned */ + int pi_cpu; /* cpu assigned */ +}; + +/* PCIIO_INTR (pi_flags) flags */ +#define PCIIO_INTR_CONNECTED 1 /* interrupt handler/thread has been connected */ +#define PCIIO_INTR_NOTHREAD 2 /* interrupt handler wants to be called at interrupt level */ + +/* + * Each PCI Card has one of these. + */ + +struct pciio_info_s { + char *c_fingerprint; + devfs_handle_t c_vertex; /* back pointer to vertex */ + pciio_bus_t c_bus; /* which bus the card is in */ + pciio_slot_t c_slot; /* which slot the card is in */ + pciio_function_t c_func; /* which func (on multi-func cards) */ + pciio_vendor_id_t c_vendor; /* PCI card "vendor" code */ + pciio_device_id_t c_device; /* PCI card "device" code */ + devfs_handle_t c_master; /* PCI bus provider */ + arbitrary_info_t c_mfast; /* cached fastinfo from c_master */ + pciio_provider_t *c_pops; /* cached provider from c_master */ + error_handler_f *c_efunc; /* error handling function */ + error_handler_arg_t c_einfo; /* first parameter for efunc */ + + struct { /* state of BASE regs */ + pciio_space_t w_space; + iopaddr_t w_base; + size_t w_size; + } c_window[6]; + + unsigned c_rbase; /* EXPANSION ROM base addr */ + unsigned c_rsize; /* EXPANSION ROM size (bytes) */ + + pciio_piospace_t c_piospace; /* additional I/O spaces allocated */ +}; + +extern char pciio_info_fingerprint[]; +#endif /* _ASM_SN_PCI_PCIIO_PRIVATE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/pio.h linux-2.4.0-test12-lia/include/asm-ia64/sn/pio.h --- linux-2.4.0-test12/include/asm-ia64/sn/pio.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/pio.h Wed Dec 13 23:58:14 2000 @@ -0,0 +1,155 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PIO_H +#define _ASM_SN_PIO_H + +#include +#include +#include + +/* + * pioaddr_t - The kernel virtual address that a PIO can be done upon. + * Should probably be (volatile void*) but EVEREST would do PIO + * to long mostly, just cast for other sizes. + */ + +typedef volatile ulong* pioaddr_t; + +/* + * iopaddr_t - the physical io space relative address (e.g. VME A16S 0x0800). + * iosapce_t - specifies the io address space to be mapped/accessed. + * piomap_t - the handle returned by pio_alloc() and used with all the pio + * access functions. + */ + + +typedef struct piomap { + uint pio_bus; + uint pio_adap; +#ifdef IRIX + iospace_t pio_iospace; +#endif + int pio_flag; + int pio_reg; + char pio_name[7]; /* to identify the mapped device */ + struct piomap *pio_next; /* dlist to link active piomap's */ + struct piomap *pio_prev; /* for debug and error reporting */ +#ifdef IRIX + void (*pio_errfunc)(); /* Pointer to an error function */ + /* Used only for piomaps allocated + * in user level vme driver */ +#endif + iopaddr_t pio_iopmask; /* valid iop address bit mask */ + iobush_t pio_bushandle; /* bus-level handle */ +} piomap_t; + + +/* Macro to get/set PIO error function */ +#define pio_seterrf(p,f) (p)->pio_errfunc = (f) +#define pio_geterrf(p) (p)->pio_errfunc + + +/* + * pio_mapalloc() - allocates a handle that specifies a mapping from kernel + * virtual to io space. The returned handle piomap is used + * with the access functions to make sure that the mapping + * to the iospace exists. + * pio_mapfree() - frees the mapping as specified in the piomap handle. + * pio_mapaddr() - returns the kv address that maps to piomap'ed io address. + */ +#ifdef IRIX +extern piomap_t *pio_mapalloc(uint,uint,iospace_t*,int,char*); +extern void pio_mapfree(piomap_t*); +extern caddr_t pio_mapaddr(piomap_t*,iopaddr_t); +extern piomap_t *pio_ioaddr(int, iobush_t, iopaddr_t, piomap_t *); + +/* + * PIO access functions. + */ +extern int pio_badaddr(piomap_t*,iopaddr_t,int); +extern int pio_badaddr_val(piomap_t*,iopaddr_t,int,void*); +extern int pio_wbadaddr(piomap_t*,iopaddr_t,int); +extern int pio_wbadaddr_val(piomap_t*,iopaddr_t,int,int); +extern int pio_bcopyin(piomap_t*,iopaddr_t,void *,int, int, int); +extern int pio_bcopyout(piomap_t*,iopaddr_t,void *,int, int, int); + + +/* + * PIO RMW functions using piomap. + */ +extern void pio_orb_rmw(piomap_t*, iopaddr_t, unsigned char); +extern void pio_orh_rmw(piomap_t*, iopaddr_t, unsigned short); +extern void pio_orw_rmw(piomap_t*, iopaddr_t, unsigned long); +extern void pio_andb_rmw(piomap_t*, iopaddr_t, unsigned char); +extern void pio_andh_rmw(piomap_t*, iopaddr_t, unsigned short); +extern void pio_andw_rmw(piomap_t*, iopaddr_t, unsigned long); + + +/* + * Old RMW function interface + */ +extern void orb_rmw(volatile void*, unsigned int); +extern void orh_rmw(volatile void*, unsigned int); +extern void orw_rmw(volatile void*, unsigned int); +extern void andb_rmw(volatile void*, unsigned int); +extern void andh_rmw(volatile void*, unsigned int); +extern void andw_rmw(volatile void*, unsigned int); +#endif /* IRIX */ + + +/* + * piomap_t type defines + */ + +#define PIOMAP_NTYPES 7 + +#define PIOMAP_A16N VME_A16NP +#define PIOMAP_A16S VME_A16S +#define PIOMAP_A24N VME_A24NP +#define PIOMAP_A24S VME_A24S +#define PIOMAP_A32N VME_A32NP +#define PIOMAP_A32S VME_A32S +#define PIOMAP_A64 6 + +#define PIOMAP_EISA_IO 0 +#define PIOMAP_EISA_MEM 1 + +#define PIOMAP_PCI_IO 0 +#define PIOMAP_PCI_MEM 1 +#define PIOMAP_PCI_CFG 2 +#define PIOMAP_PCI_ID 3 + +/* IBUS piomap types */ +#define PIOMAP_FCI 0 + +/* dang gio piomap types */ + +#define PIOMAP_GIO32 0 +#define PIOMAP_GIO64 1 + +#define ET_MEM 0 +#define ET_IO 1 +#define LAN_RAM 2 +#define LAN_IO 3 + +#define PIOREG_NULL -1 + +/* standard flags values for pio_map routines, + * including {xtalk,pciio}_piomap calls. + * NOTE: try to keep these in step with DMAMAP flags. + */ +#define PIOMAP_UNFIXED 0x0 +#define PIOMAP_FIXED 0x1 +#define PIOMAP_NOSLEEP 0x2 +#define PIOMAP_INPLACE 0x4 + +#define PIOMAP_FLAGS 0x7 + +#endif /* _ASM_SN_PIO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/prio.h linux-2.4.0-test12-lia/include/asm-ia64/sn/prio.h --- linux-2.4.0-test12/include/asm-ia64/sn/prio.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/prio.h Wed Dec 6 21:56:10 2000 @@ -0,0 +1,38 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PRIO_H +#define _ASM_SN_PRIO_H + +/* + * Priority I/O function prototypes and macro definitions + */ + +typedef long long bandwidth_t; + +/* These should be the same as FREAD/FWRITE */ +#define PRIO_READ_ALLOCATE 0x1 +#define PRIO_WRITE_ALLOCATE 0x2 +#define PRIO_READWRITE_ALLOCATE (PRIO_READ_ALLOCATE | PRIO_WRITE_ALLOCATE) + +extern int prioSetBandwidth (int /* fd */, + int /* alloc_type */, + bandwidth_t /* bytes_per_sec */, + pid_t * /* pid */); +extern int prioGetBandwidth (int /* fd */, + bandwidth_t * /* read_bw */, + bandwidth_t * /* write_bw */); +extern int prioLock (pid_t *); +extern int prioUnlock (void); + +/* Error returns */ +#define PRIO_SUCCESS 0 +#define PRIO_FAIL -1 + +#endif /* _ASM_SN_PRIO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/router.h linux-2.4.0-test12-lia/include/asm-ia64/sn/router.h --- linux-2.4.0-test12/include/asm-ia64/sn/router.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/router.h Wed Dec 13 22:29:06 2000 @@ -0,0 +1,17 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_ROUTER_H +#define _ASM_SN_ROUTER_H + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +#include +#endif + +#endif /* _ASM_SN_ROUTER_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sgi.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sgi.h --- linux-2.4.0-test12/include/asm-ia64/sn/sgi.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sgi.h Wed Dec 13 23:51:58 2000 @@ -0,0 +1,237 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +#ifndef _ASM_SN_SGI_H +#define _ASM_SN_SGI_H + +#include +#include /* for copy_??_user */ +#include +#include + +// This devfs stuff needs a better home ..... + +struct directory_type +{ + struct devfs_entry *first; + struct devfs_entry *last; + unsigned int num_removable; +}; + +struct file_type +{ + unsigned long size; +}; + +struct device_type +{ + unsigned short major; + unsigned short minor; +}; + +struct fcb_type /* File, char, block type */ +{ + uid_t default_uid; + gid_t default_gid; + void *ops; + union + { + struct file_type file; + struct device_type device; + } + u; + unsigned char auto_owner:1; + unsigned char aopen_notify:1; + unsigned char removable:1; /* Belongs in device_type, but save space */ + unsigned char open:1; /* Not entirely correct */ +}; + +struct symlink_type +{ + unsigned int length; /* Not including the NULL-termimator */ + char *linkname; /* This is NULL-terminated */ +}; + +struct fifo_type +{ + uid_t uid; + gid_t gid; +}; + +struct devfs_entry +{ + void *info; + union + { + struct directory_type dir; + struct fcb_type fcb; + struct symlink_type symlink; + struct fifo_type fifo; + } + u; + struct devfs_entry *prev; /* Previous entry in the parent directory */ + struct devfs_entry *next; /* Next entry in the parent directory */ + struct devfs_entry *parent; /* The parent directory */ + struct devfs_entry *slave; /* Another entry to unregister */ + struct devfs_inode *first_inode; + struct devfs_inode *last_inode; + umode_t mode; + unsigned short namelen; /* I think 64k+ filenames are a way off... */ + unsigned char registered:1; + unsigned char show_unreg:1; + unsigned char hide:1; + unsigned char no_persistence /*:1*/; + char name[1]; /* This is just a dummy: the allocated array is + bigger. This is NULL-terminated */ +}; + +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) + +typedef uint32_t app32_ptr_t; /* needed by edt.h */ +typedef int64_t __psint_t; /* needed by klgraph.c */ + +typedef enum { B_FALSE, B_TRUE } boolean_t; + +#define ctob(x) ((uint64_t)(x)*NBPC) +#define btoc(x) (((uint64_t)(x)+(NBPC-1))/NBPC) + +typedef __psunsigned_t nic_data_t; + + +/* +** Possible return values from graph routines. +*/ +typedef enum graph_error_e { + GRAPH_SUCCESS, /* 0 */ + GRAPH_DUP, /* 1 */ + GRAPH_NOT_FOUND, /* 2 */ + GRAPH_BAD_PARAM, /* 3 */ + GRAPH_HIT_LIMIT, /* 4 */ + GRAPH_CANNOT_ALLOC, /* 5 */ + GRAPH_ILLEGAL_REQUEST, /* 6 */ + GRAPH_IN_USE /* 7 */ +} graph_error_t; + +#define SV_FIFO 0x0 /* sv_t is FIFO type */ +#define SV_LIFO 0x2 /* sv_t is LIFO type */ +#define SV_PRIO 0x4 /* sv_t is PRIO type */ +#define SV_KEYED 0x6 /* sv_t is KEYED type */ +#define SV_DEFAULT SV_FIFO + + +#define MUTEX_DEFAULT 0x0 /* needed by mutex_init() calls */ +#define PZERO 25 /* needed by mutex_lock(), sv_wait() + * psema() calls */ + +#define sema_t uint64_t /* FIXME */ +#define KM_SLEEP 0x0000 +#define KM_NOSLEEP 0x0001 /* needed by kmem_alloc_node(), kmem_zalloc() + * calls */ +#define VM_NOSLEEP 0x0001 /* needed kmem_alloc_node(), kmem_zalloc_node + * calls */ +#define XG_WIDGET_PART_NUM 0xC102 /* KONA/xt_regs.h XG_XT_PART_NUM_VALUE */ + +#ifndef K1BASE +#define K1BASE 0xA0000000 +#endif + +#ifndef TO_PHYS_MASK +#define TO_PHYS_MASK 0x0000000fffffffff +#endif + +typedef uint64_t vhandl_t; + + +#ifndef NBPP +#define NBPP 4096 +#endif + +#ifndef D_MP +#define D_MP 1 +#endif + +#ifndef MAXDEVNAME +#define MAXDEVNAME 256 +#endif + +#ifndef NBPC +#define NBPC 0 +#endif + +#ifndef _PAGESZ +#define _PAGESZ 4096 +#endif + +typedef uint64_t k_machreg_t; /* needed by cmn_err.h */ + +typedef uint64_t mrlock_t; /* needed by devsupport.c */ + +#define HUB_PIO_CONVEYOR 0x1 +#define CNODEID_NONE (cnodeid_t)-1 +#define XTALK_PCI_PART_NUM "030-1275-" +#define kdebug 0 + + +#define COPYIN(a, b, c) copy_from_user(b,a,c) +#define COPYOUT(a, b, c) copy_to_user(b,a,c) + +#define kvtophys(x) (alenaddr_t) (x) +#define POFFMASK (NBPP - 1) +#define poff(X) ((__psunsigned_t)(X) & POFFMASK) + +#define initnsema(a,b,c) sema_init(a,b) + +#define BZERO(a,b) memset(a, 0, b) + +#define kern_malloc(x) kmalloc(x, GFP_KERNEL) +#define kern_free(x) kfree(x) + +typedef cpuid_t cpu_cookie_t; +#define CPU_NONE -1 + + +#if defined(DISABLE_ASSERT) +#define ASSERT(expr) +#define ASSERT_ALWAYS(expr) +#else +#define ASSERT(expr) \ + if(!(expr)) { \ + printk( "Assertion [%s] failed! %s:%s(line=%d)\n",\ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + panic("Assertion panic\n"); \ + } + +#define ASSERT_ALWAYS(expr) \ + if(!(expr)) { \ + printk( "Assertion [%s] failed! %s:%s(line=%d)\n",\ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + panic("Assertion always panic\n"); \ + } +#endif /* DISABLE_ASSERT */ + +/* These are defined as cmn_err() replacements */ +#define PRINT_WARNING(x...) { printk("WARNING : "); printk(x); } +#define PRINT_NOTICE(x...) { printk("NOTICE : "); printk(x); } +#define PRINT_ALERT(x...) { printk("ALERT : "); printk(x); } +#define PRINT_PANIC panic + +#define mutex_t int +#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name); + +#ifdef CONFIG_SMP +#define cpu_enabled(cpu) (test_bit(cpu, &cpu_online_map)) +#else +#define cpu_enabled(cpu) (1) +#endif + +#include /* for now */ + +#endif /* _ASM_SN_SGI_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/slotnum.h linux-2.4.0-test12-lia/include/asm-ia64/sn/slotnum.h --- linux-2.4.0-test12/include/asm-ia64/sn/slotnum.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/slotnum.h Wed Dec 13 19:35:19 2000 @@ -0,0 +1,23 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SLOTNUM_H +#define _ASM_SN_SLOTNUM_H + +typedef unsigned char slotid_t; + +#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#else + +#error <> + +#endif /* !CONFIG_SGI_IP35 && !CONFIG_IA64_SGI_SN1 */ + +#endif /* _ASM_SN_SLOTNUM_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/addrs.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/addrs.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/addrs.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/addrs.h Wed Dec 13 19:35:00 2000 @@ -0,0 +1,311 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_ADDRS_H +#define _ASM_SN_SN1_ADDRS_H + +/* + * IP35 (on a TRex) Address map + * + * This file contains a set of definitions and macros which are used + * to reference into the major address spaces (CAC, HSPEC, IO, MSPEC, + * and UNCAC) used by the IP35 architecture. It also contains addresses + * for "major" statically locatable PROM/Kernel data structures, such as + * the partition table, the configuration data structure, etc. + * We make an implicit assumption that the processor using this file + * follows the R12K's provisions for specifying uncached attributes; + * should this change, the base registers may very well become processor- + * dependent. + * + * For more information on the address spaces, see the "Local Resources" + * chapter of the Hub specification. + * + * NOTE: This header file is included both by C and by assembler source + * files. Please bracket any language-dependent definitions + * appropriately. + */ + +#include + +/* + * Some of the macros here need to be casted to appropriate types when used + * from C. They definitely must not be casted from assembly language so we + * use some new ANSI preprocessor stuff to paste these on where needed. + */ + +#if defined(_RUN_UNCACHED) +#define CAC_BASE 0x9600000000000000 +#else +#define CAC_BASE 0xa800000000000000 +#endif + +#ifdef Colin +#define HSPEC_BASE 0x9000000000000000 +#define IO_BASE 0x9200000000000000 +#define MSPEC_BASE 0x9400000000000000 +#define UNCAC_BASE 0x9600000000000000 +#else +#define HSPEC_BASE 0xc0000b0000000000 +#define HSPEC_SWIZ_BASE 0xc000030000000000 +#define IO_BASE 0xc0000a0000000000 +#define IO_SWIZ_BASE 0xc000020000000000 +#define MSPEC_BASE 0xc000000000000000 +#define UNCAC_BASE 0xc000000000000000 +#endif + +#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) +#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK)) +#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK)) +#define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK)) +#define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK)) + + +/* + * The following couple of definitions will eventually need to be variables, + * since the amount of address space assigned to each node depends on + * whether the system is running in N-mode (more nodes with less memory) + * or M-mode (fewer nodes with more memory). We expect that it will + * be a while before we need to make this decision dynamically, though, + * so for now we just use defines bracketed by an ifdef. + */ + +#if defined(N_MODE) + +#define NODE_SIZE_BITS 32 +#define BWIN_SIZE_BITS 28 + +#define NASID_BITS 8 +#define NASID_BITMASK (0xffLL) +#define NASID_SHFT 32 +#define NASID_META_BITS 1 +#define NASID_LOCAL_BITS 7 + +#define BDDIR_UPPER_MASK (UINT64_CAST 0x1ffffff << 4) +#define BDECC_UPPER_MASK (UINT64_CAST 0x1fffffff ) + +#else /* !defined(N_MODE), assume that M-mode is desired */ + +#define NODE_SIZE_BITS 33 +#define BWIN_SIZE_BITS 29 + +#define NASID_BITMASK (0x7fLL) +#define NASID_BITS 7 +#define NASID_SHFT 33 +#define NASID_META_BITS 0 +#define NASID_LOCAL_BITS 7 + +#define BDDIR_UPPER_MASK (UINT64_CAST 0x3ffffff << 4) +#define BDECC_UPPER_MASK (UINT64_CAST 0x3fffffff) + +#endif /* defined(N_MODE) */ + +#define NODE_ADDRSPACE_SIZE (UINT64_CAST 1 << NODE_SIZE_BITS) + +#define NASID_MASK (UINT64_CAST NASID_BITMASK << NASID_SHFT) +#define NASID_GET(_pa) (int) ((UINT64_CAST (_pa) >> \ + NASID_SHFT) & NASID_BITMASK) + +#if _LANGUAGE_C && !defined(_STANDALONE) +#ifndef REAL_HARDWARE +#define NODE_SWIN_BASE(nasid, widget) RAW_NODE_SWIN_BASE(nasid, widget) +#else +#define NODE_SWIN_BASE(nasid, widget) \ + ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN) \ + : RAW_NODE_SWIN_BASE(nasid, widget)) +#endif +#else +#define NODE_SWIN_BASE(nasid, widget) \ + (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS)) +#endif /* _LANGUAGE_C */ + +/* + * The following definitions pertain to the IO special address + * space. They define the location of the big and little windows + * of any given node. + */ + +#define BWIN_INDEX_BITS 3 +#define BWIN_SIZE (UINT64_CAST 1 << BWIN_SIZE_BITS) +#define BWIN_SIZEMASK (BWIN_SIZE - 1) +#define BWIN_WIDGET_MASK 0x7 +#define NODE_BWIN_BASE0(nasid) (NODE_IO_BASE(nasid) + BWIN_SIZE) +#define NODE_BWIN_BASE(nasid, bigwin) (NODE_BWIN_BASE0(nasid) + \ + (UINT64_CAST (bigwin) << BWIN_SIZE_BITS)) + +#define BWIN_WIDGETADDR(addr) ((addr) & BWIN_SIZEMASK) +#define BWIN_WINDOWNUM(addr) (((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK) +/* + * Verify if addr belongs to large window address of node with "nasid" + * + * + * NOTE: "addr" is expected to be XKPHYS address, and NOT physical + * address + * + * + */ + +#define NODE_BWIN_ADDR(nasid, addr) \ + (((addr) >= NODE_BWIN_BASE0(nasid)) && \ + ((addr) < (NODE_BWIN_BASE(nasid, HUB_NUM_BIG_WINDOW) + \ + BWIN_SIZE))) + +/* + * The following define the major position-independent aliases used + * in IP27. + * CALIAS -- Varies in size, points to the first n bytes of memory + * on the reader's node. + */ + +#define CALIAS_BASE CAC_BASE + + + +#define BRIDGE_REG_PTR(_base, _off) ((volatile bridgereg_t *) \ + ((__psunsigned_t)(_base) + (__psunsigned_t)(_off))) + +#define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid))) + +#if _LANGUAGE_C +#define KERN_NMI_ADDR(nasid, slice) \ + TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + \ + (IP27_NMI_KREGS_CPU_SIZE * (slice))) +#endif /* _LANGUAGE_C */ + + +/* + * needed by symmon so it needs to be outside #if PROM + * (see also POD_ELSCSIZE) + */ +#define IP27PROM_ELSC_BASE_A PHYS_TO_K0(0x020e0000) +#define IP27PROM_ELSC_BASE_B PHYS_TO_K0(0x020e0800) +#define IP27PROM_ELSC_BASE_C PHYS_TO_K0(0x020e1000) +#define IP27PROM_ELSC_BASE_D PHYS_TO_K0(0x020e1800) +#define IP27PROM_ELSC_SHFT 11 +#define IP27PROM_ELSC_SIZE (1 << IP27PROM_ELSC_SHFT) + +#define FREEMEM_BASE PHYS_TO_K0(0x4000000) + +#define IO6PROM_STACK_SHFT 14 /* stack per cpu */ +#define IO6PROM_STACK_SIZE (1 << IO6PROM_STACK_SHFT) + + +#define KL_UART_BASE LOCAL_HSPEC(HSPEC_UART_0) /* base of UART regs */ +#define KL_UART_CMD LOCAL_HSPEC(HSPEC_UART_0) /* UART command reg */ +#define KL_UART_DATA LOCAL_HSPEC(HSPEC_UART_1) /* UART data reg */ + +#if !_LANGUAGE_ASSEMBLY +/* Address 0x400 to 0x1000 ualias points to cache error eframe + misc + * CACHE_ERR_SP_PTR could either contain an address to the stack, or + * the stack could start at CACHE_ERR_SP_PTR + */ +#define CACHE_ERR_EFRAME 0x400 + +#define CACHE_ERR_ECCFRAME (CACHE_ERR_EFRAME + EF_SIZE) +#define CACHE_ERR_SP_PTR (0x1000 - 32) /* why -32? TBD */ +#define CACHE_ERR_IBASE_PTR (0x1000 - 40) +#define CACHE_ERR_SP (CACHE_ERR_SP_PTR - 16) +#define CACHE_ERR_AREA_SIZE (ARCS_SPB_OFFSET - CACHE_ERR_EFRAME) + +#endif /* !_LANGUAGE_ASSEMBLY */ + +/* Each CPU accesses UALIAS at a different physaddr, on 32k boundaries + * This determines the locations of the exception vectors + */ +#define UALIAS_FLIP_BASE UALIAS_BASE +#define UALIAS_FLIP_SHIFT 15 +#define UALIAS_FLIP_ADDR(_x) ((_x) ^ (cputoslice(getcpuid())<Key field is used for this purpose. + * Macros needed by IP27 device drivers to convert the + * COMPONENT->Key field to the respective base address. + * Key field looks as follows: + * + * +----------------------------------------------------+ + * |devnasid | widget |pciid |hubwidid|hstnasid | adap | + * | 2 | 1 | 1 | 1 | 2 | 1 | + * +----------------------------------------------------+ + * | | | | | | | + * 64 48 40 32 24 8 0 + * + * These are used by standalone drivers till the io infrastructure + * is in place. + */ + +#if _LANGUAGE_C + +#define uchar unsigned char + +#define KEY_DEVNASID_SHFT 48 +#define KEY_WIDID_SHFT 40 +#define KEY_PCIID_SHFT 32 +#define KEY_HUBWID_SHFT 24 +#define KEY_HSTNASID_SHFT 8 + +#define MK_SN0_KEY(nasid, widid, pciid) \ + ((((__psunsigned_t)nasid)<< KEY_DEVNASID_SHFT |\ + ((__psunsigned_t)widid) << KEY_WIDID_SHFT) |\ + ((__psunsigned_t)pciid) << KEY_PCIID_SHFT) + +#define ADD_HUBWID_KEY(key,hubwid)\ + (key|=((__psunsigned_t)hubwid << KEY_HUBWID_SHFT)) + +#define ADD_HSTNASID_KEY(key,hstnasid)\ + (key|=((__psunsigned_t)hstnasid << KEY_HSTNASID_SHFT)) + +#define GET_DEVNASID_FROM_KEY(key) ((short)(key >> KEY_DEVNASID_SHFT)) +#define GET_WIDID_FROM_KEY(key) ((uchar)(key >> KEY_WIDID_SHFT)) +#define GET_PCIID_FROM_KEY(key) ((uchar)(key >> KEY_PCIID_SHFT)) +#define GET_HUBWID_FROM_KEY(key) ((uchar)(key >> KEY_HUBWID_SHFT)) +#define GET_HSTNASID_FROM_KEY(key) ((short)(key >> KEY_HSTNASID_SHFT)) + +#define PCI_64_TARGID_SHFT 60 + +#define GET_PCIBASE_FROM_KEY(key) (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\ + GET_WIDID_FROM_KEY(key))\ + | BRIDGE_DEVIO(GET_PCIID_FROM_KEY(key))) + +#define GET_PCICFGBASE_FROM_KEY(key) \ + (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\ + GET_WIDID_FROM_KEY(key))\ + | BRIDGE_TYPE0_CFG_DEV(GET_PCIID_FROM_KEY(key))) + +#define GET_WIDBASE_FROM_KEY(key) \ + (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\ + GET_WIDID_FROM_KEY(key))) + +#define PUT_INSTALL_STATUS(c,s) c->Revision = s +#define GET_INSTALL_STATUS(c) c->Revision + +#endif /* LANGUAGE_C */ + +#endif /* _STANDALONE */ + +#endif /* _ASM_SN_SN1_ADDRS_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/arch.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/arch.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/arch.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/arch.h Wed Dec 6 21:56:11 2000 @@ -0,0 +1,81 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_ARCH_H +#define _ASM_SN_SN1_ARCH_H + +#if defined(N_MODE) +#error "ERROR constants defined only for M-mode" +#endif + +#include + +/* + * This is the maximum number of NASIDS that can be present in a system. + * (Highest NASID plus one.) + */ +#define MAX_NASIDS 128 + +/* + * MAXCPUS refers to the maximum number of CPUs in a single kernel. + * This is not necessarily the same as MAXNODES * CPUS_PER_NODE + */ +#define MAXCPUS 512 + +/* + * This is the maximum number of nodes that can be part of a kernel. + * Effectively, it's the maximum number of compact node ids (cnodeid_t). + * This is not necessarily the same as MAX_NASIDS. + */ +#define MAX_COMPACT_NODES 128 + +/* + * MAX_REGIONS refers to the maximum number of hardware partitioned regions. + */ +#define MAX_REGIONS 64 +#define MAX_NONPREMIUM_REGIONS 16 +#define MAX_PREMIUM_REGIONS MAX_REGIONS + + +/* + * MAX_PARITIONS refers to the maximum number of logically defined + * partitions the system can support. + */ +#define MAX_PARTITIONS MAX_REGIONS + + +#define NASID_MASK_BYTES ((MAX_NASIDS + 7) / 8) + +/* + * Slot constants for IP35 + */ + +#define MAX_MEM_SLOTS 8 /* max slots per node */ + +#if defined(N_MODE) +#error "N-mode not supported" +#endif + +#define SLOT_SHIFT (30) +#define SLOT_MIN_MEM_SIZE (64*1024*1024) + +/* + * two PIs per bedrock, two CPUs per PI + */ +#define NUM_SUBNODES 2 +#define SUBNODE_SHFT 1 +#define SUBNODE_MASK (0x1 << SUBNODE_SHFT) +#define LOCALCPU_SHFT 0 +#define LOCALCPU_MASK (0x1 << LOCALCPU_SHFT) +#define SUBNODE(slice) (((slice) & SUBNODE_MASK) >> SUBNODE_SHFT) +#define LOCALCPU(slice) (((slice) & LOCALCPU_MASK) >> LOCALCPU_SHFT) +#define TO_SLICE(subn, local) (((subn) << SUBNODE_SHFT) | \ + ((local) << LOCALCPU_SHFT)) + +#endif /* _ASM_SN_SN1_ARCH_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/bedrock.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/bedrock.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/bedrock.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/bedrock.h Wed Dec 13 23:52:11 2000 @@ -0,0 +1,81 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_BEDROCK_H +#define _ASM_SN_SN1_BEDROCK_H + +/* The secret password; used to release protection */ +#define HUB_PASSWORD 0x53474972756c6573ull + +#define CHIPID_HUB 0x3012 +#define CHIPID_ROUTER 0x3017 + +#define BEDROCK_REV_1_0 1 +#define BEDROCK_REV_1_1 2 + +#define MAX_HUB_PATH 80 + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else /* ! CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */ + +<< BOMB! CONFIG_SGI_IP35 is only defined for IP35 >> + +#endif /* defined(CONFIG_SGI_IP35) */ + +/* Translation of uncached attributes */ +#define UATTR_HSPEC 0 +#define UATTR_IO 1 +#define UATTR_MSPEC 2 +#define UATTR_UNCAC 3 + +#if _LANGUAGE_ASSEMBLY + +/* + * Get nasid into register, r (uses at) + */ +#define GET_NASID_ASM(r) \ + dli r, LOCAL_HUB_ADDR(LB_REV_ID); \ + ld r, (r); \ + and r, LRI_NODEID_MASK; \ + dsrl r, LRI_NODEID_SHFT + +#endif /* _LANGUAGE_ASSEMBLY */ + +#if _LANGUAGE_C + +#include + +/* hub-as-widget iograph info, labelled by INFO_LBL_XWIDGET */ +typedef struct v_hub_s *v_hub_t; +typedef uint64_t rtc_time_t; + +struct nodepda_s; +int hub_check_pci_equiv(void *addra, void *addrb); +void capture_hub_stats(cnodeid_t, struct nodepda_s *); +void init_hub_stats(cnodeid_t, struct nodepda_s *); + +#endif /* _LANGUAGE_C */ + +#endif /* _ASM_SN_SN1_BEDROCK_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubdev.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubdev.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubdev.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubdev.h Wed Dec 6 21:56:11 2000 @@ -0,0 +1,22 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_HUBDEV_H +#define _ASM_SN_SN1_HUBDEV_H + +extern void hubdev_init(void); +extern void hubdev_register(int (*attach_method)(devfs_handle_t)); +extern int hubdev_unregister(int (*attach_method)(devfs_handle_t)); +extern int hubdev_docallouts(devfs_handle_t hub); + +extern caddr_t hubdev_prombase_get(devfs_handle_t hub); +extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub); + +#endif /* _ASM_SN_SN1_HUBDEV_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubio.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubio.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubio.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubio.h Wed Dec 6 21:56:12 2000 @@ -0,0 +1,5017 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/************************************************************************ + * * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! * + * * + * This file is created by an automated script. Any (minimal) changes * + * made manually to this file should be made with care. * + * * + * MAKE ALL ADDITIONS TO THE END OF THIS FILE * + * * + ************************************************************************/ + + +#ifndef _ASM_SN_SN1_HUBIO_H +#define _ASM_SN_SN1_HUBIO_H + + +#define IIO_WID 0x00400000 /* + * Crosstalk Widget + * Identification This + * register is also + * accessible from + * Crosstalk at + * address 0x0. + */ + + + +#define IIO_WSTAT 0x00400008 /* + * Crosstalk Widget + * Status + */ + + + +#define IIO_WCR 0x00400020 /* + * Crosstalk Widget + * Control Register + */ + + + +#define IIO_ILAPR 0x00400100 /* + * IO Local Access + * Protection Register + */ + + + +#define IIO_ILAPO 0x00400108 /* + * IO Local Access + * Protection Override + */ + + + +#define IIO_IOWA 0x00400110 /* + * IO Outbound Widget + * Access + */ + + + +#define IIO_IIWA 0x00400118 /* + * IO Inbound Widget + * Access + */ + + + +#define IIO_IIDEM 0x00400120 /* + * IO Inbound Device + * Error Mask + */ + + + +#define IIO_ILCSR 0x00400128 /* + * IO LLP Control and + * Status Register + */ + + + +#define IIO_ILLR 0x00400130 /* IO LLP Log Register */ + + + +#define IIO_IIDSR 0x00400138 /* + * IO Interrupt + * Destination + */ + + + +#define IIO_IGFX0 0x00400140 /* + * IO Graphics + * Node-Widget Map 0 + */ + + + +#define IIO_IGFX1 0x00400148 /* + * IO Graphics + * Node-Widget Map 1 + */ + + + +#define IIO_ISCR0 0x00400150 /* + * IO Scratch Register + * 0 + */ + + + +#define IIO_ISCR1 0x00400158 /* + * IO Scratch Register + * 1 + */ + + + +#define IIO_ITTE1 0x00400160 /* + * IO Translation + * Table Entry 1 + */ + + + +#define IIO_ITTE2 0x00400168 /* + * IO Translation + * Table Entry 2 + */ + + + +#define IIO_ITTE3 0x00400170 /* + * IO Translation + * Table Entry 3 + */ + + + +#define IIO_ITTE4 0x00400178 /* + * IO Translation + * Table Entry 4 + */ + + + +#define IIO_ITTE5 0x00400180 /* + * IO Translation + * Table Entry 5 + */ + + + +#define IIO_ITTE6 0x00400188 /* + * IO Translation + * Table Entry 6 + */ + + + +#define IIO_ITTE7 0x00400190 /* + * IO Translation + * Table Entry 7 + */ + + + +#define IIO_IPRB0 0x00400198 /* IO PRB Entry 0 */ + + + +#define IIO_IPRB8 0x004001A0 /* IO PRB Entry 8 */ + + + +#define IIO_IPRB9 0x004001A8 /* IO PRB Entry 9 */ + + + +#define IIO_IPRBA 0x004001B0 /* IO PRB Entry A */ + + + +#define IIO_IPRBB 0x004001B8 /* IO PRB Entry B */ + + + +#define IIO_IPRBC 0x004001C0 /* IO PRB Entry C */ + + + +#define IIO_IPRBD 0x004001C8 /* IO PRB Entry D */ + + + +#define IIO_IPRBE 0x004001D0 /* IO PRB Entry E */ + + + +#define IIO_IPRBF 0x004001D8 /* IO PRB Entry F */ + + + +#define IIO_IXCC 0x004001E0 /* + * IO Crosstalk Credit + * Count Timeout + */ + + + +#define IIO_IMEM 0x004001E8 /* + * IO Miscellaneous + * Error Mask + */ + + + +#define IIO_IXTT 0x004001F0 /* + * IO Crosstalk + * Timeout Threshold + */ + + + +#define IIO_IECLR 0x004001F8 /* + * IO Error Clear + * Register + */ + + + +#define IIO_IBCR 0x00400200 /* + * IO BTE Control + * Register + */ + + + +#define IIO_IXSM 0x00400208 /* + * IO Crosstalk + * Spurious Message + */ + + + +#define IIO_IXSS 0x00400210 /* + * IO Crosstalk + * Spurious Sideband + */ + + + +#define IIO_ILCT 0x00400218 /* IO LLP Channel Test */ + + + +#define IIO_IIEPH1 0x00400220 /* + * IO Incoming Error + * Packet Header, Part + * 1 + */ + + + +#define IIO_IIEPH2 0x00400228 /* + * IO Incoming Error + * Packet Header, Part + * 2 + */ + + + +#define IIO_IPCA 0x00400300 /* + * IO PRB Counter + * Adjust + */ + + + +#define IIO_IPRTE0 0x00400308 /* + * IO PIO Read Address + * Table Entry 0 + */ + + + +#define IIO_IPRTE1 0x00400310 /* + * IO PIO Read Address + * Table Entry 1 + */ + + + +#define IIO_IPRTE2 0x00400318 /* + * IO PIO Read Address + * Table Entry 2 + */ + + + +#define IIO_IPRTE3 0x00400320 /* + * IO PIO Read Address + * Table Entry 3 + */ + + + +#define IIO_IPRTE4 0x00400328 /* + * IO PIO Read Address + * Table Entry 4 + */ + + + +#define IIO_IPRTE5 0x00400330 /* + * IO PIO Read Address + * Table Entry 5 + */ + + + +#define IIO_IPRTE6 0x00400338 /* + * IO PIO Read Address + * Table Entry 6 + */ + + + +#define IIO_IPRTE7 0x00400340 /* + * IO PIO Read Address + * Table Entry 7 + */ + + + +#define IIO_IPDR 0x00400388 /* + * IO PIO Deallocation + * Register + */ + + + +#define IIO_ICDR 0x00400390 /* + * IO CRB Entry + * Deallocation + * Register + */ + + + +#define IIO_IFDR 0x00400398 /* + * IO IOQ FIFO Depth + * Register + */ + + + +#define IIO_IIAP 0x004003A0 /* + * IO IIQ Arbitration + * Parameters + */ + + + +#define IIO_ICMR 0x004003A8 /* + * IO CRB Management + * Register + */ + + + +#define IIO_ICCR 0x004003B0 /* + * IO CRB Control + * Register + */ + + + +#define IIO_ICTO 0x004003B8 /* IO CRB Timeout */ + + + +#define IIO_ICTP 0x004003C0 /* + * IO CRB Timeout + * Prescalar + */ + + + +#define IIO_ICRB0_A 0x00400400 /* IO CRB Entry 0_A */ + + + +#define IIO_ICRB0_B 0x00400408 /* IO CRB Entry 0_B */ + + + +#define IIO_ICRB0_C 0x00400410 /* IO CRB Entry 0_C */ + + + +#define IIO_ICRB0_D 0x00400418 /* IO CRB Entry 0_D */ + + + +#define IIO_ICRB1_A 0x00400420 /* IO CRB Entry 1_A */ + + + +#define IIO_ICRB1_B 0x00400428 /* IO CRB Entry 1_B */ + + + +#define IIO_ICRB1_C 0x00400430 /* IO CRB Entry 1_C */ + + + +#define IIO_ICRB1_D 0x00400438 /* IO CRB Entry 1_D */ + + + +#define IIO_ICRB2_A 0x00400440 /* IO CRB Entry 2_A */ + + + +#define IIO_ICRB2_B 0x00400448 /* IO CRB Entry 2_B */ + + + +#define IIO_ICRB2_C 0x00400450 /* IO CRB Entry 2_C */ + + + +#define IIO_ICRB2_D 0x00400458 /* IO CRB Entry 2_D */ + + + +#define IIO_ICRB3_A 0x00400460 /* IO CRB Entry 3_A */ + + + +#define IIO_ICRB3_B 0x00400468 /* IO CRB Entry 3_B */ + + + +#define IIO_ICRB3_C 0x00400470 /* IO CRB Entry 3_C */ + + + +#define IIO_ICRB3_D 0x00400478 /* IO CRB Entry 3_D */ + + + +#define IIO_ICRB4_A 0x00400480 /* IO CRB Entry 4_A */ + + + +#define IIO_ICRB4_B 0x00400488 /* IO CRB Entry 4_B */ + + + +#define IIO_ICRB4_C 0x00400490 /* IO CRB Entry 4_C */ + + + +#define IIO_ICRB4_D 0x00400498 /* IO CRB Entry 4_D */ + + + +#define IIO_ICRB5_A 0x004004A0 /* IO CRB Entry 5_A */ + + + +#define IIO_ICRB5_B 0x004004A8 /* IO CRB Entry 5_B */ + + + +#define IIO_ICRB5_C 0x004004B0 /* IO CRB Entry 5_C */ + + + +#define IIO_ICRB5_D 0x004004B8 /* IO CRB Entry 5_D */ + + + +#define IIO_ICRB6_A 0x004004C0 /* IO CRB Entry 6_A */ + + + +#define IIO_ICRB6_B 0x004004C8 /* IO CRB Entry 6_B */ + + + +#define IIO_ICRB6_C 0x004004D0 /* IO CRB Entry 6_C */ + + + +#define IIO_ICRB6_D 0x004004D8 /* IO CRB Entry 6_D */ + + + +#define IIO_ICRB7_A 0x004004E0 /* IO CRB Entry 7_A */ + + + +#define IIO_ICRB7_B 0x004004E8 /* IO CRB Entry 7_B */ + + + +#define IIO_ICRB7_C 0x004004F0 /* IO CRB Entry 7_C */ + + + +#define IIO_ICRB7_D 0x004004F8 /* IO CRB Entry 7_D */ + + + +#define IIO_ICRB8_A 0x00400500 /* IO CRB Entry 8_A */ + + + +#define IIO_ICRB8_B 0x00400508 /* IO CRB Entry 8_B */ + + + +#define IIO_ICRB8_C 0x00400510 /* IO CRB Entry 8_C */ + + + +#define IIO_ICRB8_D 0x00400518 /* IO CRB Entry 8_D */ + + + +#define IIO_ICRB9_A 0x00400520 /* IO CRB Entry 9_A */ + + + +#define IIO_ICRB9_B 0x00400528 /* IO CRB Entry 9_B */ + + + +#define IIO_ICRB9_C 0x00400530 /* IO CRB Entry 9_C */ + + + +#define IIO_ICRB9_D 0x00400538 /* IO CRB Entry 9_D */ + + + +#define IIO_ICRBA_A 0x00400540 /* IO CRB Entry A_A */ + + + +#define IIO_ICRBA_B 0x00400548 /* IO CRB Entry A_B */ + + + +#define IIO_ICRBA_C 0x00400550 /* IO CRB Entry A_C */ + + + +#define IIO_ICRBA_D 0x00400558 /* IO CRB Entry A_D */ + + + +#define IIO_ICRBB_A 0x00400560 /* IO CRB Entry B_A */ + + + +#define IIO_ICRBB_B 0x00400568 /* IO CRB Entry B_B */ + + + +#define IIO_ICRBB_C 0x00400570 /* IO CRB Entry B_C */ + + + +#define IIO_ICRBB_D 0x00400578 /* IO CRB Entry B_D */ + + + +#define IIO_ICRBC_A 0x00400580 /* IO CRB Entry C_A */ + + + +#define IIO_ICRBC_B 0x00400588 /* IO CRB Entry C_B */ + + + +#define IIO_ICRBC_C 0x00400590 /* IO CRB Entry C_C */ + + + +#define IIO_ICRBC_D 0x00400598 /* IO CRB Entry C_D */ + + + +#define IIO_ICRBD_A 0x004005A0 /* IO CRB Entry D_A */ + + + +#define IIO_ICRBD_B 0x004005A8 /* IO CRB Entry D_B */ + + + +#define IIO_ICRBD_C 0x004005B0 /* IO CRB Entry D_C */ + + + +#define IIO_ICRBD_D 0x004005B8 /* IO CRB Entry D_D */ + + + +#define IIO_ICRBE_A 0x004005C0 /* IO CRB Entry E_A */ + + + +#define IIO_ICRBE_B 0x004005C8 /* IO CRB Entry E_B */ + + + +#define IIO_ICRBE_C 0x004005D0 /* IO CRB Entry E_C */ + + + +#define IIO_ICRBE_D 0x004005D8 /* IO CRB Entry E_D */ + + + +#define IIO_ICSML 0x00400600 /* + * IO CRB Spurious + * Message Low + */ + + + +#define IIO_ICSMH 0x00400608 /* + * IO CRB Spurious + * Message High + */ + + + +#define IIO_IDBSS 0x00400610 /* + * IO Debug Submenu + * Select + */ + + + +#define IIO_IBLS0 0x00410000 /* + * IO BTE Length + * Status 0 + */ + + + +#define IIO_IBSA0 0x00410008 /* + * IO BTE Source + * Address 0 + */ + + + +#define IIO_IBDA0 0x00410010 /* + * IO BTE Destination + * Address 0 + */ + + + +#define IIO_IBCT0 0x00410018 /* + * IO BTE Control + * Terminate 0 + */ + + + +#define IIO_IBNA0 0x00410020 /* + * IO BTE Notification + * Address 0 + */ + + + +#define IIO_IBIA0 0x00410028 /* + * IO BTE Interrupt + * Address 0 + */ + + + +#define IIO_IBLS1 0x00420000 /* + * IO BTE Length + * Status 1 + */ + + + +#define IIO_IBSA1 0x00420008 /* + * IO BTE Source + * Address 1 + */ + + + +#define IIO_IBDA1 0x00420010 /* + * IO BTE Destination + * Address 1 + */ + + + +#define IIO_IBCT1 0x00420018 /* + * IO BTE Control + * Terminate 1 + */ + + + +#define IIO_IBNA1 0x00420020 /* + * IO BTE Notification + * Address 1 + */ + + + +#define IIO_IBIA1 0x00420028 /* + * IO BTE Interrupt + * Address 1 + */ + + + +#define IIO_IPCR 0x00430000 /* + * IO Performance + * Control + */ + + + +#define IIO_IPPR 0x00430008 /* + * IO Performance + * Profiling + */ + + + + + +#ifdef _LANGUAGE_C + +/************************************************************************ + * * + * Description: This register echoes some information from the * + * LB_REV_ID register. It is available through Crosstalk as described * + * above. The REV_NUM and MFG_NUM fields receive their values from * + * the REVISION and MANUFACTURER fields in the LB_REV_ID register. * + * The PART_NUM field's value is the Crosstalk device ID number that * + * Steve Miller assigned to the Bedrock chip. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_wid_u { + bdrkreg_t ii_wid_regval; + struct { + bdrkreg_t w_rsvd_1 : 1; + bdrkreg_t w_mfg_num : 11; + bdrkreg_t w_part_num : 16; + bdrkreg_t w_rev_num : 4; + bdrkreg_t w_rsvd : 32; + } ii_wid_fld_s; +} ii_wid_u_t; + +#else + +typedef union ii_wid_u { + bdrkreg_t ii_wid_regval; + struct { + bdrkreg_t w_rsvd : 32; + bdrkreg_t w_rev_num : 4; + bdrkreg_t w_part_num : 16; + bdrkreg_t w_mfg_num : 11; + bdrkreg_t w_rsvd_1 : 1; + } ii_wid_fld_s; +} ii_wid_u_t; + +#endif + + + + +/************************************************************************ + * * + * The fields in this register are set upon detection of an error * + * and cleared by various mechanisms, as explained in the * + * description. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_wstat_u { + bdrkreg_t ii_wstat_regval; + struct { + bdrkreg_t w_pending : 4; + bdrkreg_t w_xt_crd_to : 1; + bdrkreg_t w_xt_tail_to : 1; + bdrkreg_t w_rsvd_3 : 3; + bdrkreg_t w_tx_mx_rty : 1; + bdrkreg_t w_rsvd_2 : 6; + bdrkreg_t w_llp_tx_cnt : 8; + bdrkreg_t w_rsvd_1 : 8; + bdrkreg_t w_crazy : 1; + bdrkreg_t w_rsvd : 31; + } ii_wstat_fld_s; +} ii_wstat_u_t; + +#else + +typedef union ii_wstat_u { + bdrkreg_t ii_wstat_regval; + struct { + bdrkreg_t w_rsvd : 31; + bdrkreg_t w_crazy : 1; + bdrkreg_t w_rsvd_1 : 8; + bdrkreg_t w_llp_tx_cnt : 8; + bdrkreg_t w_rsvd_2 : 6; + bdrkreg_t w_tx_mx_rty : 1; + bdrkreg_t w_rsvd_3 : 3; + bdrkreg_t w_xt_tail_to : 1; + bdrkreg_t w_xt_crd_to : 1; + bdrkreg_t w_pending : 4; + } ii_wstat_fld_s; +} ii_wstat_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This is a read-write enabled register. It controls * + * various aspects of the Crosstalk flow control. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_wcr_u { + bdrkreg_t ii_wcr_regval; + struct { + bdrkreg_t w_wid : 4; + bdrkreg_t w_tag : 1; + bdrkreg_t w_rsvd_1 : 8; + bdrkreg_t w_dst_crd : 3; + bdrkreg_t w_f_bad_pkt : 1; + bdrkreg_t w_dir_con : 1; + bdrkreg_t w_e_thresh : 5; + bdrkreg_t w_rsvd : 41; + } ii_wcr_fld_s; +} ii_wcr_u_t; + +#else + +typedef union ii_wcr_u { + bdrkreg_t ii_wcr_regval; + struct { + bdrkreg_t w_rsvd : 41; + bdrkreg_t w_e_thresh : 5; + bdrkreg_t w_dir_con : 1; + bdrkreg_t w_f_bad_pkt : 1; + bdrkreg_t w_dst_crd : 3; + bdrkreg_t w_rsvd_1 : 8; + bdrkreg_t w_tag : 1; + bdrkreg_t w_wid : 4; + } ii_wcr_fld_s; +} ii_wcr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register's value is a bit vector that guards * + * access to local registers within the II as well as to external * + * Crosstalk widgets. Each bit in the register corresponds to a * + * particular region in the system; a region consists of one, two or * + * four nodes (depending on the value of the REGION_SIZE field in the * + * LB_REV_ID register, which is documented in Section 8.3.1.1). The * + * protection provided by this register applies to PIO read * + * operations as well as PIO write operations. The II will perform a * + * PIO read or write request only if the bit for the requestor's * + * region is set; otherwise, the II will not perform the requested * + * operation and will return an error response. When a PIO read or * + * write request targets an external Crosstalk widget, then not only * + * must the bit for the requestor's region be set in the ILAPR, but * + * also the target widget's bit in the IOWA register must be set in * + * order for the II to perform the requested operation; otherwise, * + * the II will return an error response. Hence, the protection * + * provided by the IOWA register supplements the protection provided * + * by the ILAPR for requests that target external Crosstalk widgets. * + * This register itself can be accessed only by the nodes whose * + * region ID bits are enabled in this same register. It can also be * + * accessed through the IAlias space by the local processors. * + * The reset value of this register allows access by all nodes. * + * * + ************************************************************************/ + + + + +typedef union ii_ilapr_u { + bdrkreg_t ii_ilapr_regval; + struct { + bdrkreg_t i_region : 64; + } ii_ilapr_fld_s; +} ii_ilapr_u_t; + + + + +/************************************************************************ + * * + * Description: A write to this register of the 64-bit value * + * "SGIrules" in ASCII, will cause the bit in the ILAPR register * + * corresponding to the region of the requestor to be set (allow * + * access). A write of any other value will be ignored. Access * + * protection for this register is "SGIrules". * + * This register can also be accessed through the IAlias space. * + * However, this access will not change the access permissions in the * + * ILAPR. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ilapo_u { + bdrkreg_t ii_ilapo_regval; + struct { + bdrkreg_t i_io_ovrride : 9; + bdrkreg_t i_rsvd : 55; + } ii_ilapo_fld_s; +} ii_ilapo_u_t; + +#else + +typedef union ii_ilapo_u { + bdrkreg_t ii_ilapo_regval; + struct { + bdrkreg_t i_rsvd : 55; + bdrkreg_t i_io_ovrride : 9; + } ii_ilapo_fld_s; +} ii_ilapo_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register qualifies all the PIO and Graphics writes launched * + * from the Bedrock towards a widget. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iowa_u { + bdrkreg_t ii_iowa_regval; + struct { + bdrkreg_t i_w0_oac : 1; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_wx_oac : 8; + bdrkreg_t i_rsvd : 48; + } ii_iowa_fld_s; +} ii_iowa_u_t; + +#else + +typedef union ii_iowa_u { + bdrkreg_t ii_iowa_regval; + struct { + bdrkreg_t i_rsvd : 48; + bdrkreg_t i_wx_oac : 8; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_w0_oac : 1; + } ii_iowa_fld_s; +} ii_iowa_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register qualifies all the requests launched * + * from a widget towards the Bedrock. This register is intended to be * + * used by software in case of misbehaving widgets. * + * * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iiwa_u { + bdrkreg_t ii_iiwa_regval; + struct { + bdrkreg_t i_w0_iac : 1; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_wx_iac : 8; + bdrkreg_t i_rsvd : 48; + } ii_iiwa_fld_s; +} ii_iiwa_u_t; + +#else + +typedef union ii_iiwa_u { + bdrkreg_t ii_iiwa_regval; + struct { + bdrkreg_t i_rsvd : 48; + bdrkreg_t i_wx_iac : 8; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_w0_iac : 1; + } ii_iiwa_fld_s; +} ii_iiwa_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register qualifies all the operations launched * + * from a widget towards the Bedrock. It allows individual access * + * control for up to 8 devices per widget. A device refers to * + * individual DMA master hosted by a widget. * + * The bits in each field of this register are cleared by the Bedrock * + * upon detection of an error which requires the device to be * + * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric * + * Crosstalk). Whether or not a device has access rights to this * + * Bedrock is determined by an AND of the device enable bit in the * + * appropriate field of this register and the corresponding bit in * + * the Wx_IAC field (for the widget which this device belongs to). * + * The bits in this field are set by writing a 1 to them. Incoming * + * replies from Crosstalk are not subject to this access control * + * mechanism. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iidem_u { + bdrkreg_t ii_iidem_regval; + struct { + bdrkreg_t i_w8_dxs : 8; + bdrkreg_t i_w9_dxs : 8; + bdrkreg_t i_wa_dxs : 8; + bdrkreg_t i_wb_dxs : 8; + bdrkreg_t i_wc_dxs : 8; + bdrkreg_t i_wd_dxs : 8; + bdrkreg_t i_we_dxs : 8; + bdrkreg_t i_wf_dxs : 8; + } ii_iidem_fld_s; +} ii_iidem_u_t; + +#else + +typedef union ii_iidem_u { + bdrkreg_t ii_iidem_regval; + struct { + bdrkreg_t i_wf_dxs : 8; + bdrkreg_t i_we_dxs : 8; + bdrkreg_t i_wd_dxs : 8; + bdrkreg_t i_wc_dxs : 8; + bdrkreg_t i_wb_dxs : 8; + bdrkreg_t i_wa_dxs : 8; + bdrkreg_t i_w9_dxs : 8; + bdrkreg_t i_w8_dxs : 8; + } ii_iidem_fld_s; +} ii_iidem_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the various programmable fields necessary * + * for controlling and observing the LLP signals. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ilcsr_u { + bdrkreg_t ii_ilcsr_regval; + struct { + bdrkreg_t i_nullto : 6; + bdrkreg_t i_rsvd_4 : 2; + bdrkreg_t i_wrmrst : 1; + bdrkreg_t i_rsvd_3 : 1; + bdrkreg_t i_llp_en : 1; + bdrkreg_t i_bm8 : 1; + bdrkreg_t i_llp_stat : 2; + bdrkreg_t i_remote_power : 1; + bdrkreg_t i_rsvd_2 : 1; + bdrkreg_t i_maxrtry : 10; + bdrkreg_t i_d_avail_sel : 2; + bdrkreg_t i_rsvd_1 : 4; + bdrkreg_t i_maxbrst : 10; + bdrkreg_t i_rsvd : 22; + + } ii_ilcsr_fld_s; +} ii_ilcsr_u_t; + +#else + +typedef union ii_ilcsr_u { + bdrkreg_t ii_ilcsr_regval; + struct { + bdrkreg_t i_rsvd : 22; + bdrkreg_t i_maxbrst : 10; + bdrkreg_t i_rsvd_1 : 4; + bdrkreg_t i_d_avail_sel : 2; + bdrkreg_t i_maxrtry : 10; + bdrkreg_t i_rsvd_2 : 1; + bdrkreg_t i_remote_power : 1; + bdrkreg_t i_llp_stat : 2; + bdrkreg_t i_bm8 : 1; + bdrkreg_t i_llp_en : 1; + bdrkreg_t i_rsvd_3 : 1; + bdrkreg_t i_wrmrst : 1; + bdrkreg_t i_rsvd_4 : 2; + bdrkreg_t i_nullto : 6; + } ii_ilcsr_fld_s; +} ii_ilcsr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This is simply a status registers that monitors the LLP error * + * rate. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_illr_u { + bdrkreg_t ii_illr_regval; + struct { + bdrkreg_t i_sn_cnt : 16; + bdrkreg_t i_cb_cnt : 16; + bdrkreg_t i_rsvd : 32; + } ii_illr_fld_s; +} ii_illr_u_t; + +#else + +typedef union ii_illr_u { + bdrkreg_t ii_illr_regval; + struct { + bdrkreg_t i_rsvd : 32; + bdrkreg_t i_cb_cnt : 16; + bdrkreg_t i_sn_cnt : 16; + } ii_illr_fld_s; +} ii_illr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: All II-detected non-BTE error interrupts are * + * specified via this register. * + * NOTE: The PI interrupt register address is hardcoded in the II. If * + * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI * + * packet) to address offset 0x0180_0090 within the local register * + * address space of PI0 on the node specified by the NODE field. If * + * PI_ID==1, then the II sends the interrupt request to address * + * offset 0x01A0_0090 within the local register address space of PI1 * + * on the node specified by the NODE field. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iidsr_u { + bdrkreg_t ii_iidsr_regval; + struct { + bdrkreg_t i_level : 7; + bdrkreg_t i_rsvd_4 : 1; + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_node : 8; + bdrkreg_t i_rsvd_3 : 7; + bdrkreg_t i_enable : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_int_sent : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_pi0_forward_int : 1; + bdrkreg_t i_pi1_forward_int : 1; + bdrkreg_t i_rsvd : 30; + } ii_iidsr_fld_s; +} ii_iidsr_u_t; + +#else + +typedef union ii_iidsr_u { + bdrkreg_t ii_iidsr_regval; + struct { + bdrkreg_t i_rsvd : 30; + bdrkreg_t i_pi1_forward_int : 1; + bdrkreg_t i_pi0_forward_int : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_int_sent : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_enable : 1; + bdrkreg_t i_rsvd_3 : 7; + bdrkreg_t i_node : 8; + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_rsvd_4 : 1; + bdrkreg_t i_level : 7; + } ii_iidsr_fld_s; +} ii_iidsr_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are two instances of this register. This register is used * + * for matching up the incoming responses from the graphics widget to * + * the processor that initiated the graphics operation. The * + * write-responses are converted to graphics credits and returned to * + * the processor so that the processor interface can manage the flow * + * control. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_igfx0_u { + bdrkreg_t ii_igfx0_regval; + struct { + bdrkreg_t i_w_num : 4; + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_n_num : 8; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_p_num : 1; + bdrkreg_t i_rsvd : 47; + } ii_igfx0_fld_s; +} ii_igfx0_u_t; + +#else + +typedef union ii_igfx0_u { + bdrkreg_t ii_igfx0_regval; + struct { + bdrkreg_t i_rsvd : 47; + bdrkreg_t i_p_num : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_n_num : 8; + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_w_num : 4; + } ii_igfx0_fld_s; +} ii_igfx0_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are two instances of this register. This register is used * + * for matching up the incoming responses from the graphics widget to * + * the processor that initiated the graphics operation. The * + * write-responses are converted to graphics credits and returned to * + * the processor so that the processor interface can manage the flow * + * control. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_igfx1_u { + bdrkreg_t ii_igfx1_regval; + struct { + bdrkreg_t i_w_num : 4; + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_n_num : 8; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_p_num : 1; + bdrkreg_t i_rsvd : 47; + } ii_igfx1_fld_s; +} ii_igfx1_u_t; + +#else + +typedef union ii_igfx1_u { + bdrkreg_t ii_igfx1_regval; + struct { + bdrkreg_t i_rsvd : 47; + bdrkreg_t i_p_num : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_n_num : 8; + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_w_num : 4; + } ii_igfx1_fld_s; +} ii_igfx1_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are two instances of this registers. These registers are * + * used as scratch registers for software use. * + * * + ************************************************************************/ + + + + +typedef union ii_iscr0_u { + bdrkreg_t ii_iscr0_regval; + struct { + bdrkreg_t i_scratch : 64; + } ii_iscr0_fld_s; +} ii_iscr0_u_t; + + + + +/************************************************************************ + * * + * There are two instances of this registers. These registers are * + * used as scratch registers for software use. * + * * + ************************************************************************/ + + + + +typedef union ii_iscr1_u { + bdrkreg_t ii_iscr1_regval; + struct { + bdrkreg_t i_scratch : 64; + } ii_iscr1_fld_s; +} ii_iscr1_u_t; + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte1_u { + bdrkreg_t ii_itte1_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte1_fld_s; +} ii_itte1_u_t; + +#else + +typedef union ii_itte1_u { + bdrkreg_t ii_itte1_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte1_fld_s; +} ii_itte1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte2_u { + bdrkreg_t ii_itte2_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte2_fld_s; +} ii_itte2_u_t; + +#else +typedef union ii_itte2_u { + bdrkreg_t ii_itte2_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte2_fld_s; +} ii_itte2_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte3_u { + bdrkreg_t ii_itte3_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte3_fld_s; +} ii_itte3_u_t; + +#else + +typedef union ii_itte3_u { + bdrkreg_t ii_itte3_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte3_fld_s; +} ii_itte3_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte4_u { + bdrkreg_t ii_itte4_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte4_fld_s; +} ii_itte4_u_t; + +#else + +typedef union ii_itte4_u { + bdrkreg_t ii_itte4_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte4_fld_s; +} ii_itte4_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte5_u { + bdrkreg_t ii_itte5_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte5_fld_s; +} ii_itte5_u_t; + +#else + +typedef union ii_itte5_u { + bdrkreg_t ii_itte5_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte5_fld_s; +} ii_itte5_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte6_u { + bdrkreg_t ii_itte6_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte6_fld_s; +} ii_itte6_u_t; + +#else + +typedef union ii_itte6_u { + bdrkreg_t ii_itte6_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte6_fld_s; +} ii_itte6_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Bedrock Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Bedrock is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Bedrock is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_itte7_u { + bdrkreg_t ii_itte7_regval; + struct { + bdrkreg_t i_offset : 5; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_rsvd : 51; + } ii_itte7_fld_s; +} ii_itte7_u_t; + +#else + +typedef union ii_itte7_u { + bdrkreg_t ii_itte7_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_iosp : 1; + bdrkreg_t i_w_num : 4; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_offset : 5; + } ii_itte7_fld_s; +} ii_itte7_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprb0_u { + bdrkreg_t ii_iprb0_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprb0_fld_s; +} ii_iprb0_u_t; + +#else + +typedef union ii_iprb0_u { + bdrkreg_t ii_iprb0_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprb0_fld_s; +} ii_iprb0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprb8_u { + bdrkreg_t ii_iprb8_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprb8_fld_s; +} ii_iprb8_u_t; + +#else + + +typedef union ii_iprb8_u { + bdrkreg_t ii_iprb8_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprb8_fld_s; +} ii_iprb8_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprb9_u { + bdrkreg_t ii_iprb9_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprb9_fld_s; +} ii_iprb9_u_t; + +#else + +typedef union ii_iprb9_u { + bdrkreg_t ii_iprb9_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprb9_fld_s; +} ii_iprb9_u_t; + +#endif + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprba_u { + bdrkreg_t ii_iprba_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprba_fld_s; +} ii_iprba_u_t; + +#else + +typedef union ii_iprba_u { + bdrkreg_t ii_iprba_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprba_fld_s; +} ii_iprba_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprbb_u { + bdrkreg_t ii_iprbb_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprbb_fld_s; +} ii_iprbb_u_t; + +#else + +typedef union ii_iprbb_u { + bdrkreg_t ii_iprbb_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprbb_fld_s; +} ii_iprbb_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprbc_u { + bdrkreg_t ii_iprbc_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprbc_fld_s; +} ii_iprbc_u_t; + +#else + +typedef union ii_iprbc_u { + bdrkreg_t ii_iprbc_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprbc_fld_s; +} ii_iprbc_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprbd_u { + bdrkreg_t ii_iprbd_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprbd_fld_s; +} ii_iprbd_u_t; + +#else + +typedef union ii_iprbd_u { + bdrkreg_t ii_iprbd_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprbd_fld_s; +} ii_iprbd_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprbe_u { + bdrkreg_t ii_iprbe_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprbe_fld_s; +} ii_iprbe_u_t; + +#else + +typedef union ii_iprbe_u { + bdrkreg_t ii_iprbe_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprbe_fld_s; +} ii_iprbe_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Bedrock and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprbf_u { + bdrkreg_t ii_iprbf_regval; + struct { + bdrkreg_t i_c : 8; + bdrkreg_t i_na : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_m : 2; + bdrkreg_t i_f : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_error : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_mult_err : 1; + } ii_iprbe_fld_s; +} ii_iprbf_u_t; + +#else + +typedef union ii_iprbf_u { + bdrkreg_t ii_iprbf_regval; + struct { + bdrkreg_t i_mult_err : 1; + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_spur_rd : 1; + bdrkreg_t i_spur_wr : 1; + bdrkreg_t i_rd_to : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_of_cnt : 5; + bdrkreg_t i_f : 1; + bdrkreg_t i_m : 2; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_nb : 14; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_na : 14; + bdrkreg_t i_c : 8; + } ii_iprbf_fld_s; +} ii_iprbf_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register specifies the timeout value to use for monitoring * + * Crosstalk credits which are used outbound to Crosstalk. An * + * internal counter called the Crosstalk Credit Timeout Counter * + * increments every 128 II clocks. The counter starts counting * + * anytime the credit count drops below a threshold, and resets to * + * zero (stops counting) anytime the credit count is at or above the * + * threshold. The threshold is 1 credit in direct connect mode and 2 * + * in Crossbow connect mode. When the internal Crosstalk Credit * + * Timeout Counter reaches the value programmed in this register, a * + * Crosstalk Credit Timeout has occurred. The internal counter is not * + * readable from software, and stops counting at its maximum value, * + * so it cannot cause more than one interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ixcc_u { + bdrkreg_t ii_ixcc_regval; + struct { + bdrkreg_t i_time_out : 26; + bdrkreg_t i_rsvd : 38; + } ii_ixcc_fld_s; +} ii_ixcc_u_t; + +#else + +typedef union ii_ixcc_u { + bdrkreg_t ii_ixcc_regval; + struct { + bdrkreg_t i_rsvd : 38; + bdrkreg_t i_time_out : 26; + } ii_ixcc_fld_s; +} ii_ixcc_u_t; + +#endif + + + +/************************************************************************ + * * + * Description: This register qualifies all the PIO and DMA * + * operations launched from widget 0 towards the Bedrock. In * + * addition, it also qualifies accesses by the BTE streams. * + * The bits in each field of this register are cleared by the Bedrock * + * upon detection of an error which requires widget 0 or the BTE * + * streams to be terminated. Whether or not widget x has access * + * rights to this Bedrock is determined by an AND of the device * + * enable bit in the appropriate field of this register and bit 0 in * + * the Wx_IAC field. The bits in this field are set by writing a 1 to * + * them. Incoming replies from Crosstalk are not subject to this * + * access control mechanism. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_imem_u { + bdrkreg_t ii_imem_regval; + struct { + bdrkreg_t i_w0_esd : 1; + bdrkreg_t i_rsvd_3 : 3; + bdrkreg_t i_b0_esd : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_b1_esd : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_clr_precise : 1; + bdrkreg_t i_rsvd : 51; + } ii_imem_fld_s; +} ii_imem_u_t; + +#else + +typedef union ii_imem_u { + bdrkreg_t ii_imem_regval; + struct { + bdrkreg_t i_rsvd : 51; + bdrkreg_t i_clr_precise : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_b1_esd : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_b0_esd : 1; + bdrkreg_t i_rsvd_3 : 3; + bdrkreg_t i_w0_esd : 1; + } ii_imem_fld_s; +} ii_imem_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register specifies the timeout value to use for * + * monitoring Crosstalk tail flits coming into the Bedrock in the * + * TAIL_TO field. An internal counter associated with this register * + * is incremented every 128 II internal clocks (7 bits). The counter * + * starts counting anytime a header micropacket is received and stops * + * counting (and resets to zero) any time a micropacket with a Tail * + * bit is received. Once the counter reaches the threshold value * + * programmed in this register, it generates an interrupt to the * + * processor that is programmed into the IIDSR. The counter saturates * + * (does not roll over) at its maximum value, so it cannot cause * + * another interrupt until after it is cleared. * + * The register also contains the Read Response Timeout values. The * + * Prescalar is 23 bits, and counts II clocks. An internal counter * + * increments on every II clock and when it reaches the value in the * + * Prescalar field, all IPRTE registers with their valid bits set * + * have their Read Response timers bumped. Whenever any of them match * + * the value in the RRSP_TO field, a Read Response Timeout has * + * occurred, and error handling occurs as described in the Error * + * Handling section of this document. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ixtt_u { + bdrkreg_t ii_ixtt_regval; + struct { + bdrkreg_t i_tail_to : 26; + bdrkreg_t i_rsvd_1 : 6; + bdrkreg_t i_rrsp_ps : 23; + bdrkreg_t i_rrsp_to : 5; + bdrkreg_t i_rsvd : 4; + } ii_ixtt_fld_s; +} ii_ixtt_u_t; + +#else + +typedef union ii_ixtt_u { + bdrkreg_t ii_ixtt_regval; + struct { + bdrkreg_t i_rsvd : 4; + bdrkreg_t i_rrsp_to : 5; + bdrkreg_t i_rrsp_ps : 23; + bdrkreg_t i_rsvd_1 : 6; + bdrkreg_t i_tail_to : 26; + } ii_ixtt_fld_s; +} ii_ixtt_u_t; + +#endif + + + + +/************************************************************************ + * * + * Writing a 1 to the fields of this register clears the appropriate * + * error bits in other areas of Bedrock_II. Note that when the * + * E_PRB_x bits are used to clear error bits in PRB registers, * + * SPUR_RD and SPUR_WR may persist, because they require additional * + * action to clear them. See the IPRBx and IXSS Register * + * specifications. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ieclr_u { + bdrkreg_t ii_ieclr_regval; + struct { + bdrkreg_t i_e_prb_0 : 1; + bdrkreg_t i_rsvd : 7; + bdrkreg_t i_e_prb_8 : 1; + bdrkreg_t i_e_prb_9 : 1; + bdrkreg_t i_e_prb_a : 1; + bdrkreg_t i_e_prb_b : 1; + bdrkreg_t i_e_prb_c : 1; + bdrkreg_t i_e_prb_d : 1; + bdrkreg_t i_e_prb_e : 1; + bdrkreg_t i_e_prb_f : 1; + bdrkreg_t i_e_crazy : 1; + bdrkreg_t i_e_bte_0 : 1; + bdrkreg_t i_e_bte_1 : 1; + bdrkreg_t i_reserved_1 : 9; + bdrkreg_t i_ii_internal : 1; + bdrkreg_t i_spur_rd_hdr : 1; + bdrkreg_t i_pi0_forward_int : 1; + bdrkreg_t i_pi1_forward_int : 1; + bdrkreg_t i_reserved : 32; + } ii_ieclr_fld_s; +} ii_ieclr_u_t; + +#else + +typedef union ii_ieclr_u { + bdrkreg_t ii_ieclr_regval; + struct { + bdrkreg_t i_reserved : 32; + bdrkreg_t i_pi1_forward_int : 1; + bdrkreg_t i_pi0_forward_int : 1; + bdrkreg_t i_spur_rd_hdr : 1; + bdrkreg_t i_ii_internal : 1; + bdrkreg_t i_reserved_1 : 9; + bdrkreg_t i_e_bte_1 : 1; + bdrkreg_t i_e_bte_0 : 1; + bdrkreg_t i_e_crazy : 1; + bdrkreg_t i_e_prb_f : 1; + bdrkreg_t i_e_prb_e : 1; + bdrkreg_t i_e_prb_d : 1; + bdrkreg_t i_e_prb_c : 1; + bdrkreg_t i_e_prb_b : 1; + bdrkreg_t i_e_prb_a : 1; + bdrkreg_t i_e_prb_9 : 1; + bdrkreg_t i_e_prb_8 : 1; + bdrkreg_t i_rsvd : 7; + bdrkreg_t i_e_prb_0 : 1; + } ii_ieclr_fld_s; +} ii_ieclr_u_t; + +#endif + + + + + +/************************************************************************ + * * + * This register controls both BTEs. SOFT_RESET is intended for * + * recovery after an error. COUNT controls the total number of CRBs * + * that both BTEs (combined) can use, which affects total BTE * + * bandwidth. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibcr_u { + bdrkreg_t ii_ibcr_regval; + struct { + bdrkreg_t i_count : 4; + bdrkreg_t i_rsvd_1 : 4; + bdrkreg_t i_soft_reset : 1; + bdrkreg_t i_rsvd : 55; + } ii_ibcr_fld_s; +} ii_ibcr_u_t; + +#else + +typedef union ii_ibcr_u { + bdrkreg_t ii_ibcr_regval; + struct { + bdrkreg_t i_rsvd : 55; + bdrkreg_t i_soft_reset : 1; + bdrkreg_t i_rsvd_1 : 4; + bdrkreg_t i_count : 4; + } ii_ibcr_fld_s; +} ii_ibcr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the header of a spurious read response * + * received from Crosstalk. A spurious read response is defined as a * + * read response received by II from a widget for which (1) the SIDN * + * has a value between 1 and 7, inclusive (II never sends requests to * + * these widgets (2) there is no valid IPRTE register which * + * corresponds to the TNUM, or (3) the widget indicated in SIDN is * + * not the same as the widget recorded in the IPRTE register * + * referenced by the TNUM. If this condition is true, and if the * + * IXSS[VALID] bit is clear, then the header of the spurious read * + * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The * + * errant header is thereby captured, and no further spurious read * + * respones are captured until IXSS[VALID] is cleared by setting the * + * appropriate bit in IECLR.Everytime a spurious read response is * + * detected, the SPUR_RD bit of the PRB corresponding to the incoming * + * message's SIDN field is set. This always happens, regarless of * + * whether a header is captured. The programmer should check * + * IXSM[SIDN] to determine which widget sent the spurious response, * + * because there may be more than one SPUR_RD bit set in the PRB * + * registers. The widget indicated by IXSM[SIDN] was the first * + * spurious read response to be received since the last time * + * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB * + * will be set. Any SPUR_RD bits in any other PRB registers indicate * + * spurious messages from other widets which were detected after the * + * header was captured.. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ixsm_u { + bdrkreg_t ii_ixsm_regval; + struct { + bdrkreg_t i_byte_en : 32; + bdrkreg_t i_reserved : 1; + bdrkreg_t i_tag : 3; + bdrkreg_t i_alt_pactyp : 4; + bdrkreg_t i_bo : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_vbpm : 1; + bdrkreg_t i_gbr : 1; + bdrkreg_t i_ds : 2; + bdrkreg_t i_ct : 1; + bdrkreg_t i_tnum : 5; + bdrkreg_t i_pactyp : 4; + bdrkreg_t i_sidn : 4; + bdrkreg_t i_didn : 4; + } ii_ixsm_fld_s; +} ii_ixsm_u_t; + +#else + +typedef union ii_ixsm_u { + bdrkreg_t ii_ixsm_regval; + struct { + bdrkreg_t i_didn : 4; + bdrkreg_t i_sidn : 4; + bdrkreg_t i_pactyp : 4; + bdrkreg_t i_tnum : 5; + bdrkreg_t i_ct : 1; + bdrkreg_t i_ds : 2; + bdrkreg_t i_gbr : 1; + bdrkreg_t i_vbpm : 1; + bdrkreg_t i_error : 1; + bdrkreg_t i_bo : 1; + bdrkreg_t i_alt_pactyp : 4; + bdrkreg_t i_tag : 3; + bdrkreg_t i_reserved : 1; + bdrkreg_t i_byte_en : 32; + } ii_ixsm_fld_s; +} ii_ixsm_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the sideband bits of a spurious read * + * response received from Crosstalk. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ixss_u { + bdrkreg_t ii_ixss_regval; + struct { + bdrkreg_t i_sideband : 8; + bdrkreg_t i_rsvd : 55; + bdrkreg_t i_valid : 1; + } ii_ixss_fld_s; +} ii_ixss_u_t; + +#else + +typedef union ii_ixss_u { + bdrkreg_t ii_ixss_regval; + struct { + bdrkreg_t i_valid : 1; + bdrkreg_t i_rsvd : 55; + bdrkreg_t i_sideband : 8; + } ii_ixss_fld_s; +} ii_ixss_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register enables software to access the II LLP's test port. * + * Refer to the LLP 2.5 documentation for an explanation of the test * + * port. Software can write to this register to program the values * + * for the control fields (TestErrCapture, TestClear, TestFlit, * + * TestMask and TestSeed). Similarly, software can read from this * + * register to obtain the values of the test port's status outputs * + * (TestCBerr, TestValid and TestData). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ilct_u { + bdrkreg_t ii_ilct_regval; + struct { + bdrkreg_t i_rsvd : 9; + bdrkreg_t i_test_err_capture : 1; + bdrkreg_t i_test_clear : 1; + bdrkreg_t i_test_flit : 3; + bdrkreg_t i_test_cberr : 1; + bdrkreg_t i_test_valid : 1; + bdrkreg_t i_test_data : 20; + bdrkreg_t i_test_mask : 8; + bdrkreg_t i_test_seed : 20; + } ii_ilct_fld_s; +} ii_ilct_u_t; + +#else + +typedef union ii_ilct_u { + bdrkreg_t ii_ilct_regval; + struct { + bdrkreg_t i_rsvd : 9; + bdrkreg_t i_test_err_capture : 1; + bdrkreg_t i_test_clear : 1; + bdrkreg_t i_test_flit : 3; + bdrkreg_t i_test_cberr : 1; + bdrkreg_t i_test_valid : 1; + bdrkreg_t i_test_data : 20; + bdrkreg_t i_test_mask : 8; + bdrkreg_t i_test_seed : 20; + } ii_ilct_fld_s; +} ii_ilct_u_t; + +#endif + + + + +/************************************************************************ + * * + * If the II detects an illegal incoming Duplonet packet (request or * + * reply) when VALID==0 in the IIEPH1 register, then it saves the * + * contents of the packet's header flit in the IIEPH1 and IIEPH2 * + * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit, * + * and assigns a value to the ERR_TYPE field which indicates the * + * specific nature of the error. The II recognizes four different * + * types of errors: short request packets (ERR_TYPE==2), short reply * + * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long * + * reply packets (ERR_TYPE==5). The encodings for these types of * + * errors were chosen to be consistent with the same types of errors * + * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in * + * the LB unit). If the II detects an illegal incoming Duplonet * + * packet when VALID==1 in the IIEPH1 register, then it merely sets * + * the OVERRUN bit to indicate that a subsequent error has happened, * + * and does nothing further. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iieph1_u { + bdrkreg_t ii_iieph1_regval; + struct { + bdrkreg_t i_command : 7; + bdrkreg_t i_rsvd_5 : 1; + bdrkreg_t i_suppl : 11; + bdrkreg_t i_rsvd_4 : 1; + bdrkreg_t i_source : 11; + bdrkreg_t i_rsvd_3 : 1; + bdrkreg_t i_err_type : 4; + bdrkreg_t i_rsvd_2 : 4; + bdrkreg_t i_overrun : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_valid : 1; + bdrkreg_t i_rsvd : 19; + } ii_iieph1_fld_s; +} ii_iieph1_u_t; + +#else + +typedef union ii_iieph1_u { + bdrkreg_t ii_iieph1_regval; + struct { + bdrkreg_t i_rsvd : 19; + bdrkreg_t i_valid : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_overrun : 1; + bdrkreg_t i_rsvd_2 : 4; + bdrkreg_t i_err_type : 4; + bdrkreg_t i_rsvd_3 : 1; + bdrkreg_t i_source : 11; + bdrkreg_t i_rsvd_4 : 1; + bdrkreg_t i_suppl : 11; + bdrkreg_t i_rsvd_5 : 1; + bdrkreg_t i_command : 7; + } ii_iieph1_fld_s; +} ii_iieph1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register holds the Address field from the header flit of an * + * incoming erroneous Duplonet packet, along with the tail bit which * + * accompanied this header flit. This register is essentially an * + * extension of IIEPH1. Two registers were necessary because the 64 * + * bits available in only a single register were insufficient to * + * capture the entire header flit of an erroneous packet. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iieph2_u { + bdrkreg_t ii_iieph2_regval; + struct { + bdrkreg_t i_address : 38; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_tail : 1; + bdrkreg_t i_rsvd : 23; + } ii_iieph2_fld_s; +} ii_iieph2_u_t; + +#else + +typedef union ii_iieph2_u { + bdrkreg_t ii_iieph2_regval; + struct { + bdrkreg_t i_rsvd : 23; + bdrkreg_t i_tail : 1; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_address : 38; + } ii_iieph2_fld_s; +} ii_iieph2_u_t; + +#endif + + + + +/************************************************************************ + * * + * A write to this register causes a particular field in the * + * corresponding widget's PRB entry to be adjusted up or down by 1. * + * This counter should be used when recovering from error and reset * + * conditions. Note that software would be capable of causing * + * inadvertent overflow or underflow of these counters. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ipca_u { + bdrkreg_t ii_ipca_regval; + struct { + bdrkreg_t i_wid : 4; + bdrkreg_t i_adjust : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_field : 2; + bdrkreg_t i_rsvd : 54; + } ii_ipca_fld_s; +} ii_ipca_u_t; + +#else + +typedef union ii_ipca_u { + bdrkreg_t ii_ipca_regval; + struct { + bdrkreg_t i_rsvd : 54; + bdrkreg_t i_field : 2; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_adjust : 1; + bdrkreg_t i_wid : 4; + } ii_ipca_fld_s; +} ii_ipca_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte0_u { + bdrkreg_t ii_iprte0_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte0_fld_s; +} ii_iprte0_u_t; + +#else + +typedef union ii_iprte0_u { + bdrkreg_t ii_iprte0_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte0_fld_s; +} ii_iprte0_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte1_u { + bdrkreg_t ii_iprte1_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte1_fld_s; +} ii_iprte1_u_t; + +#else + +typedef union ii_iprte1_u { + bdrkreg_t ii_iprte1_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte1_fld_s; +} ii_iprte1_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte2_u { + bdrkreg_t ii_iprte2_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte2_fld_s; +} ii_iprte2_u_t; + +#else + +typedef union ii_iprte2_u { + bdrkreg_t ii_iprte2_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte2_fld_s; +} ii_iprte2_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte3_u { + bdrkreg_t ii_iprte3_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte3_fld_s; +} ii_iprte3_u_t; + +#else + +typedef union ii_iprte3_u { + bdrkreg_t ii_iprte3_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte3_fld_s; +} ii_iprte3_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte4_u { + bdrkreg_t ii_iprte4_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte4_fld_s; +} ii_iprte4_u_t; + +#else + +typedef union ii_iprte4_u { + bdrkreg_t ii_iprte4_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte4_fld_s; +} ii_iprte4_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte5_u { + bdrkreg_t ii_iprte5_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte5_fld_s; +} ii_iprte5_u_t; + +#else + +typedef union ii_iprte5_u { + bdrkreg_t ii_iprte5_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte5_fld_s; +} ii_iprte5_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte6_u { + bdrkreg_t ii_iprte6_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte6_fld_s; +} ii_iprte6_u_t; + +#else + +typedef union ii_iprte6_u { + bdrkreg_t ii_iprte6_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte6_fld_s; +} ii_iprte6_u_t; + +#endif + + + + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iprte7_u { + bdrkreg_t ii_iprte7_regval; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } ii_iprte7_fld_s; +} ii_iprte7_u_t; + +#else + +typedef union ii_iprte7_u { + bdrkreg_t ii_iprte7_regval; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } ii_iprte7_fld_s; +} ii_iprte7_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Bedrock_II contains a feature which did not exist in * + * the Hub which automatically cleans up after a Read Response * + * timeout, including deallocation of the IPRTE and recovery of IBuf * + * space. The inclusion of this register in Bedrock is for backward * + * compatibility * + * A write to this register causes an entry from the table of * + * outstanding PIO Read Requests to be freed and returned to the * + * stack of free entries. This register is used in handling the * + * timeout errors that result in a PIO Reply never returning from * + * Crosstalk. * + * Note that this register does not affect the contents of the IPRTE * + * registers. The Valid bits in those registers have to be * + * specifically turned off by software. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ipdr_u { + bdrkreg_t ii_ipdr_regval; + struct { + bdrkreg_t i_te : 3; + bdrkreg_t i_rsvd_1 : 1; + bdrkreg_t i_pnd : 1; + bdrkreg_t i_init_rpcnt : 1; + bdrkreg_t i_rsvd : 58; + } ii_ipdr_fld_s; +} ii_ipdr_u_t; + +#else + +typedef union ii_ipdr_u { + bdrkreg_t ii_ipdr_regval; + struct { + bdrkreg_t i_rsvd : 58; + bdrkreg_t i_init_rpcnt : 1; + bdrkreg_t i_pnd : 1; + bdrkreg_t i_rsvd_1 : 1; + bdrkreg_t i_te : 3; + } ii_ipdr_fld_s; +} ii_ipdr_u_t; + +#endif + + + + +/************************************************************************ + * * + * A write to this register causes a CRB entry to be returned to the * + * queue of free CRBs. The entry should have previously been cleared * + * (mark bit) via backdoor access to the pertinent CRB entry. This * + * register is used in the last step of handling the errors that are * + * captured and marked in CRB entries. Briefly: 1) first error for * + * DMA write from a particular device, and first error for a * + * particular BTE stream, lead to a marked CRB entry, and processor * + * interrupt, 2) software reads the error information captured in the * + * CRB entry, and presumably takes some corrective action, 3) * + * software clears the mark bit, and finally 4) software writes to * + * the ICDR register to return the CRB entry to the list of free CRB * + * entries. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icdr_u { + bdrkreg_t ii_icdr_regval; + struct { + bdrkreg_t i_crb_num : 4; + bdrkreg_t i_pnd : 1; + bdrkreg_t i_rsvd : 59; + } ii_icdr_fld_s; +} ii_icdr_u_t; + +#else + +typedef union ii_icdr_u { + bdrkreg_t ii_icdr_regval; + struct { + bdrkreg_t i_rsvd : 59; + bdrkreg_t i_pnd : 1; + bdrkreg_t i_crb_num : 4; + } ii_icdr_fld_s; +} ii_icdr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register provides debug access to two FIFOs inside of II. * + * Both IOQ_MAX* fields of this register contain the instantaneous * + * depth (in units of the number of available entries) of the * + * associated IOQ FIFO. A read of this register will return the * + * number of free entries on each FIFO at the time of the read. So * + * when a FIFO is idle, the associated field contains the maximum * + * depth of the FIFO. This register is writable for debug reasons * + * and is intended to be written with the maximum desired FIFO depth * + * while the FIFO is idle. Software must assure that II is idle when * + * this register is written. If there are any active entries in any * + * of these FIFOs when this register is written, the results are * + * undefined. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ifdr_u { + bdrkreg_t ii_ifdr_regval; + struct { + bdrkreg_t i_ioq_max_rq : 7; + bdrkreg_t i_set_ioq_rq : 1; + bdrkreg_t i_ioq_max_rp : 7; + bdrkreg_t i_set_ioq_rp : 1; + bdrkreg_t i_rsvd : 48; + } ii_ifdr_fld_s; +} ii_ifdr_u_t; + +#else + +typedef union ii_ifdr_u { + bdrkreg_t ii_ifdr_regval; + struct { + bdrkreg_t i_rsvd : 48; + bdrkreg_t i_set_ioq_rp : 1; + bdrkreg_t i_ioq_max_rp : 7; + bdrkreg_t i_set_ioq_rq : 1; + bdrkreg_t i_ioq_max_rq : 7; + } ii_ifdr_fld_s; +} ii_ifdr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register allows the II to become sluggish in removing * + * messages from its inbound queue (IIQ). This will cause messages to * + * back up in either virtual channel. Disabling the "molasses" mode * + * subsequently allows the II to be tested under stress. In the * + * sluggish ("Molasses") mode, the localized effects of congestion * + * can be observed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iiap_u { + bdrkreg_t ii_iiap_regval; + struct { + bdrkreg_t i_rq_mls : 6; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_rp_mls : 6; + bdrkreg_t i_rsvd : 50; + } ii_iiap_fld_s; +} ii_iiap_u_t; + +#else + +typedef union ii_iiap_u { + bdrkreg_t ii_iiap_regval; + struct { + bdrkreg_t i_rsvd : 50; + bdrkreg_t i_rp_mls : 6; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_rq_mls : 6; + } ii_iiap_fld_s; +} ii_iiap_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register allows several parameters of CRB operation to be * + * set. Note that writing to this register can have catastrophic side * + * effects, if the CRB is not quiescent, i.e. if the CRB is * + * processing protocol messages when the write occurs. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icmr_u { + bdrkreg_t ii_icmr_regval; + struct { + bdrkreg_t i_sp_msg : 1; + bdrkreg_t i_rd_hdr : 1; + bdrkreg_t i_rsvd_4 : 2; + bdrkreg_t i_c_cnt : 4; + bdrkreg_t i_rsvd_3 : 4; + bdrkreg_t i_clr_rqpd : 1; + bdrkreg_t i_clr_rppd : 1; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_fc_cnt : 4; + bdrkreg_t i_crb_vld : 15; + bdrkreg_t i_crb_mark : 15; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_precise : 1; + bdrkreg_t i_rsvd : 11; + } ii_icmr_fld_s; +} ii_icmr_u_t; + +#else + +typedef union ii_icmr_u { + bdrkreg_t ii_icmr_regval; + struct { + bdrkreg_t i_rsvd : 11; + bdrkreg_t i_precise : 1; + bdrkreg_t i_rsvd_1 : 2; + bdrkreg_t i_crb_mark : 15; + bdrkreg_t i_crb_vld : 15; + bdrkreg_t i_fc_cnt : 4; + bdrkreg_t i_rsvd_2 : 2; + bdrkreg_t i_clr_rppd : 1; + bdrkreg_t i_clr_rqpd : 1; + bdrkreg_t i_rsvd_3 : 4; + bdrkreg_t i_c_cnt : 4; + bdrkreg_t i_rsvd_4 : 2; + bdrkreg_t i_rd_hdr : 1; + bdrkreg_t i_sp_msg : 1; + } ii_icmr_fld_s; +} ii_icmr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register allows control of the table portion of the CRB * + * logic via software. Control operations from this register have * + * priority over all incoming Crosstalk or BTE requests. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_iccr_u { + bdrkreg_t ii_iccr_regval; + struct { + bdrkreg_t i_crb_num : 4; + bdrkreg_t i_rsvd_1 : 4; + bdrkreg_t i_cmd : 8; + bdrkreg_t i_pending : 1; + bdrkreg_t i_rsvd : 47; + } ii_iccr_fld_s; +} ii_iccr_u_t; + +#else + +typedef union ii_iccr_u { + bdrkreg_t ii_iccr_regval; + struct { + bdrkreg_t i_rsvd : 47; + bdrkreg_t i_pending : 1; + bdrkreg_t i_cmd : 8; + bdrkreg_t i_rsvd_1 : 4; + bdrkreg_t i_crb_num : 4; + } ii_iccr_fld_s; +} ii_iccr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register allows the maximum timeout value to be programmed. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icto_u { + bdrkreg_t ii_icto_regval; + struct { + bdrkreg_t i_timeout : 8; + bdrkreg_t i_rsvd : 56; + } ii_icto_fld_s; +} ii_icto_u_t; + +#else + +typedef union ii_icto_u { + bdrkreg_t ii_icto_regval; + struct { + bdrkreg_t i_rsvd : 56; + bdrkreg_t i_timeout : 8; + } ii_icto_fld_s; +} ii_icto_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register allows the timeout prescalar to be programmed. An * + * internal counter is associated with this register. When the * + * internal counter reaches the value of the PRESCALE field, the * + * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT] * + * field). The internal counter resets to zero, and then continues * + * counting. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ictp_u { + bdrkreg_t ii_ictp_regval; + struct { + bdrkreg_t i_prescale : 24; + bdrkreg_t i_rsvd : 40; + } ii_ictp_fld_s; +} ii_ictp_u_t; + +#else + +typedef union ii_ictp_u { + bdrkreg_t ii_ictp_regval; + struct { + bdrkreg_t i_rsvd : 40; + bdrkreg_t i_prescale : 24; + } ii_ictp_fld_s; +} ii_ictp_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, four * + * registers (_A to _D) are required to read and write each entry. * + * The CRB Entry registers can be conceptualized as rows and columns * + * (illustrated in the table above). Each row contains the 4 * + * registers required for a single CRB Entry. The first doubleword * + * (column) for each entry is labeled A, and the second doubleword * + * (higher address) is labeled B, the third doubleword is labeled C, * + * and the fourth doubleword is labeled D. All CRB entries have their * + * addresses on a quarter cacheline aligned boundary. * + * Upon reset, only the following fields are initialized: valid * + * (VLD), priority count, timeout, timeout valid, and context valid. * + * All other bits should be cleared by software before use (after * + * recovering any potential error state from before the reset). * + * The following four tables summarize the format for the four * + * registers that are used for each ICRB# Entry. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icrb0_a_u { + bdrkreg_t ii_icrb0_a_regval; + struct { + bdrkreg_t ia_iow : 1; + bdrkreg_t ia_vld : 1; + bdrkreg_t ia_addr : 38; + bdrkreg_t ia_tnum : 5; + bdrkreg_t ia_sidn : 4; + bdrkreg_t ia_xt_err : 1; + bdrkreg_t ia_mark : 1; + bdrkreg_t ia_ln_uce : 1; + bdrkreg_t ia_errcode : 3; + bdrkreg_t ia_error : 1; + bdrkreg_t ia_stall__bte_1 : 1; + bdrkreg_t ia_stall__bte_0 : 1; + bdrkreg_t ia_rsvd : 6; + } ii_icrb0_a_fld_s; +} ii_icrb0_a_u_t; + +#else + +typedef union ii_icrb0_a_u { + bdrkreg_t ii_icrb0_a_regval; + struct { + bdrkreg_t ia_rsvd : 6; + bdrkreg_t ia_stall__bte_0 : 1; + bdrkreg_t ia_stall__bte_1 : 1; + bdrkreg_t ia_error : 1; + bdrkreg_t ia_errcode : 3; + bdrkreg_t ia_ln_uce : 1; + bdrkreg_t ia_mark : 1; + bdrkreg_t ia_xt_err : 1; + bdrkreg_t ia_sidn : 4; + bdrkreg_t ia_tnum : 5; + bdrkreg_t ia_addr : 38; + bdrkreg_t ia_vld : 1; + bdrkreg_t ia_iow : 1; + } ii_icrb0_a_fld_s; +} ii_icrb0_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, four * + * registers (_A to _D) are required to read and write each entry. * + * * + ************************************************************************/ + + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icrb0_b_u { + bdrkreg_t ii_icrb0_b_regval; + struct { + bdrkreg_t ib_stall__intr : 1; + bdrkreg_t ib_stall_ib : 1; + bdrkreg_t ib_intvn : 1; + bdrkreg_t ib_wb : 1; + bdrkreg_t ib_hold : 1; + bdrkreg_t ib_ack : 1; + bdrkreg_t ib_resp : 1; + bdrkreg_t ib_ack_cnt : 11; + bdrkreg_t ib_rsvd_1 : 7; + bdrkreg_t ib_exc : 5; + bdrkreg_t ib_init : 3; + bdrkreg_t ib_imsg : 8; + bdrkreg_t ib_imsgtype : 2; + bdrkreg_t ib_use_old : 1; + bdrkreg_t ib_source : 12; + bdrkreg_t ib_size : 2; + bdrkreg_t ib_ct : 1; + bdrkreg_t ib_bte_num : 1; + bdrkreg_t ib_rsvd : 4; + } ii_icrb0_b_fld_s; +} ii_icrb0_b_u_t; + +#else + +typedef union ii_icrb0_b_u { + bdrkreg_t ii_icrb0_b_regval; + struct { + bdrkreg_t ib_rsvd : 4; + bdrkreg_t ib_bte_num : 1; + bdrkreg_t ib_ct : 1; + bdrkreg_t ib_size : 2; + bdrkreg_t ib_source : 12; + bdrkreg_t ib_use_old : 1; + bdrkreg_t ib_imsgtype : 2; + bdrkreg_t ib_imsg : 8; + bdrkreg_t ib_init : 3; + bdrkreg_t ib_exc : 5; + bdrkreg_t ib_rsvd_1 : 7; + bdrkreg_t ib_ack_cnt : 11; + bdrkreg_t ib_resp : 1; + bdrkreg_t ib_ack : 1; + bdrkreg_t ib_hold : 1; + bdrkreg_t ib_wb : 1; + bdrkreg_t ib_intvn : 1; + bdrkreg_t ib_stall_ib : 1; + bdrkreg_t ib_stall__intr : 1; + } ii_icrb0_b_fld_s; +} ii_icrb0_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, four * + * registers (_A to _D) are required to read and write each entry. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icrb0_c_u { + bdrkreg_t ii_icrb0_c_regval; + struct { + bdrkreg_t ic_gbr : 1; + bdrkreg_t ic_resprqd : 1; + bdrkreg_t ic_bo : 1; + bdrkreg_t ic_suppl : 12; + bdrkreg_t ic_pa_be : 34; + bdrkreg_t ic_bte_op : 1; + bdrkreg_t ic_pr_psc : 4; + bdrkreg_t ic_pr_cnt : 4; + bdrkreg_t ic_sleep : 1; + bdrkreg_t ic_rsvd : 5; + } ii_icrb0_c_fld_s; +} ii_icrb0_c_u_t; + +#else + +typedef union ii_icrb0_c_u { + bdrkreg_t ii_icrb0_c_regval; + struct { + bdrkreg_t ic_rsvd : 5; + bdrkreg_t ic_sleep : 1; + bdrkreg_t ic_pr_cnt : 4; + bdrkreg_t ic_pr_psc : 4; + bdrkreg_t ic_bte_op : 1; + bdrkreg_t ic_pa_be : 34; + bdrkreg_t ic_suppl : 12; + bdrkreg_t ic_bo : 1; + bdrkreg_t ic_resprqd : 1; + bdrkreg_t ic_gbr : 1; + } ii_icrb0_c_fld_s; +} ii_icrb0_c_u_t; + +#endif + + + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, four * + * registers (_A to _D) are required to read and write each entry. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icrb0_d_u { + bdrkreg_t ii_icrb0_d_regval; + struct { + bdrkreg_t id_timeout : 8; + bdrkreg_t id_context : 15; + bdrkreg_t id_rsvd_1 : 1; + bdrkreg_t id_tvld : 1; + bdrkreg_t id_cvld : 1; + bdrkreg_t id_rsvd : 38; + } ii_icrb0_d_fld_s; +} ii_icrb0_d_u_t; + +#else + +typedef union ii_icrb0_d_u { + bdrkreg_t ii_icrb0_d_regval; + struct { + bdrkreg_t id_rsvd : 38; + bdrkreg_t id_cvld : 1; + bdrkreg_t id_tvld : 1; + bdrkreg_t id_rsvd_1 : 1; + bdrkreg_t id_context : 15; + bdrkreg_t id_timeout : 8; + } ii_icrb0_d_fld_s; +} ii_icrb0_d_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the lower 64 bits of the header of the * + * spurious message captured by II. Valid when the SP_MSG bit in ICMR * + * register is set. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icsml_u { + bdrkreg_t ii_icsml_regval; + struct { + bdrkreg_t i_tt_addr : 38; + bdrkreg_t i_tt_ack_cnt : 11; + bdrkreg_t i_newsuppl_ex : 11; + bdrkreg_t i_reserved : 3; + bdrkreg_t i_overflow : 1; + } ii_icsml_fld_s; +} ii_icsml_u_t; + +#else + +typedef union ii_icsml_u { + bdrkreg_t ii_icsml_regval; + struct { + bdrkreg_t i_overflow : 1; + bdrkreg_t i_reserved : 3; + bdrkreg_t i_newsuppl_ex : 11; + bdrkreg_t i_tt_ack_cnt : 11; + bdrkreg_t i_tt_addr : 38; + } ii_icsml_fld_s; +} ii_icsml_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the microscopic state, all the inputs to * + * the protocol table, captured with the spurious message. Valid when * + * the SP_MSG bit in the ICMR register is set. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_icsmh_u { + bdrkreg_t ii_icsmh_regval; + struct { + bdrkreg_t i_tt_vld : 1; + bdrkreg_t i_xerr : 1; + bdrkreg_t i_ft_cwact_o : 1; + bdrkreg_t i_ft_wact_o : 1; + bdrkreg_t i_ft_active_o : 1; + bdrkreg_t i_sync : 1; + bdrkreg_t i_mnusg : 1; + bdrkreg_t i_mnusz : 1; + bdrkreg_t i_plusz : 1; + bdrkreg_t i_plusg : 1; + bdrkreg_t i_tt_exc : 5; + bdrkreg_t i_tt_wb : 1; + bdrkreg_t i_tt_hold : 1; + bdrkreg_t i_tt_ack : 1; + bdrkreg_t i_tt_resp : 1; + bdrkreg_t i_tt_intvn : 1; + bdrkreg_t i_g_stall_bte1 : 1; + bdrkreg_t i_g_stall_bte0 : 1; + bdrkreg_t i_g_stall_il : 1; + bdrkreg_t i_g_stall_ib : 1; + bdrkreg_t i_tt_imsg : 8; + bdrkreg_t i_tt_imsgtype : 2; + bdrkreg_t i_tt_use_old : 1; + bdrkreg_t i_tt_respreqd : 1; + bdrkreg_t i_tt_bte_num : 1; + bdrkreg_t i_cbn : 1; + bdrkreg_t i_match : 1; + bdrkreg_t i_rpcnt_lt_34 : 1; + bdrkreg_t i_rpcnt_ge_34 : 1; + bdrkreg_t i_rpcnt_lt_18 : 1; + bdrkreg_t i_rpcnt_ge_18 : 1; + bdrkreg_t i_rpcnt_lt_2 : 1; + bdrkreg_t i_rpcnt_ge_2 : 1; + bdrkreg_t i_rqcnt_lt_18 : 1; + bdrkreg_t i_rqcnt_ge_18 : 1; + bdrkreg_t i_rqcnt_lt_2 : 1; + bdrkreg_t i_rqcnt_ge_2 : 1; + bdrkreg_t i_tt_device : 7; + bdrkreg_t i_tt_init : 3; + bdrkreg_t i_reserved : 5; + } ii_icsmh_fld_s; +} ii_icsmh_u_t; + +#else + +typedef union ii_icsmh_u { + bdrkreg_t ii_icsmh_regval; + struct { + bdrkreg_t i_reserved : 5; + bdrkreg_t i_tt_init : 3; + bdrkreg_t i_tt_device : 7; + bdrkreg_t i_rqcnt_ge_2 : 1; + bdrkreg_t i_rqcnt_lt_2 : 1; + bdrkreg_t i_rqcnt_ge_18 : 1; + bdrkreg_t i_rqcnt_lt_18 : 1; + bdrkreg_t i_rpcnt_ge_2 : 1; + bdrkreg_t i_rpcnt_lt_2 : 1; + bdrkreg_t i_rpcnt_ge_18 : 1; + bdrkreg_t i_rpcnt_lt_18 : 1; + bdrkreg_t i_rpcnt_ge_34 : 1; + bdrkreg_t i_rpcnt_lt_34 : 1; + bdrkreg_t i_match : 1; + bdrkreg_t i_cbn : 1; + bdrkreg_t i_tt_bte_num : 1; + bdrkreg_t i_tt_respreqd : 1; + bdrkreg_t i_tt_use_old : 1; + bdrkreg_t i_tt_imsgtype : 2; + bdrkreg_t i_tt_imsg : 8; + bdrkreg_t i_g_stall_ib : 1; + bdrkreg_t i_g_stall_il : 1; + bdrkreg_t i_g_stall_bte0 : 1; + bdrkreg_t i_g_stall_bte1 : 1; + bdrkreg_t i_tt_intvn : 1; + bdrkreg_t i_tt_resp : 1; + bdrkreg_t i_tt_ack : 1; + bdrkreg_t i_tt_hold : 1; + bdrkreg_t i_tt_wb : 1; + bdrkreg_t i_tt_exc : 5; + bdrkreg_t i_plusg : 1; + bdrkreg_t i_plusz : 1; + bdrkreg_t i_mnusz : 1; + bdrkreg_t i_mnusg : 1; + bdrkreg_t i_sync : 1; + bdrkreg_t i_ft_active_o : 1; + bdrkreg_t i_ft_wact_o : 1; + bdrkreg_t i_ft_cwact_o : 1; + bdrkreg_t i_xerr : 1; + bdrkreg_t i_tt_vld : 1; + } ii_icsmh_fld_s; +} ii_icsmh_u_t; + +#endif + + +/************************************************************************ + * * + * The Bedrock DEBUG unit provides a 3-bit selection signal to the * + * II unit, thus allowing a choice of one set of debug signal outputs * + * from a menu of 8 options. Each option is limited to 32 bits in * + * size. There are more signals of interest than can be accommodated * + * in this 8*32 framework, so the IDBSS register has been defined to * + * extend the range of choices available. For each menu option * + * available to the DEBUG unit, the II provides a "submenu" of * + * several options. The value of the SUBMENU field in the IDBSS * + * register selects the desired submenu. Hence, the particular debug * + * signals provided by the II are determined by the 3-bit selection * + * signal from the DEBUG unit and the value of the SUBMENU field * + * within the IDBSS register. For a detailed description of the * + * available menus and submenus for II debug signals, refer to the * + * documentation in ii_interface.doc.. * + * * + ************************************************************************/ + + + + +#ifdef LIITLE_ENDIAN + +typedef union ii_idbss_u { + bdrkreg_t ii_idbss_regval; + struct { + bdrkreg_t i_submenu : 3; + bdrkreg_t i_rsvd : 61; + } ii_idbss_fld_s; +} ii_idbss_u_t; + +#else + +typedef union ii_idbss_u { + bdrkreg_t ii_idbss_regval; + struct { + bdrkreg_t i_rsvd : 61; + bdrkreg_t i_submenu : 3; + } ii_idbss_fld_s; +} ii_idbss_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register is used to set up the length for a * + * transfer and then to monitor the progress of that transfer. This * + * register needs to be initialized before a transfer is started. A * + * legitimate write to this register will set the Busy bit, clear the * + * Error bit, and initialize the length to the value desired. * + * While the transfer is in progress, hardware will decrement the * + * length field with each successful block that is copied. Once the * + * transfer completes, hardware will clear the Busy bit. The length * + * field will also contain the number of cache lines left to be * + * transferred. * + * * + ************************************************************************/ + + + + +#ifdef LIITLE_ENDIAN + +typedef union ii_ibls0_u { + bdrkreg_t ii_ibls0_regval; + struct { + bdrkreg_t i_length : 16; + bdrkreg_t i_error : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_busy : 1; + bdrkreg_t i_rsvd : 43; + } ii_ibls0_fld_s; +} ii_ibls0_u_t; + +#else + +typedef union ii_ibls0_u { + bdrkreg_t ii_ibls0_regval; + struct { + bdrkreg_t i_rsvd : 43; + bdrkreg_t i_busy : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_error : 1; + bdrkreg_t i_length : 16; + } ii_ibls0_fld_s; +} ii_ibls0_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibsa0_u { + bdrkreg_t ii_ibsa0_regval; + struct { + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd : 24; + } ii_ibsa0_fld_s; +} ii_ibsa0_u_t; + +#else + +typedef union ii_ibsa0_u { + bdrkreg_t ii_ibsa0_regval; + struct { + bdrkreg_t i_rsvd : 24; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd_1 : 7; + } ii_ibsa0_fld_s; +} ii_ibsa0_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibda0_u { + bdrkreg_t ii_ibda0_regval; + struct { + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd : 24; + } ii_ibda0_fld_s; +} ii_ibda0_u_t; + +#else + +typedef union ii_ibda0_u { + bdrkreg_t ii_ibda0_regval; + struct { + bdrkreg_t i_rsvd : 24; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd_1 : 7; + } ii_ibda0_fld_s; +} ii_ibda0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Writing to this register sets up the attributes of the transfer * + * and initiates the transfer operation. Reading this register has * + * the side effect of terminating any transfer in progress. Note: * + * stopping a transfer midstream could have an adverse impact on the * + * other BTE. If a BTE stream has to be stopped (due to error * + * handling for example), both BTE streams should be stopped and * + * their transfers discarded. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibct0_u { + bdrkreg_t ii_ibct0_regval; + struct { + bdrkreg_t i_zerofill : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_notify : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_poison : 1; + bdrkreg_t i_rsvd : 55; + } ii_ibct0_fld_s; +} ii_ibct0_u_t; + +#else + +typedef union ii_ibct0_u { + bdrkreg_t ii_ibct0_regval; + struct { + bdrkreg_t i_rsvd : 55; + bdrkreg_t i_poison : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_notify : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_zerofill : 1; + } ii_ibct0_fld_s; +} ii_ibct0_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the address to which the WINV is sent. * + * This address has to be cache line aligned. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibna0_u { + bdrkreg_t ii_ibna0_regval; + struct { + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd : 24; + } ii_ibna0_fld_s; +} ii_ibna0_u_t; + +#else + +typedef union ii_ibna0_u { + bdrkreg_t ii_ibna0_regval; + struct { + bdrkreg_t i_rsvd : 24; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd_1 : 7; + } ii_ibna0_fld_s; +} ii_ibna0_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the programmable level as well as the node * + * ID and PI unit of the processor to which the interrupt will be * + * sent. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibia0_u { + bdrkreg_t ii_ibia0_regval; + struct { + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_node_id : 8; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_level : 7; + bdrkreg_t i_rsvd : 41; + } ii_ibia0_fld_s; +} ii_ibia0_u_t; + +#else + +typedef union ii_ibia0_u { + bdrkreg_t ii_ibia0_regval; + struct { + bdrkreg_t i_rsvd : 41; + bdrkreg_t i_level : 7; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_node_id : 8; + bdrkreg_t i_pi_id : 1; + } ii_ibia0_fld_s; +} ii_ibia0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register is used to set up the length for a * + * transfer and then to monitor the progress of that transfer. This * + * register needs to be initialized before a transfer is started. A * + * legitimate write to this register will set the Busy bit, clear the * + * Error bit, and initialize the length to the value desired. * + * While the transfer is in progress, hardware will decrement the * + * length field with each successful block that is copied. Once the * + * transfer completes, hardware will clear the Busy bit. The length * + * field will also contain the number of cache lines left to be * + * transferred. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibls1_u { + bdrkreg_t ii_ibls1_regval; + struct { + bdrkreg_t i_length : 16; + bdrkreg_t i_error : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_busy : 1; + bdrkreg_t i_rsvd : 43; + } ii_ibls1_fld_s; +} ii_ibls1_u_t; + +#else + +typedef union ii_ibls1_u { + bdrkreg_t ii_ibls1_regval; + struct { + bdrkreg_t i_rsvd : 43; + bdrkreg_t i_busy : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_error : 1; + bdrkreg_t i_length : 16; + } ii_ibls1_fld_s; +} ii_ibls1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibsa1_u { + bdrkreg_t ii_ibsa1_regval; + struct { + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd : 24; + } ii_ibsa1_fld_s; +} ii_ibsa1_u_t; + +#else + +typedef union ii_ibsa1_u { + bdrkreg_t ii_ibsa1_regval; + struct { + bdrkreg_t i_rsvd : 24; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd_1 : 7; + } ii_ibsa1_fld_s; +} ii_ibsa1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibda1_u { + bdrkreg_t ii_ibda1_regval; + struct { + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd : 24; + } ii_ibda1_fld_s; +} ii_ibda1_u_t; + +#else + +typedef union ii_ibda1_u { + bdrkreg_t ii_ibda1_regval; + struct { + bdrkreg_t i_rsvd : 24; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd_1 : 7; + } ii_ibda1_fld_s; +} ii_ibda1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Writing to this register sets up the attributes of the transfer * + * and initiates the transfer operation. Reading this register has * + * the side effect of terminating any transfer in progress. Note: * + * stopping a transfer midstream could have an adverse impact on the * + * other BTE. If a BTE stream has to be stopped (due to error * + * handling for example), both BTE streams should be stopped and * + * their transfers discarded. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibct1_u { + bdrkreg_t ii_ibct1_regval; + struct { + bdrkreg_t i_zerofill : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_notify : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_poison : 1; + bdrkreg_t i_rsvd : 55; + } ii_ibct1_fld_s; +} ii_ibct1_u_t; + +#else + +typedef union ii_ibct1_u { + bdrkreg_t ii_ibct1_regval; + struct { + bdrkreg_t i_rsvd : 55; + bdrkreg_t i_poison : 1; + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_notify : 1; + bdrkreg_t i_rsvd_2 : 3; + bdrkreg_t i_zerofill : 1; + } ii_ibct1_fld_s; +} ii_ibct1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the address to which the WINV is sent. * + * This address has to be cache line aligned. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibna1_u { + bdrkreg_t ii_ibna1_regval; + struct { + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd : 24; + } ii_ibna1_fld_s; +} ii_ibna1_u_t; + +#else + +typedef union ii_ibna1_u { + bdrkreg_t ii_ibna1_regval; + struct { + bdrkreg_t i_rsvd : 24; + bdrkreg_t i_addr : 33; + bdrkreg_t i_rsvd_1 : 7; + } ii_ibna1_fld_s; +} ii_ibna1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the programmable level as well as the node * + * ID and PI unit of the processor to which the interrupt will be * + * sent. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ibia1_u { + bdrkreg_t ii_ibia1_regval; + struct { + bdrkreg_t i_pi_id : 1; + bdrkreg_t i_node_id : 8; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_level : 7; + bdrkreg_t i_rsvd : 41; + } ii_ibia1_fld_s; +} ii_ibia1_u_t; + +#else + +typedef union ii_ibia1_u { + bdrkreg_t ii_ibia1_regval; + struct { + bdrkreg_t i_rsvd : 41; + bdrkreg_t i_level : 7; + bdrkreg_t i_rsvd_1 : 7; + bdrkreg_t i_node_id : 8; + bdrkreg_t i_pi_id : 1; + } ii_ibia1_fld_s; +} ii_ibia1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register defines the resources that feed information into * + * the two performance counters located in the IO Performance * + * Profiling Register. There are 17 different quantities that can be * + * measured. Given these 17 different options, the two performance * + * counters have 15 of them in common; menu selections 0 through 0xE * + * are identical for each performance counter. As for the other two * + * options, one is available from one performance counter and the * + * other is available from the other performance counter. Hence, the * + * II supports all 17*16=272 possible combinations of quantities to * + * measure. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ipcr_u { + bdrkreg_t ii_ipcr_regval; + struct { + bdrkreg_t i_ippr0_c : 4; + bdrkreg_t i_ippr1_c : 4; + bdrkreg_t i_icct : 8; + bdrkreg_t i_rsvd : 48; + } ii_ipcr_fld_s; +} ii_ipcr_u_t; + +#else + +typedef union ii_ipcr_u { + bdrkreg_t ii_ipcr_regval; + struct { + bdrkreg_t i_rsvd : 48; + bdrkreg_t i_icct : 8; + bdrkreg_t i_ippr1_c : 4; + bdrkreg_t i_ippr0_c : 4; + } ii_ipcr_fld_s; +} ii_ipcr_u_t; + +#endif + + + + +/************************************************************************ + * * + * * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ii_ippr_u { + bdrkreg_t ii_ippr_regval; + struct { + bdrkreg_t i_ippr0 : 32; + bdrkreg_t i_ippr1 : 32; + } ii_ippr_fld_s; +} ii_ippr_u_t; + +#else + +typedef union ii_ippr_u { + bdrkreg_t ii_ippr_regval; + struct { + bdrkreg_t i_ippr1 : 32; + bdrkreg_t i_ippr0 : 32; + } ii_ippr_fld_s; +} ii_ippr_u_t; + +#endif + + + + + + +#endif /* _LANGUAGE_C */ + +/************************************************************************ + * * + * The following defines which were not formed into structures are * + * probably indentical to another register, and the name of the * + * register is provided against each of these registers. This * + * information needs to be checked carefully * + * * + * IIO_ICRB1_A IIO_ICRB0_A * + * IIO_ICRB1_B IIO_ICRB0_B * + * IIO_ICRB1_C IIO_ICRB0_C * + * IIO_ICRB1_D IIO_ICRB0_D * + * IIO_ICRB2_A IIO_ICRB0_A * + * IIO_ICRB2_B IIO_ICRB0_B * + * IIO_ICRB2_C IIO_ICRB0_C * + * IIO_ICRB2_D IIO_ICRB0_D * + * IIO_ICRB3_A IIO_ICRB0_A * + * IIO_ICRB3_B IIO_ICRB0_B * + * IIO_ICRB3_C IIO_ICRB0_C * + * IIO_ICRB3_D IIO_ICRB0_D * + * IIO_ICRB4_A IIO_ICRB0_A * + * IIO_ICRB4_B IIO_ICRB0_B * + * IIO_ICRB4_C IIO_ICRB0_C * + * IIO_ICRB4_D IIO_ICRB0_D * + * IIO_ICRB5_A IIO_ICRB0_A * + * IIO_ICRB5_B IIO_ICRB0_B * + * IIO_ICRB5_C IIO_ICRB0_C * + * IIO_ICRB5_D IIO_ICRB0_D * + * IIO_ICRB6_A IIO_ICRB0_A * + * IIO_ICRB6_B IIO_ICRB0_B * + * IIO_ICRB6_C IIO_ICRB0_C * + * IIO_ICRB6_D IIO_ICRB0_D * + * IIO_ICRB7_A IIO_ICRB0_A * + * IIO_ICRB7_B IIO_ICRB0_B * + * IIO_ICRB7_C IIO_ICRB0_C * + * IIO_ICRB7_D IIO_ICRB0_D * + * IIO_ICRB8_A IIO_ICRB0_A * + * IIO_ICRB8_B IIO_ICRB0_B * + * IIO_ICRB8_C IIO_ICRB0_C * + * IIO_ICRB8_D IIO_ICRB0_D * + * IIO_ICRB9_A IIO_ICRB0_A * + * IIO_ICRB9_B IIO_ICRB0_B * + * IIO_ICRB9_C IIO_ICRB0_C * + * IIO_ICRB9_D IIO_ICRB0_D * + * IIO_ICRBA_A IIO_ICRB0_A * + * IIO_ICRBA_B IIO_ICRB0_B * + * IIO_ICRBA_C IIO_ICRB0_C * + * IIO_ICRBA_D IIO_ICRB0_D * + * IIO_ICRBB_A IIO_ICRB0_A * + * IIO_ICRBB_B IIO_ICRB0_B * + * IIO_ICRBB_C IIO_ICRB0_C * + * IIO_ICRBB_D IIO_ICRB0_D * + * IIO_ICRBC_A IIO_ICRB0_A * + * IIO_ICRBC_B IIO_ICRB0_B * + * IIO_ICRBC_C IIO_ICRB0_C * + * IIO_ICRBC_D IIO_ICRB0_D * + * IIO_ICRBD_A IIO_ICRB0_A * + * IIO_ICRBD_B IIO_ICRB0_B * + * IIO_ICRBD_C IIO_ICRB0_C * + * IIO_ICRBD_D IIO_ICRB0_D * + * IIO_ICRBE_A IIO_ICRB0_A * + * IIO_ICRBE_B IIO_ICRB0_B * + * IIO_ICRBE_C IIO_ICRB0_C * + * IIO_ICRBE_D IIO_ICRB0_D * + * * + ************************************************************************/ + + +/************************************************************************ + * * + * MAKE ALL ADDITIONS AFTER THIS LINE * + * * + ************************************************************************/ + + + + + +#endif /* _ASM_SN_SN1_HUBIO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubio_next.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubio_next.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubio_next.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubio_next.h Wed Dec 13 19:35:00 2000 @@ -0,0 +1,714 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBIO_NEXT_H +#define _ASM_SN_SN1_HUBIO_NEXT_H + +/* + * Slightly friendlier names for some common registers. + */ +#define IIO_WIDGET IIO_WID /* Widget identification */ +#define IIO_WIDGET_STAT IIO_WSTAT /* Widget status register */ +#define IIO_WIDGET_CTRL IIO_WCR /* Widget control register */ +#define IIO_PROTECT IIO_ILAPR /* IO interface protection */ +#define IIO_PROTECT_OVRRD IIO_ILAPO /* IO protect override */ +#define IIO_OUTWIDGET_ACCESS IIO_IOWA /* Outbound widget access */ +#define IIO_INWIDGET_ACCESS IIO_IIWA /* Inbound widget access */ +#define IIO_INDEV_ERR_MASK IIO_IIDEM /* Inbound device error mask */ +#define IIO_LLP_CSR IIO_ILCSR /* LLP control and status */ +#define IIO_LLP_LOG IIO_ILLR /* LLP log */ +#define IIO_XTALKCC_TOUT IIO_IXCC /* Xtalk credit count timeout*/ +#define IIO_XTALKTT_TOUT IIO_IXTT /* Xtalk tail timeout */ +#define IIO_IO_ERR_CLR IIO_IECLR /* IO error clear */ +#define IIO_IGFX_0 IIO_IGFX0 +#define IIO_IGFX_1 IIO_IGFX1 +#define IIO_IBCT_0 IIO_IBCT0 +#define IIO_IBCT_1 IIO_IBCT1 +#define IIO_IBLS_0 IIO_IBLS0 +#define IIO_IBLS_1 IIO_IBLS1 +#define IIO_IBSA_0 IIO_IBSA0 +#define IIO_IBSA_1 IIO_IBSA1 +#define IIO_IBDA_0 IIO_IBDA0 +#define IIO_IBDA_1 IIO_IBDA1 +#define IIO_IBNA_0 IIO_IBNA0 +#define IIO_IBNA_1 IIO_IBNA1 +#define IIO_IBIA_0 IIO_IBIA0 +#define IIO_IBIA_1 IIO_IBIA1 +#define IIO_IOPRB_0 IIO_IPRB0 +#define IIO_PRTE_0 IIO_IPRTE0 /* PIO Read address table entry 0 */ +#define IIO_PRTE(_x) (IIO_PRTE_0 + (8 * (_x))) + +#define IIO_LLP_CSR_IS_UP 0x00002000 +#define IIO_LLP_CSR_LLP_STAT_MASK 0x00003000 +#define IIO_LLP_CSR_LLP_STAT_SHFT 12 + +#define IIO_LLP_CB_MAX 0xffff /* in ILLR CB_CNT, Max Check Bit errors */ +#define IIO_LLP_SN_MAX 0xffff /* in ILLR SN_CNT, Max Sequence Number errors */ + +/* key to IIO_PROTECT_OVRRD */ +#define IIO_PROTECT_OVRRD_KEY 0x53474972756c6573ull /* "SGIrules" */ + +/* BTE register names */ +#define IIO_BTE_STAT_0 IIO_IBLS_0 /* Also BTE length/status 0 */ +#define IIO_BTE_SRC_0 IIO_IBSA_0 /* Also BTE source address 0 */ +#define IIO_BTE_DEST_0 IIO_IBDA_0 /* Also BTE dest. address 0 */ +#define IIO_BTE_CTRL_0 IIO_IBCT_0 /* Also BTE control/terminate 0 */ +#define IIO_BTE_NOTIFY_0 IIO_IBNA_0 /* Also BTE notification 0 */ +#define IIO_BTE_INT_0 IIO_IBIA_0 /* Also BTE interrupt 0 */ +#define IIO_BTE_OFF_0 0 /* Base offset from BTE 0 regs. */ +#define IIO_BTE_OFF_1 IIO_IBLS_1 - IIO_IBLS_0 /* Offset from base to BTE 1 */ + +/* BTE register offsets from base */ +#define BTEOFF_STAT 0 +#define BTEOFF_SRC (IIO_BTE_SRC_0 - IIO_BTE_STAT_0) +#define BTEOFF_DEST (IIO_BTE_DEST_0 - IIO_BTE_STAT_0) +#define BTEOFF_CTRL (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0) +#define BTEOFF_NOTIFY (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0) +#define BTEOFF_INT (IIO_BTE_INT_0 - IIO_BTE_STAT_0) + + +/* names used in hub_diags.c; carried over from SN0 */ +#define IIO_BASE_BTE0 IIO_IBLS_0 +#define IIO_BASE_BTE1 IIO_IBLS_1 +#if 0 +#define IIO_BASE IIO_WID +#define IIO_BASE_PERF IIO_IPCR /* IO Performance Control */ +#define IIO_PERF_CNT IIO_IPPR /* IO Performance Profiling */ +#endif + + +/* GFX Flow Control Node/Widget Register */ +#define IIO_IGFX_W_NUM_BITS 4 /* size of widget num field */ +#define IIO_IGFX_W_NUM_MASK ((1<> IIO_WSTAT_TXRETRY_SHFT) & \ + IIO_WSTAT_TXRETRY_MASK) + +/* Number of II perf. counters we can multiplex at once */ + +#define IO_PERF_SETS 32 + +#ifdef BRINGUP +#if __KERNEL__ +#if _LANGUAGE_C +/* XXX moved over from SN/SN0/hubio.h -- each should be checked for SN1 */ +#include +#include +#include +#include + +/* Bit for the widget in inbound access register */ +#define IIO_IIWA_WIDGET(_w) ((uint64_t)(1ULL << _w)) +/* Bit for the widget in outbound access register */ +#define IIO_IOWA_WIDGET(_w) ((uint64_t)(1ULL << _w)) + +/* NOTE: The following define assumes that we are going to get + * widget numbers from 8 thru F and the device numbers within + * widget from 0 thru 7. + */ +#define IIO_IIDEM_WIDGETDEV_MASK(w, d) ((uint64_t)(1ULL << (8 * ((w) - 8) + (d)))) + +/* IO Interrupt Destination Register */ +#define IIO_IIDSR_SENT_SHIFT 28 +#define IIO_IIDSR_SENT_MASK 0x10000000 +#define IIO_IIDSR_ENB_SHIFT 24 +#define IIO_IIDSR_ENB_MASK 0x01000000 +#define IIO_IIDSR_NODE_SHIFT 8 +#define IIO_IIDSR_NODE_MASK 0x0000ff00 +#define IIO_IIDSR_PI_ID_SHIFT 8 +#define IIO_IIDSR_PI_ID_MASK 0x00000010 +#define IIO_IIDSR_LVL_SHIFT 0 +#define IIO_IIDSR_LVL_MASK 0x0000007f + +/* Xtalk timeout threshhold register (IIO_IXTT) */ +#define IXTT_RRSP_TO_SHFT 55 /* read response timeout */ +#define IXTT_RRSP_TO_MASK (0x1FULL << IXTT_RRSP_TO_SHFT) +#define IXTT_RRSP_PS_SHFT 32 /* read responsed TO prescalar */ +#define IXTT_RRSP_PS_MASK (0x7FFFFFULL << IXTT_RRSP_PS_SHFT) +#define IXTT_TAIL_TO_SHFT 0 /* tail timeout counter threshold */ +#define IXTT_TAIL_TO_MASK (0x3FFFFFFULL << IXTT_TAIL_TO_SHFT) + +/* + * The IO LLP control status register and widget control register + */ + +#ifdef LITTLE_ENDIAN + +typedef union hubii_wcr_u { + uint64_t wcr_reg_value; + struct { + uint64_t wcr_widget_id: 4, /* LLP crossbar credit */ + wcr_tag_mode: 1, /* Tag mode */ + wcr_rsvd1: 8, /* Reserved */ + wcr_xbar_crd: 3, /* LLP crossbar credit */ + wcr_f_bad_pkt: 1, /* Force bad llp pkt enable */ + wcr_dir_con: 1, /* widget direct connect */ + wcr_e_thresh: 5, /* elasticity threshold */ + wcr_rsvd: 41; /* unused */ + } wcr_fields_s; +} hubii_wcr_t; + +#else + +typedef union hubii_wcr_u { + uint64_t wcr_reg_value; + struct { + uint64_t wcr_rsvd: 41, /* unused */ + wcr_e_thresh: 5, /* elasticity threshold */ + wcr_dir_con: 1, /* widget direct connect */ + wcr_f_bad_pkt: 1, /* Force bad llp pkt enable */ + wcr_xbar_crd: 3, /* LLP crossbar credit */ + wcr_rsvd1: 8, /* Reserved */ + wcr_tag_mode: 1, /* Tag mode */ + wcr_widget_id: 4; /* LLP crossbar credit */ + } wcr_fields_s; +} hubii_wcr_t; + +#endif + +#define iwcr_dir_con wcr_fields_s.wcr_dir_con + +/* The structures below are defined to extract and modify the ii +performance registers */ + +/* io_perf_sel allows the caller to specify what tests will be + performed */ +#ifdef LITTLE_ENDIAN + +typedef union io_perf_sel { + uint64_t perf_sel_reg; + struct { + uint64_t perf_ippr0 : 4, + perf_ippr1 : 4, + perf_icct : 8, + perf_rsvd : 48; + } perf_sel_bits; +} io_perf_sel_t; + +#else + +typedef union io_perf_sel { + uint64_t perf_sel_reg; + struct { + uint64_t perf_rsvd : 48, + perf_icct : 8, + perf_ippr1 : 4, + perf_ippr0 : 4; + } perf_sel_bits; +} io_perf_sel_t; + +#endif + +/* io_perf_cnt is to extract the count from the hub registers. Due to + hardware problems there is only one counter, not two. */ + +#ifdef LITTLE_ENDIAN + +typedef union io_perf_cnt { + uint64_t perf_cnt; + struct { + uint64_t perf_cnt : 20, + perf_rsvd2 : 12, + perf_rsvd1 : 32; + } perf_cnt_bits; + +} io_perf_cnt_t; + +#else + +typedef union io_perf_cnt { + uint64_t perf_cnt; + struct { + uint64_t perf_rsvd1 : 32, + perf_rsvd2 : 12, + perf_cnt : 20; + } perf_cnt_bits; + +} io_perf_cnt_t; + +#endif + +#ifdef LITTLE_ENDIAN + +typedef union iprte_a { + bdrkreg_t entry; + struct { + bdrkreg_t i_rsvd_1 : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_init : 3; + bdrkreg_t i_source : 8; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_widget : 4; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_vld : 1; + } iprte_fields; +} iprte_a_t; + +#else + +typedef union iprte_a { + bdrkreg_t entry; + struct { + bdrkreg_t i_vld : 1; + bdrkreg_t i_to_cnt : 5; + bdrkreg_t i_widget : 4; + bdrkreg_t i_rsvd : 2; + bdrkreg_t i_source : 8; + bdrkreg_t i_init : 3; + bdrkreg_t i_addr : 38; + bdrkreg_t i_rsvd_1 : 3; + } iprte_fields; +} iprte_a_t; + +#endif + +/* PIO MANAGEMENT */ +typedef struct hub_piomap_s *hub_piomap_t; + +extern hub_piomap_t +hub_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ + size_t byte_count, + size_t byte_count_max, /* maximum size of a mapping */ + unsigned flags); /* defined in sys/pio.h */ + +extern void hub_piomap_free(hub_piomap_t hub_piomap); + +extern caddr_t +hub_piomap_addr(hub_piomap_t hub_piomap, /* mapping resources */ + iopaddr_t xtalk_addr, /* map for this xtalk addr */ + size_t byte_count); /* map this many bytes */ + +extern void +hub_piomap_done(hub_piomap_t hub_piomap); + +extern caddr_t +hub_piotrans_addr( devfs_handle_t dev, /* translate to this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* Crosstalk address */ + size_t byte_count, /* map this many bytes */ + unsigned flags); /* (currently unused) */ + +/* DMA MANAGEMENT */ +typedef struct hub_dmamap_s *hub_dmamap_t; + +extern hub_dmamap_t +hub_dmamap_alloc( devfs_handle_t dev, /* set up mappings for dev */ + device_desc_t dev_desc, /* device descriptor */ + size_t byte_count_max, /* max size of a mapping */ + unsigned flags); /* defined in dma.h */ + +extern void +hub_dmamap_free(hub_dmamap_t dmamap); + +extern iopaddr_t +hub_dmamap_addr( hub_dmamap_t dmamap, /* use mapping resources */ + paddr_t paddr, /* map for this address */ + size_t byte_count); /* map this many bytes */ + +extern alenlist_t +hub_dmamap_list( hub_dmamap_t dmamap, /* use mapping resources */ + alenlist_t alenlist, /* map this Addr/Length List */ + unsigned flags); + +extern void +hub_dmamap_done( hub_dmamap_t dmamap); /* done w/ mapping resources */ + +extern iopaddr_t +hub_dmatrans_addr( devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + unsigned flags); /* defined in dma.h */ + +extern alenlist_t +hub_dmatrans_list( devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + alenlist_t palenlist, /* system addr/length list */ + unsigned flags); /* defined in dma.h */ + +extern void +hub_dmamap_drain( hub_dmamap_t map); + +extern void +hub_dmaaddr_drain( devfs_handle_t vhdl, + paddr_t addr, + size_t bytes); + +extern void +hub_dmalist_drain( devfs_handle_t vhdl, + alenlist_t list); + + +/* INTERRUPT MANAGEMENT */ +typedef struct hub_intr_s *hub_intr_t; + +extern hub_intr_t +hub_intr_alloc( devfs_handle_t dev, /* which device */ + device_desc_t dev_desc, /* device descriptor */ + devfs_handle_t owner_dev); /* owner of this interrupt */ + +extern void +hub_intr_free(hub_intr_t intr_hdl); + +extern int +hub_intr_connect( hub_intr_t intr_hdl, /* xtalk intr resource hndl */ + intr_func_t intr_func, /* xtalk intr handler */ + void *intr_arg, /* arg to intr handler */ + xtalk_intr_setfunc_t setfunc, + /* func to set intr hw */ + void *setfunc_arg, /* arg to setfunc */ + void *thread); /* intr thread to use */ + +extern void +hub_intr_disconnect(hub_intr_t intr_hdl); + +extern devfs_handle_t +hub_intr_cpu_get(hub_intr_t intr_hdl); + +/* CONFIGURATION MANAGEMENT */ + +extern void +hub_provider_startup(devfs_handle_t hub); + +extern void +hub_provider_shutdown(devfs_handle_t hub); + +#define HUB_PIO_CONVEYOR 0x1 /* PIO in conveyor belt mode */ +#define HUB_PIO_FIRE_N_FORGET 0x2 /* PIO in fire-and-forget mode */ + +/* Flags that make sense to hub_widget_flags_set */ +#define HUB_WIDGET_FLAGS ( \ + HUB_PIO_CONVEYOR | \ + HUB_PIO_FIRE_N_FORGET \ + ) + + +typedef int hub_widget_flags_t; + +/* Set the PIO mode for a widget. These two functions perform the + * same operation, but hub_device_flags_set() takes a hardware graph + * vertex while hub_widget_flags_set() takes a nasid and widget + * number. In most cases, hub_device_flags_set() should be used. + */ +extern int hub_widget_flags_set(nasid_t nasid, + xwidgetnum_t widget_num, + hub_widget_flags_t flags); + +/* Depending on the flags set take the appropriate actions */ +extern int hub_device_flags_set(devfs_handle_t widget_dev, + hub_widget_flags_t flags); + + +/* Error Handling. */ +extern int hub_ioerror_handler(devfs_handle_t, int, int, struct io_error_s *); +extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t, + int, paddr_t, caddr_t, ioerror_mode_t); +extern void hub_widget_reset(devfs_handle_t, xwidgetnum_t); +extern int hub_error_devenable(devfs_handle_t, int, int); +extern void hub_widgetdev_enable(devfs_handle_t, int); +extern void hub_widgetdev_shutdown(devfs_handle_t, int); +extern int hub_dma_enabled(devfs_handle_t); + +#endif /* _LANGUAGE_C */ +#endif /* _KERNEL */ +#endif /* BRINGUP */ +#endif /* _ASM_SN_SN1_HUBIO_NEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hublb.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hublb.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hublb.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hublb.h Wed Dec 6 21:56:13 2000 @@ -0,0 +1,1608 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/************************************************************************ + * * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! * + * * + * This file is created by an automated script. Any (minimal) changes * + * made manually to this file should be made with care. * + * * + * MAKE ALL ADDITIONS TO THE END OF THIS FILE * + * * + ************************************************************************/ + + +#ifndef _ASM_SN_SN1_HUBLB_H +#define _ASM_SN_SN1_HUBLB_H + + +#define LB_REV_ID 0x00600000 /* + * Bedrock Revision + * and ID + */ + + + +#define LB_CPU_PERMISSION 0x00604000 /* + * CPU PIO access + * permission bits + */ + + + +#define LB_CPU_PERM_OVRRD 0x00604008 /* + * CPU PIO access + * permission bit + * override + */ + + + +#define LB_IO_PERMISSION 0x00604010 /* + * IO PIO access + * permission bits + */ + + + +#define LB_SOFT_RESET 0x00604018 /* + * Soft reset the + * Bedrock chip + */ + + + +#define LB_REGION_PRESENT 0x00604020 /* + * Regions Present for + * Invalidates + */ + + + +#define LB_NODES_ABSENT 0x00604028 /* + * Nodes Absent for + * Invalidates + */ + + + +#define LB_MICROLAN_CTL 0x00604030 /* + * Microlan Control + * (NIC) + */ + + + +#define LB_ERROR_BITS 0x00604040 /* + * Local Block error + * bits + */ + + + +#define LB_ERROR_MASK_CLR 0x00604048 /* + * Bit mask write to + * clear error bits + */ + + + +#define LB_ERROR_HDR1 0x00604050 /* + * Source, Suppl and + * Cmd fields + */ + + + +#define LB_ERROR_HDR2 0x00604058 /* + * Address field from + * first error + */ + + + +#define LB_ERROR_DATA 0x00604060 /* + * Data flit (if any) + * from first error + */ + + + +#define LB_DEBUG_SELECT 0x00604100 /* + * Choice of debug + * signals from chip + */ + + + +#define LB_DEBUG_PINS 0x00604108 /* + * Value on the chip's + * debug pins + */ + + + +#define LB_RT_LOCAL_CTRL 0x00604200 /* + * Local generation of + * real-time clock + */ + + + +#define LB_RT_FILTER_CTRL 0x00604208 /* + * Control of + * filtering of global + * clock + */ + + + +#define LB_SCRATCH_REG0 0x00608000 /* Scratch Register 0 */ + + + +#define LB_SCRATCH_REG1 0x00608008 /* Scratch Register 1 */ + + + +#define LB_SCRATCH_REG2 0x00608010 /* Scratch Register 2 */ + + + +#define LB_SCRATCH_REG3 0x00608018 /* Scratch Register 3 */ + + + +#define LB_SCRATCH_REG4 0x00608020 /* Scratch Register 4 */ + + + +#define LB_SCRATCH_REG0_WZ 0x00608040 /* + * Scratch Register 0 + * (WZ alias) + */ + + + +#define LB_SCRATCH_REG1_WZ 0x00608048 /* + * Scratch Register 1 + * (WZ alias) + */ + + + +#define LB_SCRATCH_REG2_WZ 0x00608050 /* + * Scratch Register 2 + * (WZ alias) + */ + + + +#define LB_SCRATCH_REG3_RZ 0x00608058 /* + * Scratch Register 3 + * (RZ alias) + */ + + + +#define LB_SCRATCH_REG4_RZ 0x00608060 /* + * Scratch Register 4 + * (RZ alias) + */ + + + +#define LB_VECTOR_PARMS 0x0060C000 /* + * Vector PIO + * parameters + */ + + + +#define LB_VECTOR_ROUTE 0x0060C008 /* + * Vector PIO Vector + * Route + */ + + + +#define LB_VECTOR_DATA 0x0060C010 /* + * Vector PIO Write + * Data + */ + + + +#define LB_VECTOR_STATUS 0x0060C020 /* + * Vector PIO Return + * Status + */ + + + +#define LB_VECTOR_RETURN 0x0060C028 /* + * Vector PIO Return + * Route + */ + + + +#define LB_VECTOR_READ_DATA 0x0060C030 /* + * Vector PIO Read + * Data + */ + + + +#define LB_VECTOR_STATUS_CLEAR 0x0060C038 /* + * Clear Vector PIO + * Return Status + */ + + + + + +#ifdef _LANGUAGE_C + +/************************************************************************ + * * + * Description: This register contains information that allows * + * exploratory software to probe for chip type. This is also the * + * register that sets this node's ID and the size of each region * + * (which affects the maximum possible system size). IBM assigns the * + * values for the REVISION, PART_NUMBER and MANUFACTURER fields, in * + * accordance with the IEEE 1149.1 standard; SGI is not at liberty to * + * unilaterally change the values of these fields. * + * . * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_rev_id_u { + bdrkreg_t lb_rev_id_regval; + struct { + bdrkreg_t ri_reserved_2 : 1; + bdrkreg_t ri_manufacturer : 11; + bdrkreg_t ri_part_number : 16; + bdrkreg_t ri_revision : 4; + bdrkreg_t ri_node_id : 8; + bdrkreg_t ri_reserved_1 : 6; + bdrkreg_t ri_region_size : 2; + bdrkreg_t ri_reserved : 16; + } lb_rev_id_fld_s; +} lb_rev_id_u_t; + +#else + +typedef union lb_rev_id_u { + bdrkreg_t lb_rev_id_regval; + struct { + bdrkreg_t ri_reserved : 16; + bdrkreg_t ri_region_size : 2; + bdrkreg_t ri_reserved_1 : 6; + bdrkreg_t ri_node_id : 8; + bdrkreg_t ri_revision : 4; + bdrkreg_t ri_part_number : 16; + bdrkreg_t ri_manufacturer : 11; + bdrkreg_t ri_reserved_2 : 1; + } lb_rev_id_fld_s; +} lb_rev_id_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the PI-access-rights bit-vector for the * + * LB, NI, XB and MD portions of the Bedrock local register space. If * + * a bit in the bit-vector is set, the region corresponding to that * + * bit has read/write permission on the LB, NI, XB and MD local * + * registers. If the bit is clear, that region has no write access to * + * the local registers and no read access if the read will cause any * + * state change. If a write or a read with side effects is attempted * + * by a PI in a region for which access is restricted, the LB will * + * not perform the operation and will send back a reply which * + * indicates an error. * + * * + ************************************************************************/ + + + + +typedef union lb_cpu_permission_u { + bdrkreg_t lb_cpu_permission_regval; + struct { + bdrkreg_t cp_cpu_access : 64; + } lb_cpu_permission_fld_s; +} lb_cpu_permission_u_t; + + + + +/************************************************************************ + * * + * A write to this register of the 64-bit value "SGIrules" will * + * cause the bit in the LB_CPU_PROTECT register corresponding to the * + * region of the requester to be set. * + * * + ************************************************************************/ + + + + +typedef union lb_cpu_perm_ovrrd_u { + bdrkreg_t lb_cpu_perm_ovrrd_regval; + struct { + bdrkreg_t cpo_cpu_perm_ovr : 64; + } lb_cpu_perm_ovrrd_fld_s; +} lb_cpu_perm_ovrrd_u_t; + + + + +/************************************************************************ + * * + * This register contains the II-access-rights bit-vector for the * + * LB, NI, XB and MD portions of the Bedrock local register space. If * + * a bit in the bit-vector is set, the region corresponding to that * + * bit has read/write permission on the LB, NI, XB and MD local * + * registers. If the bit is clear, then that region has no write * + * access to the local registers and no read access if the read * + * results in any state change. If a write or a read with side * + * effects is attempted by an II in a region for which access is * + * restricted, the LB will not perform the operation and will send * + * back a reply which indicates an error. * + * * + ************************************************************************/ + + + + +typedef union lb_io_permission_u { + bdrkreg_t lb_io_permission_regval; + struct { + bdrkreg_t ip_io_permission : 64; + } lb_io_permission_fld_s; +} lb_io_permission_u_t; + + + + +/************************************************************************ + * * + * A write to this bit resets the Bedrock chip with a soft reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_soft_reset_u { + bdrkreg_t lb_soft_reset_regval; + struct { + bdrkreg_t sr_soft_reset : 1; + bdrkreg_t sr_reserved : 63; + } lb_soft_reset_fld_s; +} lb_soft_reset_u_t; + +#else + +typedef union lb_soft_reset_u { + bdrkreg_t lb_soft_reset_regval; + struct { + bdrkreg_t sr_reserved : 63; + bdrkreg_t sr_soft_reset : 1; + } lb_soft_reset_fld_s; +} lb_soft_reset_u_t; + +#endif + + + +/************************************************************************ + * * + * This register indicates which regions are present and capable of * + * receiving an invalidate (INVAL) request. The LB samples this * + * register at the start of processing each LINVAL. When an LINVAL * + * indicates that a particular PI unit might hold a shared copy of a * + * cache block but this PI is in a region which is not present (i.e., * + * its bit in LB_REGION_PRESENT is clear), then the LB sends an IVACK * + * reply packet on behalf of this PI. The REGION_SIZE field in the * + * LB_REV_ID register determines the number of nodes per region (and * + * hence, the number of PI units which share a common bit in the * + * LB_REGION_PRESENT register). * + * * + ************************************************************************/ + + + + +typedef union lb_region_present_u { + bdrkreg_t lb_region_present_regval; + struct { + bdrkreg_t rp_present_bits : 64; + } lb_region_present_fld_s; +} lb_region_present_u_t; + + + + +/************************************************************************ + * * + * Description: This register indicates which nodes are absent and * + * not capable of receiving an invalidate (INVAL) request. The LB * + * samples this register at the start of processing each LINVAL. When * + * an LINVAL indicates that a particular PI unit might hold a shared * + * copy of a cache block but this PI unit's node is not present * + * (i.e., its node ID is listed in the LB_NODES_ABSENT register), * + * then the LB sends an IVACK reply packet on behalf of this PI. * + * * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_nodes_absent_u { + bdrkreg_t lb_nodes_absent_regval; + struct { + bdrkreg_t na_node_0 : 8; + bdrkreg_t na_reserved_3 : 7; + bdrkreg_t na_node_0_valid : 1; + bdrkreg_t na_node_1 : 8; + bdrkreg_t na_reserved_2 : 7; + bdrkreg_t na_node_1_valid : 1; + bdrkreg_t na_node_2 : 8; + bdrkreg_t na_reserved_1 : 7; + bdrkreg_t na_node_2_valid : 1; + bdrkreg_t na_node_3 : 8; + bdrkreg_t na_reserved : 7; + bdrkreg_t na_node_3_valid : 1; + } lb_nodes_absent_fld_s; +} lb_nodes_absent_u_t; + +#else + +typedef union lb_nodes_absent_u { + bdrkreg_t lb_nodes_absent_regval; + struct { + bdrkreg_t na_node_3_valid : 1; + bdrkreg_t na_reserved : 7; + bdrkreg_t na_node_3 : 8; + bdrkreg_t na_node_2_valid : 1; + bdrkreg_t na_reserved_1 : 7; + bdrkreg_t na_node_2 : 8; + bdrkreg_t na_node_1_valid : 1; + bdrkreg_t na_reserved_2 : 7; + bdrkreg_t na_node_1 : 8; + bdrkreg_t na_node_0_valid : 1; + bdrkreg_t na_reserved_3 : 7; + bdrkreg_t na_node_0 : 8; + } lb_nodes_absent_fld_s; +} lb_nodes_absent_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register provides access to the Number-In-a-Can add-only * + * serial PROM that is used to store node board serial number and * + * configuration information. (Refer to NIC datasheet Dallas 1990A * + * that is viewable at * + * URL::http://www.dalsemi.com/DocControl/PDFs/pdfindex.html). Data * + * comes from this interface LSB first. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_microlan_ctl_u { + bdrkreg_t lb_microlan_ctl_regval; + struct { + bdrkreg_t mc_rd_data : 1; + bdrkreg_t mc_done : 1; + bdrkreg_t mc_sample : 8; + bdrkreg_t mc_pulse : 10; + bdrkreg_t mc_clkdiv_phi0 : 7; + bdrkreg_t mc_clkdiv_phi1 : 7; + bdrkreg_t mc_reserved : 30; + } lb_microlan_ctl_fld_s; +} lb_microlan_ctl_u_t; + +#else + +typedef union lb_microlan_ctl_u { + bdrkreg_t lb_microlan_ctl_regval; + struct { + bdrkreg_t mc_reserved : 30; + bdrkreg_t mc_clkdiv_phi1 : 7; + bdrkreg_t mc_clkdiv_phi0 : 7; + bdrkreg_t mc_pulse : 10; + bdrkreg_t mc_sample : 8; + bdrkreg_t mc_done : 1; + bdrkreg_t mc_rd_data : 1; + } lb_microlan_ctl_fld_s; +} lb_microlan_ctl_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register contains the LB error status bits. * + * Whenever a particular type of error occurs, the LB sets its bit in * + * this register so that software will be aware that such an event * + * has happened. Reads from this register are non-destructive and the * + * contents of this register remain intact across reset operations. * + * Whenever any of these bits is set, the LB will assert its * + * interrupt request output signals that go to the PI units. * + * Software can simulate the occurrence of an error by first writing * + * appropriate values into the LB_ERROR_HDR1, LB_ERROR_HDR2 and * + * LB_ERROR_DATA registers, and then writing to the LB_ERROR_BITS * + * register to set the error bits in a particular way. Setting one or * + * more error bits will cause the LB to interrupt a processor and * + * invoke error-handling software. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_error_bits_u { + bdrkreg_t lb_error_bits_regval; + struct { + bdrkreg_t eb_rq_bad_cmd : 1; + bdrkreg_t eb_rp_bad_cmd : 1; + bdrkreg_t eb_rq_short : 1; + bdrkreg_t eb_rp_short : 1; + bdrkreg_t eb_rq_long : 1; + bdrkreg_t eb_rp_long : 1; + bdrkreg_t eb_rq_bad_data : 1; + bdrkreg_t eb_rp_bad_data : 1; + bdrkreg_t eb_rq_bad_addr : 1; + bdrkreg_t eb_rq_bad_linval : 1; + bdrkreg_t eb_gclk_drop : 1; + bdrkreg_t eb_reserved : 53; + } lb_error_bits_fld_s; +} lb_error_bits_u_t; + +#else + +typedef union lb_error_bits_u { + bdrkreg_t lb_error_bits_regval; + struct { + bdrkreg_t eb_reserved : 53; + bdrkreg_t eb_gclk_drop : 1; + bdrkreg_t eb_rq_bad_linval : 1; + bdrkreg_t eb_rq_bad_addr : 1; + bdrkreg_t eb_rp_bad_data : 1; + bdrkreg_t eb_rq_bad_data : 1; + bdrkreg_t eb_rp_long : 1; + bdrkreg_t eb_rq_long : 1; + bdrkreg_t eb_rp_short : 1; + bdrkreg_t eb_rq_short : 1; + bdrkreg_t eb_rp_bad_cmd : 1; + bdrkreg_t eb_rq_bad_cmd : 1; + } lb_error_bits_fld_s; +} lb_error_bits_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register lets software clear some of the bits in the * + * LB_ERROR_BITS register without affecting other bits. Essentially, * + * it provides bit mask functionality. When software writes to the * + * LB_ERROR_MASK_CLR register, the bits which are set in the data * + * value indicate which bits are to be cleared in LB_ERROR_BITS. If a * + * bit is clear in the data value written to the LB_ERROR_MASK_CLR * + * register, then its corresponding bit in the LB_ERROR_BITS register * + * is not affected. Hence, software can atomically clear any subset * + * of the error bits in the LB_ERROR_BITS register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_error_mask_clr_u { + bdrkreg_t lb_error_mask_clr_regval; + struct { + bdrkreg_t emc_clr_rq_bad_cmd : 1; + bdrkreg_t emc_clr_rp_bad_cmd : 1; + bdrkreg_t emc_clr_rq_short : 1; + bdrkreg_t emc_clr_rp_short : 1; + bdrkreg_t emc_clr_rq_long : 1; + bdrkreg_t emc_clr_rp_long : 1; + bdrkreg_t emc_clr_rq_bad_data : 1; + bdrkreg_t emc_clr_rp_bad_data : 1; + bdrkreg_t emc_clr_rq_bad_addr : 1; + bdrkreg_t emc_clr_rq_bad_linval : 1; + bdrkreg_t emc_clr_gclk_drop : 1; + bdrkreg_t emc_reserved : 53; + } lb_error_mask_clr_fld_s; +} lb_error_mask_clr_u_t; + +#else + +typedef union lb_error_mask_clr_u { + bdrkreg_t lb_error_mask_clr_regval; + struct { + bdrkreg_t emc_reserved : 53; + bdrkreg_t emc_clr_gclk_drop : 1; + bdrkreg_t emc_clr_rq_bad_linval : 1; + bdrkreg_t emc_clr_rq_bad_addr : 1; + bdrkreg_t emc_clr_rp_bad_data : 1; + bdrkreg_t emc_clr_rq_bad_data : 1; + bdrkreg_t emc_clr_rp_long : 1; + bdrkreg_t emc_clr_rq_long : 1; + bdrkreg_t emc_clr_rp_short : 1; + bdrkreg_t emc_clr_rq_short : 1; + bdrkreg_t emc_clr_rp_bad_cmd : 1; + bdrkreg_t emc_clr_rq_bad_cmd : 1; + } lb_error_mask_clr_fld_s; +} lb_error_mask_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * If the LB detects an error when VALID==0 in the LB_ERROR_HDR1 * + * register, then it saves the contents of the offending packet's * + * header flit in the LB_ERROR_HDR1 and LB_ERROR_HDR2 registers, sets * + * the VALID bit in LB_ERROR_HDR1 and clears the OVERRUN bit in * + * LB_ERROR_HDR1 (and it will also set the corresponding bit in the * + * LB_ERROR_BITS register). The ERR_TYPE field indicates specifically * + * what kind of error occurred. Its encoding corresponds to the bit * + * positions in the LB_ERROR_BITS register (e.g., ERR_TYPE==5 * + * indicates a RP_LONG error). If an error (of any type except * + * GCLK_DROP) subsequently happens while VALID==1, then the LB sets * + * the OVERRUN bit in LB_ERROR_HDR1. This register is not relevant * + * when a GCLK_DROP error occurs; the LB does not even attempt to * + * change the ERR_TYPE, VALID or OVERRUN field when a GCLK_DROP error * + * happens. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_error_hdr1_u { + bdrkreg_t lb_error_hdr1_regval; + struct { + bdrkreg_t eh_command : 7; + bdrkreg_t eh_reserved_5 : 1; + bdrkreg_t eh_suppl : 11; + bdrkreg_t eh_reserved_4 : 1; + bdrkreg_t eh_source : 11; + bdrkreg_t eh_reserved_3 : 1; + bdrkreg_t eh_err_type : 4; + bdrkreg_t eh_reserved_2 : 4; + bdrkreg_t eh_overrun : 1; + bdrkreg_t eh_reserved_1 : 3; + bdrkreg_t eh_valid : 1; + bdrkreg_t eh_reserved : 19; + } lb_error_hdr1_fld_s; +} lb_error_hdr1_u_t; + +#else + +typedef union lb_error_hdr1_u { + bdrkreg_t lb_error_hdr1_regval; + struct { + bdrkreg_t eh_reserved : 19; + bdrkreg_t eh_valid : 1; + bdrkreg_t eh_reserved_1 : 3; + bdrkreg_t eh_overrun : 1; + bdrkreg_t eh_reserved_2 : 4; + bdrkreg_t eh_err_type : 4; + bdrkreg_t eh_reserved_3 : 1; + bdrkreg_t eh_source : 11; + bdrkreg_t eh_reserved_4 : 1; + bdrkreg_t eh_suppl : 11; + bdrkreg_t eh_reserved_5 : 1; + bdrkreg_t eh_command : 7; + } lb_error_hdr1_fld_s; +} lb_error_hdr1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contents of the Address field from header flit of first packet * + * that causes an error. This register is not relevant when a * + * GCLK_DROP error occurs. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_error_hdr2_u { + bdrkreg_t lb_error_hdr2_regval; + struct { + bdrkreg_t eh_address : 38; + bdrkreg_t eh_reserved : 26; + } lb_error_hdr2_fld_s; +} lb_error_hdr2_u_t; + +#else + +typedef union lb_error_hdr2_u { + bdrkreg_t lb_error_hdr2_regval; + struct { + bdrkreg_t eh_reserved : 26; + bdrkreg_t eh_address : 38; + } lb_error_hdr2_fld_s; +} lb_error_hdr2_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register accompanies the LB_ERROR_HDR1 and * + * LB_ERROR_HDR2 registers. The LB updates the value in this * + * register when an incoming packet with a data flit causes an error * + * while VALID==0 in the LB_ERROR_HDR1 register. This register * + * retains the contents of the data flit from the incoming packet * + * that caused the error. This register is relevant for the following * + * types of errors: * + *
    * + *
      * + *
        * + *
          * + *
            * + *
          • RQ_BAD_LINVAL for a LINVAL request. * + *
          • RQ_BAD_ADDR for a normal or vector PIO request. * + *
          • RP_BAD_DATA for a vector PIO reply. * + *
          • RQ_BAD DATA for an incoming request with data. * + *
          • RP_LONG for a vector PIO reply. * + *
          • RQ_LONG for an incoming request with expected data. * + *
            * + * In the case of RQ_BAD_LINVAL, the register retains the 64-bit data * + * value that followed the header flit. In the case of RQ_BAD_ADDR * + * or RQ_BAD_DATA, the register retains the incoming packet's 64-bit * + * data value (i.e., 2nd flit in the packet for a normal PIO write or * + * an LINVAL, 3rd flit for a vector PIO read or write). In the case * + * of RP_BAD_DATA, the register retains the 64-bit data value in the * + * 3rd flit of the packet. When a RP_LONG or RQ_LONG error occurs, * + * the LB loads the LB_ERROR_DATA register with the contents of the * + * expected data flit (i.e., the 3rd flit in the packet for a vector * + * PIO request or reply, the 2nd flit for other packets), if any. The * + * contents of the LB_ERROR_DATA register are undefined after a * + * RP_SHORT, RQ_SHORT, RP_BAD_CMD or RQ_BAD_CMD error. The contents * + * of the LB_ERROR_DATA register are also undefined after an incoming * + * normal PIO read request which encounters a RQ_LONG error. * + * * + ************************************************************************/ + + + + +typedef union lb_error_data_u { + bdrkreg_t lb_error_data_regval; + struct { + bdrkreg_t ed_data : 64; + } lb_error_data_fld_s; +} lb_error_data_u_t; + + + + +/************************************************************************ + * * + * This register enables software to control what internal Bedrock * + * signals are visible on the chip's debug pins. The LB provides the * + * 6-bit value in this register to Bedrock's DEBUG unit. The JTAG * + * unit provides a similar 6-bit selection input to the DEBUG unit, * + * along with another signal that tells the DEBUG unit whether to use * + * the selection signal from the LB or the JTAG unit. For a * + * description of the menu of choices for debug signals, refer to the * + * documentation for the DEBUG unit. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_debug_select_u { + bdrkreg_t lb_debug_select_regval; + struct { + bdrkreg_t ds_debug_sel : 6; + bdrkreg_t ds_reserved : 58; + } lb_debug_select_fld_s; +} lb_debug_select_u_t; + +#else + +typedef union lb_debug_select_u { + bdrkreg_t lb_debug_select_regval; + struct { + bdrkreg_t ds_reserved : 58; + bdrkreg_t ds_debug_sel : 6; + } lb_debug_select_fld_s; +} lb_debug_select_u_t; + +#endif + + + + +/************************************************************************ + * * + * A PIO read from this register returns the 32-bit value that is * + * currently on the Bedrock chip's debug pins. This register allows * + * software to observe debug pin output values which do not change * + * frequently (i.e., they remain constant over a period of many * + * cycles). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_debug_pins_u { + bdrkreg_t lb_debug_pins_regval; + struct { + bdrkreg_t dp_debug_pins : 32; + bdrkreg_t dp_reserved : 32; + } lb_debug_pins_fld_s; +} lb_debug_pins_u_t; + +#else + +typedef union lb_debug_pins_u { + bdrkreg_t lb_debug_pins_regval; + struct { + bdrkreg_t dp_reserved : 32; + bdrkreg_t dp_debug_pins : 32; + } lb_debug_pins_fld_s; +} lb_debug_pins_u_t; + +#endif + + + + +/************************************************************************ + * * + * The LB unit provides the PI0 and PI1 units with a real-time clock * + * signal. The LB can generate this signal itself, based on the * + * Bedrock chip's system clock which the LB receives as an input. * + * Alternatively, the LB can filter a global clock signal which it * + * receives as an input and provide the filtered version to PI0 and * + * PI1. The user can program the LB_RT_LOCAL_CTRL register to choose * + * the source of the real-time clock. If the user chooses to generate * + * the real-time clock internally within the LB, then the user can * + * specify the period for the real-time clock signal. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_rt_local_ctrl_u { + bdrkreg_t lb_rt_local_ctrl_regval; + struct { + bdrkreg_t rlc_gclk_enable : 1; + bdrkreg_t rlc_reserved_4 : 3; + bdrkreg_t rlc_max_count : 10; + bdrkreg_t rlc_reserved_3 : 2; + bdrkreg_t rlc_gclk_counter : 10; + bdrkreg_t rlc_reserved_2 : 2; + bdrkreg_t rlc_gclk : 1; + bdrkreg_t rlc_reserved_1 : 3; + bdrkreg_t rlc_use_internal : 1; + bdrkreg_t rlc_reserved : 31; + } lb_rt_local_ctrl_fld_s; +} lb_rt_local_ctrl_u_t; + +#else + +typedef union lb_rt_local_ctrl_u { + bdrkreg_t lb_rt_local_ctrl_regval; + struct { + bdrkreg_t rlc_reserved : 31; + bdrkreg_t rlc_use_internal : 1; + bdrkreg_t rlc_reserved_1 : 3; + bdrkreg_t rlc_gclk : 1; + bdrkreg_t rlc_reserved_2 : 2; + bdrkreg_t rlc_gclk_counter : 10; + bdrkreg_t rlc_reserved_3 : 2; + bdrkreg_t rlc_max_count : 10; + bdrkreg_t rlc_reserved_4 : 3; + bdrkreg_t rlc_gclk_enable : 1; + } lb_rt_local_ctrl_fld_s; +} lb_rt_local_ctrl_u_t; + +#endif + + + + +/************************************************************************ + * * + * When the value of the USE_INTERNAL field in the LB_RT_LOCAL_CTRL * + * register is 0, the LB filters an incoming global clock signal and * + * provides the result to PI0 and PI1 for their real-time clock * + * inputs. The LB can perform either simple filtering or complex * + * filtering, depending on the value of the MASK_ENABLE bit. For the * + * simple filtering option, the LB merely removes glitches from the * + * incoming global clock; if the global clock goes high (or low) for * + * only a single cycle, the LB considers it to be a glitch and does * + * not pass it through to PI0 and PI1. For the complex filtering * + * option, the LB expects positive edges on the incoming global clock * + * to be spaced at fairly regular intervals and it looks for them at * + * these times; the LB keeps track of unexpected or missing positive * + * edges, and it generates an edge itself whenever the incoming * + * global clock apparently misses an edge. For each filtering option, * + * the real-time clock which the LB provides to PI0 and PI1 is not * + * necessarily a square wave; when a positive edge happens, the * + * real-time clock stays high for (2*MAX_COUNT+1-OFFSET)/2 cycles of * + * the LB's system clock, and then is low until the next positive * + * edge. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_rt_filter_ctrl_u { + bdrkreg_t lb_rt_filter_ctrl_regval; + struct { + bdrkreg_t rfc_offset : 5; + bdrkreg_t rfc_reserved_4 : 3; + bdrkreg_t rfc_mask_counter : 12; + bdrkreg_t rfc_mask_enable : 1; + bdrkreg_t rfc_reserved_3 : 3; + bdrkreg_t rfc_dropout_counter : 10; + bdrkreg_t rfc_reserved_2 : 2; + bdrkreg_t rfc_dropout_thresh : 10; + bdrkreg_t rfc_reserved_1 : 2; + bdrkreg_t rfc_error_counter : 10; + bdrkreg_t rfc_reserved : 6; + } lb_rt_filter_ctrl_fld_s; +} lb_rt_filter_ctrl_u_t; + +#else + +typedef union lb_rt_filter_ctrl_u { + bdrkreg_t lb_rt_filter_ctrl_regval; + struct { + bdrkreg_t rfc_reserved : 6; + bdrkreg_t rfc_error_counter : 10; + bdrkreg_t rfc_reserved_1 : 2; + bdrkreg_t rfc_dropout_thresh : 10; + bdrkreg_t rfc_reserved_2 : 2; + bdrkreg_t rfc_dropout_counter : 10; + bdrkreg_t rfc_reserved_3 : 3; + bdrkreg_t rfc_mask_enable : 1; + bdrkreg_t rfc_mask_counter : 12; + bdrkreg_t rfc_reserved_4 : 3; + bdrkreg_t rfc_offset : 5; + } lb_rt_filter_ctrl_fld_s; +} lb_rt_filter_ctrl_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is a scratch register that is reset to 0x0. At the * + * normal address, the register is a simple storage location. At the * + * Write-If-Zero address, the register accepts a new value from a * + * write operation only if the current value is zero. * + * * + ************************************************************************/ + + + + +typedef union lb_scratch_reg0_u { + bdrkreg_t lb_scratch_reg0_regval; + struct { + bdrkreg_t sr_scratch_bits : 64; + } lb_scratch_reg0_fld_s; +} lb_scratch_reg0_u_t; + + + + +/************************************************************************ + * * + * These registers are scratch registers that are not reset. At a * + * register's normal address, it is a simple storage location. At a * + * register's Write-If-Zero address, it accepts a new value from a * + * write operation only if the current value is zero. * + * * + ************************************************************************/ + + + + +typedef union lb_scratch_reg1_u { + bdrkreg_t lb_scratch_reg1_regval; + struct { + bdrkreg_t sr_scratch_bits : 64; + } lb_scratch_reg1_fld_s; +} lb_scratch_reg1_u_t; + + + + +/************************************************************************ + * * + * These registers are scratch registers that are not reset. At a * + * register's normal address, it is a simple storage location. At a * + * register's Write-If-Zero address, it accepts a new value from a * + * write operation only if the current value is zero. * + * * + ************************************************************************/ + + + + +typedef union lb_scratch_reg2_u { + bdrkreg_t lb_scratch_reg2_regval; + struct { + bdrkreg_t sr_scratch_bits : 64; + } lb_scratch_reg2_fld_s; +} lb_scratch_reg2_u_t; + + + + +/************************************************************************ + * * + * These one-bit registers are scratch registers. At a register's * + * normal address, it is a simple storage location. At a register's * + * Read-Set-If-Zero address, it returns the original contents and * + * sets the bit if the original value is zero. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_scratch_reg3_u { + bdrkreg_t lb_scratch_reg3_regval; + struct { + bdrkreg_t sr_scratch_bit : 1; + bdrkreg_t sr_reserved : 63; + } lb_scratch_reg3_fld_s; +} lb_scratch_reg3_u_t; + +#else + +typedef union lb_scratch_reg3_u { + bdrkreg_t lb_scratch_reg3_regval; + struct { + bdrkreg_t sr_reserved : 63; + bdrkreg_t sr_scratch_bit : 1; + } lb_scratch_reg3_fld_s; +} lb_scratch_reg3_u_t; + +#endif + + + + +/************************************************************************ + * * + * These one-bit registers are scratch registers. At a register's * + * normal address, it is a simple storage location. At a register's * + * Read-Set-If-Zero address, it returns the original contents and * + * sets the bit if the original value is zero. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_scratch_reg4_u { + bdrkreg_t lb_scratch_reg4_regval; + struct { + bdrkreg_t sr_scratch_bit : 1; + bdrkreg_t sr_reserved : 63; + } lb_scratch_reg4_fld_s; +} lb_scratch_reg4_u_t; + +#else + +typedef union lb_scratch_reg4_u { + bdrkreg_t lb_scratch_reg4_regval; + struct { + bdrkreg_t sr_reserved : 63; + bdrkreg_t sr_scratch_bit : 1; + } lb_scratch_reg4_fld_s; +} lb_scratch_reg4_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is a scratch register that is reset to 0x0. At the * + * normal address, the register is a simple storage location. At the * + * Write-If-Zero address, the register accepts a new value from a * + * write operation only if the current value is zero. * + * * + ************************************************************************/ + + + + +typedef union lb_scratch_reg0_wz_u { + bdrkreg_t lb_scratch_reg0_wz_regval; + struct { + bdrkreg_t srw_scratch_bits : 64; + } lb_scratch_reg0_wz_fld_s; +} lb_scratch_reg0_wz_u_t; + + + + +/************************************************************************ + * * + * These registers are scratch registers that are not reset. At a * + * register's normal address, it is a simple storage location. At a * + * register's Write-If-Zero address, it accepts a new value from a * + * write operation only if the current value is zero. * + * * + ************************************************************************/ + + + + +typedef union lb_scratch_reg1_wz_u { + bdrkreg_t lb_scratch_reg1_wz_regval; + struct { + bdrkreg_t srw_scratch_bits : 64; + } lb_scratch_reg1_wz_fld_s; +} lb_scratch_reg1_wz_u_t; + + + + +/************************************************************************ + * * + * These registers are scratch registers that are not reset. At a * + * register's normal address, it is a simple storage location. At a * + * register's Write-If-Zero address, it accepts a new value from a * + * write operation only if the current value is zero. * + * * + ************************************************************************/ + + + + +typedef union lb_scratch_reg2_wz_u { + bdrkreg_t lb_scratch_reg2_wz_regval; + struct { + bdrkreg_t srw_scratch_bits : 64; + } lb_scratch_reg2_wz_fld_s; +} lb_scratch_reg2_wz_u_t; + + + + +/************************************************************************ + * * + * These one-bit registers are scratch registers. At a register's * + * normal address, it is a simple storage location. At a register's * + * Read-Set-If-Zero address, it returns the original contents and * + * sets the bit if the original value is zero. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_scratch_reg3_rz_u { + bdrkreg_t lb_scratch_reg3_rz_regval; + struct { + bdrkreg_t srr_scratch_bit : 1; + bdrkreg_t srr_reserved : 63; + } lb_scratch_reg3_rz_fld_s; +} lb_scratch_reg3_rz_u_t; + +#else + +typedef union lb_scratch_reg3_rz_u { + bdrkreg_t lb_scratch_reg3_rz_regval; + struct { + bdrkreg_t srr_reserved : 63; + bdrkreg_t srr_scratch_bit : 1; + } lb_scratch_reg3_rz_fld_s; +} lb_scratch_reg3_rz_u_t; + +#endif + + + + +/************************************************************************ + * * + * These one-bit registers are scratch registers. At a register's * + * normal address, it is a simple storage location. At a register's * + * Read-Set-If-Zero address, it returns the original contents and * + * sets the bit if the original value is zero. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_scratch_reg4_rz_u { + bdrkreg_t lb_scratch_reg4_rz_regval; + struct { + bdrkreg_t srr_scratch_bit : 1; + bdrkreg_t srr_reserved : 63; + } lb_scratch_reg4_rz_fld_s; +} lb_scratch_reg4_rz_u_t; + +#else + +typedef union lb_scratch_reg4_rz_u { + bdrkreg_t lb_scratch_reg4_rz_regval; + struct { + bdrkreg_t srr_reserved : 63; + bdrkreg_t srr_scratch_bit : 1; + } lb_scratch_reg4_rz_fld_s; +} lb_scratch_reg4_rz_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register contains vector PIO parameters. A * + * write to this register triggers the LB to send out a vector PIO * + * request packet. Immediately after servicing a write request to the * + * LB_VECTOR_PARMS register, the LB sends back a reply (i.e., the LB * + * doesn't wait for the vector PIO operation to finish first). Three * + * LB registers provide the contents for an outgoing vector PIO * + * request packet. Software should wait until the BUSY bit in * + * LB_VECTOR_PARMS is clear and then initialize all three of these * + * registers before initiating a vector PIO operation. The three * + * vector PIO registers are: * + * LB_VECTOR_ROUTE * + * LB_VECTOR_DATA * + * LB_VECTOR_PARMS (should be written last) * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_vector_parms_u { + bdrkreg_t lb_vector_parms_regval; + struct { + bdrkreg_t vp_type : 1; + bdrkreg_t vp_reserved_2 : 2; + bdrkreg_t vp_address : 21; + bdrkreg_t vp_reserved_1 : 8; + bdrkreg_t vp_write_id : 8; + bdrkreg_t vp_pio_id : 11; + bdrkreg_t vp_reserved : 12; + bdrkreg_t vp_busy : 1; + } lb_vector_parms_fld_s; +} lb_vector_parms_u_t; + +#else + +typedef union lb_vector_parms_u { + bdrkreg_t lb_vector_parms_regval; + struct { + bdrkreg_t vp_busy : 1; + bdrkreg_t vp_reserved : 12; + bdrkreg_t vp_pio_id : 11; + bdrkreg_t vp_write_id : 8; + bdrkreg_t vp_reserved_1 : 8; + bdrkreg_t vp_address : 21; + bdrkreg_t vp_reserved_2 : 2; + bdrkreg_t vp_type : 1; + } lb_vector_parms_fld_s; +} lb_vector_parms_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the vector PIO route. This is one of the 3 * + * vector PIO control registers. * + * * + ************************************************************************/ + + + + +typedef union lb_vector_route_u { + bdrkreg_t lb_vector_route_regval; + struct { + bdrkreg_t vr_vector : 64; + } lb_vector_route_fld_s; +} lb_vector_route_u_t; + + + + +/************************************************************************ + * * + * This register contains the vector PIO write data. This is one of * + * the 3 vector PIO control registers. The contents of this register * + * also provide the data value to be sent in outgoing vector PIO read * + * requests and vector PIO write replies. * + * * + ************************************************************************/ + + + + +typedef union lb_vector_data_u { + bdrkreg_t lb_vector_data_regval; + struct { + bdrkreg_t vd_write_data : 64; + } lb_vector_data_fld_s; +} lb_vector_data_u_t; + + + + +/************************************************************************ + * * + * Description: This register contains the vector PIO return status. * + * Software should clear this register before launching a vector PIO * + * request from the LB. The LB will not modify this register's value * + * if an incoming reply packet encounters any kind of error. If an * + * incoming reply packet does not encounter an error but the * + * STATUS_VALID bit is already set, then the LB sets the OVERRUN bit * + * and leaves the other fields unchanged. The LB updates the values * + * of the SOURCE, PIO_ID, WRITE_ID, ADDRESS and TYPE fields only if * + * an incoming vector PIO reply packet does not encounter an error * + * and the STATUS_VALID bit is clear; at the same time, the LB sets * + * the STATUS_VALID bit and will also update the LB_VECTOR_RETURN and * + * LB_VECTOR_READ_DATA registers. * + * * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_vector_status_u { + bdrkreg_t lb_vector_status_regval; + struct { + bdrkreg_t vs_type : 3; + bdrkreg_t vs_address : 21; + bdrkreg_t vs_reserved : 8; + bdrkreg_t vs_write_id : 8; + bdrkreg_t vs_pio_id : 11; + bdrkreg_t vs_source : 11; + bdrkreg_t vs_overrun : 1; + bdrkreg_t vs_status_valid : 1; + } lb_vector_status_fld_s; +} lb_vector_status_u_t; + +#else + +typedef union lb_vector_status_u { + bdrkreg_t lb_vector_status_regval; + struct { + bdrkreg_t vs_status_valid : 1; + bdrkreg_t vs_overrun : 1; + bdrkreg_t vs_source : 11; + bdrkreg_t vs_pio_id : 11; + bdrkreg_t vs_write_id : 8; + bdrkreg_t vs_reserved : 8; + bdrkreg_t vs_address : 21; + bdrkreg_t vs_type : 3; + } lb_vector_status_fld_s; +} lb_vector_status_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the return vector PIO route. The LB will * + * not modify this register's value if an incoming reply packet * + * encounters any kind of error. The LB also will not modify this * + * register's value if the STATUS_VALID bit in the LB_VECTOR_STATUS * + * register is set when it receives an incoming vector PIO reply. The * + * LB stores an incoming vector PIO reply packet's vector route flit * + * in this register only if the packet does not encounter an error * + * and the STATUS_VALID bit is clear. * + * * + ************************************************************************/ + + + + +typedef union lb_vector_return_u { + bdrkreg_t lb_vector_return_regval; + struct { + bdrkreg_t vr_return_vector : 64; + } lb_vector_return_fld_s; +} lb_vector_return_u_t; + + + + +/************************************************************************ + * * + * This register contains the vector PIO read data, if any. The LB * + * will not modify this register's value if an incoming reply packet * + * encounters any kind of error. The LB also will not modify this * + * register's value if the STATUS_VALID bit in the LB_VECTOR_STATUS * + * register is set when it receives an incoming vector PIO reply. The * + * LB stores an incoming vector PIO reply packet's data flit in this * + * register only if the packet does not encounter an error and the * + * STATUS_VALID bit is clear. * + * * + ************************************************************************/ + + + + +typedef union lb_vector_read_data_u { + bdrkreg_t lb_vector_read_data_regval; + struct { + bdrkreg_t vrd_read_data : 64; + } lb_vector_read_data_fld_s; +} lb_vector_read_data_u_t; + + + + +/************************************************************************ + * * + * Description: This register contains the vector PIO return status. * + * Software should clear this register before launching a vector PIO * + * request from the LB. The LB will not modify this register's value * + * if an incoming reply packet encounters any kind of error. If an * + * incoming reply packet does not encounter an error but the * + * STATUS_VALID bit is already set, then the LB sets the OVERRUN bit * + * and leaves the other fields unchanged. The LB updates the values * + * of the SOURCE, PIO_ID, WRITE_ID, ADDRESS and TYPE fields only if * + * an incoming vector PIO reply packet does not encounter an error * + * and the STATUS_VALID bit is clear; at the same time, the LB sets * + * the STATUS_VALID bit and will also update the LB_VECTOR_RETURN and * + * LB_VECTOR_READ_DATA registers. * + * * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union lb_vector_status_clear_u { + bdrkreg_t lb_vector_status_clear_regval; + struct { + bdrkreg_t vsc_type : 3; + bdrkreg_t vsc_address : 21; + bdrkreg_t vsc_reserved : 8; + bdrkreg_t vsc_write_id : 8; + bdrkreg_t vsc_pio_id : 11; + bdrkreg_t vsc_source : 11; + bdrkreg_t vsc_overrun : 1; + bdrkreg_t vsc_status_valid : 1; + } lb_vector_status_clear_fld_s; +} lb_vector_status_clear_u_t; + +#else + +typedef union lb_vector_status_clear_u { + bdrkreg_t lb_vector_status_clear_regval; + struct { + bdrkreg_t vsc_status_valid : 1; + bdrkreg_t vsc_overrun : 1; + bdrkreg_t vsc_source : 11; + bdrkreg_t vsc_pio_id : 11; + bdrkreg_t vsc_write_id : 8; + bdrkreg_t vsc_reserved : 8; + bdrkreg_t vsc_address : 21; + bdrkreg_t vsc_type : 3; + } lb_vector_status_clear_fld_s; +} lb_vector_status_clear_u_t; + +#endif + + + + + + +#endif /* _LANGUAGE_C */ + +/************************************************************************ + * * + * MAKE ALL ADDITIONS AFTER THIS LINE * + * * + ************************************************************************/ + + + + + +#endif /* _ASM_SN_SN1_HUBLB_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hublb_next.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hublb_next.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hublb_next.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hublb_next.h Wed Dec 6 21:56:13 2000 @@ -0,0 +1,110 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBLB_NEXT_H +#define _ASM_SN_SN1_HUBLB_NEXT_H + +/********************************************************************** + + This contains some mask and shift values for LB defined as required + for compatibility. + + **********************************************************************/ + +#define LRI_SYSTEM_SIZE_SHFT 46 +#define LRI_SYSTEM_SIZE_MASK (UINT64_CAST 0x3 << LRI_SYSTEM_SIZE_SHFT) +#define LRI_NODEID_SHFT 32 +#define LRI_NODEID_MASK (UINT64_CAST 0xff << LRI_NODEID_SHFT)/* Node ID */ +#define LRI_CHIPID_SHFT 12 +#define LRI_CHIPID_MASK (UINT64_CAST 0xffff << LRI_CHIPID_SHFT) /* should be 0x3012 */ +#define LRI_REV_SHFT 28 +#define LRI_REV_MASK (UINT64_CAST 0xf << LRI_REV_SHFT)/* Chip revision */ + +/* Values for LRI_SYSTEM_SIZE */ +#define SYSTEM_SIZE_INVALID 0x3 +#define SYSTEM_SIZE_NMODE 0x2 +#define SYSTEM_SIZE_COARSE 0x1 +#define SYSTEM_SIZE_SMALL 0x0 + +/* In fine mode, each node is a region. In coarse mode, there are + * 2 nodes per region. In N-mode, there are 4 nodes per region. */ +#define NASID_TO_FINEREG_SHFT 0 +#define NASID_TO_COARSEREG_SHFT 1 +#define NASID_TO_NMODEREG_SHFT 2 + +#define LR_LOCALRESET (UINT64_CAST 1) +/* + * LB_VECTOR_PARMS mask and shift definitions. + * TYPE may be any of the first four PIOTYPEs defined under NI_VECTOR_STATUS. + */ + +#define LVP_BUSY (UINT64_CAST 1 << 63) +#define LVP_PIOID_SHFT 40 +#define LVP_PIOID_MASK (UINT64_CAST 0x7ff << 40) +#define LVP_WRITEID_SHFT 32 +#define LVP_WRITEID_MASK (UINT64_CAST 0xff << 32) +#define LVP_ADDRESS_MASK (UINT64_CAST 0xfffff8) /* Bits 23:3 */ +#define LVP_TYPE_SHFT 0 +#define LVP_TYPE_MASK (UINT64_CAST 0x3) + +/* LB_VECTOR_STATUS mask and shift definitions */ + +#define LVS_VALID (UINT64_CAST 1 << 63) +#define LVS_OVERRUN (UINT64_CAST 1 << 62) +#define LVS_TARGET_SHFT 51 +#define LVS_TARGET_MASK (UINT64_CAST 0x7ff << 51) +#define LVS_PIOID_SHFT 40 +#define LVS_PIOID_MASK (UINT64_CAST 0x7ff << 40) +#define LVS_WRITEID_SHFT 32 +#define LVS_WRITEID_MASK (UINT64_CAST 0xff << 32) +#define LVS_ADDRESS_MASK (UINT64_CAST 0xfffff8) /* Bits 23:3 */ +#define LVS_TYPE_SHFT 0 +#define LVS_TYPE_MASK (UINT64_CAST 0x7) +#define LVS_ERROR_MASK (UINT64_CAST 0x4) /* bit set means error */ + +/* LB_RT_LOCAL_CTRL mask and shift definitions */ + +#define LRLC_USE_INT_SHFT 32 +#define LRLC_USE_INT_MASK (UINT64_CAST 1 << 32) +#define LRLC_USE_INT (UINT64_CAST 1 << 32) +#define LRLC_GCLK_SHFT 28 +#define LRLC_GCLK_MASK (UINT64_CAST 1 << 28) +#define LRLC_GCLK (UINT64_CAST 1 << 28) +#define LRLC_GCLK_COUNT_SHFT 16 +#define LRLC_GCLK_COUNT_MASK (UINT64_CAST 0x3ff << 16) +#define LRLC_MAX_COUNT_SHFT 4 +#define LRLC_MAX_COUNT_MASK (UINT64_CAST 0x3ff << 4) +#define LRLC_GCLK_EN_SHFT 0 +#define LRLC_GCLK_EN_MASK (UINT64_CAST 1) +#define LRLC_GCLK_EN (UINT64_CAST 1) + +/* LB_NODES_ABSENT mask and shift definitions */ +#define LNA_VALID_SHFT 15 +#define LNA_VALID_MASK (UINT64_CAST 1 << LNA_VALID_SHFT) +#define LNA_VALID (UINT64_CAST 1 << LNA_VALID_SHFT) +#define LNA_NODE_SHFT 0 +#define LNA_NODE_MASK (UINT64_CAST 0xff << LNA_NODE_SHFT) + +/* LB_NODES_ABSENT has 4 identical sub-registers, on 16-bit boundaries */ +#define LNA_ENTRY_SHFT 16 +#define LNA_MAX_ENTRIES 4 +#define LNA_ADD(_reg, _n) ((_reg) = (_reg) << LNA_ENTRY_SHFT | \ + LNA_VALID | (_n) << LNA_NODE_SHFT) + +#define PIOTYPE_READ 0 /* VECTOR_PARMS and VECTOR_STATUS */ +#define PIOTYPE_WRITE 1 /* VECTOR_PARMS and VECTOR_STATUS */ +#define PIOTYPE_UNDEFINED 2 /* VECTOR_PARMS and VECTOR_STATUS */ +/* XXX IP35 doesn't support vector exchange: scr. regs. do locks directly */ +#define PIOTYPE_EXCHANGE 3 /* VECTOR_PARMS and VECTOR_STATUS */ +#define PIOTYPE_ADDR_ERR 4 /* VECTOR_STATUS only */ +#define PIOTYPE_CMD_ERR 5 /* VECTOR_STATUS only */ +#define PIOTYPE_PROT_ERR 6 /* VECTOR_STATUS only */ +#define PIOTYPE_UNKNOWN 7 /* VECTOR_STATUS only */ + +#endif /* _ASM_SN_SN1_HUBLB_NEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubmd.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubmd.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubmd.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubmd.h Wed Dec 6 21:56:13 2000 @@ -0,0 +1,2477 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBMD_H +#define _ASM_SN_SN1_HUBMD_H + + +/************************************************************************ + * * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! * + * * + * This file is created by an automated script. Any (minimal) changes * + * made manually to this file should be made with care. * + * * + * MAKE ALL ADDITIONS TO THE END OF THIS FILE * + * * + ************************************************************************/ + + +#define MD_CURRENT_CELL 0x00780000 /* + * BDDIR, LREG, LBOOT, + * RREG, RBOOT + * protection and mask + * for using Local + * Access protection. + */ + + + +#define MD_MEMORY_CONFIG 0x00780008 /* + * Memory/Directory + * DIMM control + */ + + + +#define MD_ARBITRATION_CONTROL 0x00780010 /* + * Arbitration + * Parameters + */ + + + +#define MD_MIG_CONFIG 0x00780018 /* + * Page Migration + * control + */ + + + +#define MD_FANDOP_CAC_STAT0 0x00780020 /* + * Fetch-and-op cache + * 0 status + */ + + + +#define MD_FANDOP_CAC_STAT1 0x00780028 /* + * Fetch-and-op cache + * 1 status + */ + + + +#define MD_MISC0_ERROR 0x00780040 /* + * Miscellaneous MD + * error + */ + + + +#define MD_MISC1_ERROR 0x00780048 /* + * Miscellaneous MD + * error + */ + + + +#define MD_MISC1_ERROR_CLR 0x00780058 /* + * Miscellaneous MD + * error clear + */ + + + +#define MD_OUTGOING_RP_QUEUE_SIZE 0x00780060 /* + * MD outgoing reply + * queues sizing + */ + + + +#define MD_PERF_SEL0 0x00790000 /* + * Selects events + * monitored by + * MD_PERF_CNT0 + */ + + + +#define MD_PERF_SEL1 0x00790008 /* + * Selects events + * monitored by + * MD_PERF_CNT1 + */ + + + +#define MD_PERF_CNT0 0x00790010 /* + * Performance counter + * 0 + */ + + + +#define MD_PERF_CNT1 0x00790018 /* + * Performance counter + * 1 + */ + + + +#define MD_REFRESH_CONTROL 0x007A0000 /* + * Memory/Directory + * refresh control + */ + + + +#define MD_JUNK_BUS_TIMING 0x007A0008 /* Junk Bus Timing */ + + + +#define MD_LED0 0x007A0010 /* Reads of 8-bit LED0 */ + + + +#define MD_LED1 0x007A0018 /* Reads of 8-bit LED1 */ + + + +#define MD_LED2 0x007A0020 /* Reads of 8-bit LED2 */ + + + +#define MD_LED3 0x007A0028 /* Reads of 8-bit LED3 */ + + + +#define MD_BIST_CTL 0x007A0030 /* + * BIST general + * control + */ + + + +#define MD_BIST_DATA 0x007A0038 /* + * BIST initial data + * pattern and + * variation control + */ + + + +#define MD_BIST_AB_ERR_ADDR 0x007A0040 /* BIST error address */ + + + +#define MD_BIST_STATUS 0x007A0048 /* BIST status */ + + + +#define MD_IB_DEBUG 0x007A0060 /* IB debug select */ + + + +#define MD_DIR_CONFIG 0x007C0000 /* + * Directory mode + * control + */ + + + +#define MD_DIR_ERROR 0x007C0010 /* + * Directory DIMM + * error + */ + + + +#define MD_DIR_ERROR_CLR 0x007C0018 /* + * Directory DIMM + * error clear + */ + + + +#define MD_PROTOCOL_ERROR 0x007C0020 /* + * Directory protocol + * error + */ + + + +#define MD_PROTOCOL_ERR_CLR 0x007C0028 /* + * Directory protocol + * error clear + */ + + + +#define MD_MIG_CANDIDATE 0x007C0030 /* + * Page migration + * candidate + */ + + + +#define MD_MIG_CANDIDATE_CLR 0x007C0038 /* + * Page migration + * candidate clear + */ + + + +#define MD_MIG_DIFF_THRESH 0x007C0040 /* + * Page migration + * count difference + * threshold + */ + + + +#define MD_MIG_VALUE_THRESH 0x007C0048 /* + * Page migration + * count absolute + * threshold + */ + + + +#define MD_OUTGOING_RQ_QUEUE_SIZE 0x007C0050 /* + * MD outgoing request + * queues sizing + */ + + + +#define MD_BIST_DB_ERR_DATA 0x007C0058 /* + * BIST directory + * error data + */ + + + +#define MD_DB_DEBUG 0x007C0060 /* DB debug select */ + + + +#define MD_MB_ECC_CONFIG 0x007E0000 /* + * Data ECC + * Configuration + */ + + + +#define MD_MEM_ERROR 0x007E0010 /* Memory DIMM error */ + + + +#define MD_MEM_ERROR_CLR 0x007E0018 /* + * Memory DIMM error + * clear + */ + + + +#define MD_BIST_MB_ERR_DATA_0 0x007E0020 /* + * BIST memory error + * data + */ + + + +#define MD_BIST_MB_ERR_DATA_1 0x007E0028 /* + * BIST memory error + * data + */ + + + +#define MD_BIST_MB_ERR_DATA_2 0x007E0030 /* + * BIST memory error + * data + */ + + + +#define MD_BIST_MB_ERR_DATA_3 0x007E0038 /* + * BIST memory error + * data + */ + + + +#define MD_MB_DEBUG 0x007E0040 /* MB debug select */ + + + + + +#ifdef _LANGUAGE_C + +/************************************************************************ + * * + * Description: This register shows which regions are in the current * + * cell. If a region has its bit set in this register, then it uses * + * the Local Access protection in the directory instead of the * + * separate per-region protection (which would cause a small * + * performance penalty). In addition, writeback and write reply * + * commands from outside the current cell will always check the * + * directory protection before writing data to memory. Writeback and * + * write reply commands from inside the current cell will write * + * memory regardless of the protection value. * + * This register is also used as the access-rights bit-vector for * + * most of the ASIC-special (HSpec) portion of the address space. It * + * covers the BDDIR, LREG, LBOOT, RREG, and RBOOT spaces. It does not * + * cover the UALIAS and BDECC spaces, as they are covered by the * + * protection in the directory. If a bit in the bit-vector is set, * + * the region corresponding to that bit has read/write permission on * + * these spaces. If the bit is clear, then that region has read-only * + * access to these spaces (except for LREG/RREG which have no access * + * when the bit is clear). * + * The granularity of a region is set by the REGION_SIZE register in * + * the NI local register space. * + * NOTE: This means that no processor outside the current cell can * + * write into the BDDIR, LREG, LBOOT, RREG, or RBOOT spaces. * + * * + ************************************************************************/ + + + + +typedef union md_current_cell_u { + bdrkreg_t md_current_cell_regval; + struct { + bdrkreg_t cc_hspec_prot : 64; + } md_current_cell_fld_s; +} md_current_cell_u_t; + + + + +/************************************************************************ + * * + * Description: This register contains three sets of information. * + * The first set describes the size and configuration of DIMMs that * + * are plugged into a system, the second set controls which set of * + * protection checks are performed on each access and the third set * + * controls various DDR SDRAM timing parameters. * + * In order to config a DIMM bank, three fields must be initialized: * + * BANK_SIZE, DRAM_WIDTH, and BANK_ENABLE. The BANK_SIZE field sets * + * the address range that the MD unit will accept for that DIMM bank. * + * All addresses larger than the specified size will return errors on * + * access. In order to read from a DIMM bank, Bedrock must know * + * whether or not the bank contains x4 or x8/x16 DRAM. The operating * + * system must query the System Controller for this information and * + * then set the DRAM_WIDTH field accordingly. The BANK_ENABLE field * + * can be used to individually enable the two physical banks located * + * on each DIMM bank. * + * The contents of this register are preserved through soft-resets. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_memory_config_u { + bdrkreg_t md_memory_config_regval; + struct { + bdrkreg_t mc_dimm0_bank_enable : 2; + bdrkreg_t mc_reserved_7 : 1; + bdrkreg_t mc_dimm0_dram_width : 1; + bdrkreg_t mc_dimm0_bank_size : 4; + bdrkreg_t mc_dimm1_bank_enable : 2; + bdrkreg_t mc_reserved_6 : 1; + bdrkreg_t mc_dimm1_dram_width : 1; + bdrkreg_t mc_dimm1_bank_size : 4; + bdrkreg_t mc_dimm2_bank_enable : 2; + bdrkreg_t mc_reserved_5 : 1; + bdrkreg_t mc_dimm2_dram_width : 1; + bdrkreg_t mc_dimm2_bank_size : 4; + bdrkreg_t mc_dimm3_bank_enable : 2; + bdrkreg_t mc_reserved_4 : 1; + bdrkreg_t mc_dimm3_dram_width : 1; + bdrkreg_t mc_dimm3_bank_size : 4; + bdrkreg_t mc_dimm0_sel : 2; + bdrkreg_t mc_reserved_3 : 10; + bdrkreg_t mc_cc_enable : 1; + bdrkreg_t mc_io_prot_en : 1; + bdrkreg_t mc_io_prot_ignore : 1; + bdrkreg_t mc_cpu_prot_ignore : 1; + bdrkreg_t mc_db_neg_edge : 1; + bdrkreg_t mc_phase_delay : 1; + bdrkreg_t mc_delay_mux_sel : 2; + bdrkreg_t mc_sample_time : 2; + bdrkreg_t mc_reserved_2 : 2; + bdrkreg_t mc_mb_neg_edge : 3; + bdrkreg_t mc_reserved_1 : 1; + bdrkreg_t mc_rcd_config : 1; + bdrkreg_t mc_rp_config : 1; + bdrkreg_t mc_reserved : 2; + } md_memory_config_fld_s; +} md_memory_config_u_t; + +#else + +typedef union md_memory_config_u { + bdrkreg_t md_memory_config_regval; + struct { + bdrkreg_t mc_reserved : 2; + bdrkreg_t mc_rp_config : 1; + bdrkreg_t mc_rcd_config : 1; + bdrkreg_t mc_reserved_1 : 1; + bdrkreg_t mc_mb_neg_edge : 3; + bdrkreg_t mc_reserved_2 : 2; + bdrkreg_t mc_sample_time : 2; + bdrkreg_t mc_delay_mux_sel : 2; + bdrkreg_t mc_phase_delay : 1; + bdrkreg_t mc_db_neg_edge : 1; + bdrkreg_t mc_cpu_prot_ignore : 1; + bdrkreg_t mc_io_prot_ignore : 1; + bdrkreg_t mc_io_prot_en : 1; + bdrkreg_t mc_cc_enable : 1; + bdrkreg_t mc_reserved_3 : 10; + bdrkreg_t mc_dimm0_sel : 2; + bdrkreg_t mc_dimm3_bank_size : 4; + bdrkreg_t mc_dimm3_dram_width : 1; + bdrkreg_t mc_reserved_4 : 1; + bdrkreg_t mc_dimm3_bank_enable : 2; + bdrkreg_t mc_dimm2_bank_size : 4; + bdrkreg_t mc_dimm2_dram_width : 1; + bdrkreg_t mc_reserved_5 : 1; + bdrkreg_t mc_dimm2_bank_enable : 2; + bdrkreg_t mc_dimm1_bank_size : 4; + bdrkreg_t mc_dimm1_dram_width : 1; + bdrkreg_t mc_reserved_6 : 1; + bdrkreg_t mc_dimm1_bank_enable : 2; + bdrkreg_t mc_dimm0_bank_size : 4; + bdrkreg_t mc_dimm0_dram_width : 1; + bdrkreg_t mc_reserved_7 : 1; + bdrkreg_t mc_dimm0_bank_enable : 2; + } md_memory_config_fld_s; +} md_memory_config_u_t; + +#endif + + + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_arbitration_control_u { + bdrkreg_t md_arbitration_control_regval; + struct { + bdrkreg_t ac_reply_guar : 4; + bdrkreg_t ac_write_guar : 4; + bdrkreg_t ac_reserved : 56; + } md_arbitration_control_fld_s; +} md_arbitration_control_u_t; + +#else + +typedef union md_arbitration_control_u { + bdrkreg_t md_arbitration_control_regval; + struct { + bdrkreg_t ac_reserved : 56; + bdrkreg_t ac_write_guar : 4; + bdrkreg_t ac_reply_guar : 4; + } md_arbitration_control_fld_s; +} md_arbitration_control_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains page migration control fields. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mig_config_u { + bdrkreg_t md_mig_config_regval; + struct { + bdrkreg_t mc_mig_interval : 10; + bdrkreg_t mc_reserved_2 : 6; + bdrkreg_t mc_mig_node_mask : 8; + bdrkreg_t mc_reserved_1 : 8; + bdrkreg_t mc_mig_enable : 1; + bdrkreg_t mc_reserved : 31; + } md_mig_config_fld_s; +} md_mig_config_u_t; + +#else + +typedef union md_mig_config_u { + bdrkreg_t md_mig_config_regval; + struct { + bdrkreg_t mc_reserved : 31; + bdrkreg_t mc_mig_enable : 1; + bdrkreg_t mc_reserved_1 : 8; + bdrkreg_t mc_mig_node_mask : 8; + bdrkreg_t mc_reserved_2 : 6; + bdrkreg_t mc_mig_interval : 10; + } md_mig_config_fld_s; +} md_mig_config_u_t; + +#endif + + + + +/************************************************************************ + * * + * Each register contains the valid bit and address of the entry in * + * the fetch-and-op for cache 0 (or 1). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_fandop_cac_stat0_u { + bdrkreg_t md_fandop_cac_stat0_regval; + struct { + bdrkreg_t fcs_reserved_1 : 6; + bdrkreg_t fcs_addr : 27; + bdrkreg_t fcs_reserved : 30; + bdrkreg_t fcs_valid : 1; + } md_fandop_cac_stat0_fld_s; +} md_fandop_cac_stat0_u_t; + +#else + +typedef union md_fandop_cac_stat0_u { + bdrkreg_t md_fandop_cac_stat0_regval; + struct { + bdrkreg_t fcs_valid : 1; + bdrkreg_t fcs_reserved : 30; + bdrkreg_t fcs_addr : 27; + bdrkreg_t fcs_reserved_1 : 6; + } md_fandop_cac_stat0_fld_s; +} md_fandop_cac_stat0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Each register contains the valid bit and address of the entry in * + * the fetch-and-op for cache 0 (or 1). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_fandop_cac_stat1_u { + bdrkreg_t md_fandop_cac_stat1_regval; + struct { + bdrkreg_t fcs_reserved_1 : 6; + bdrkreg_t fcs_addr : 27; + bdrkreg_t fcs_reserved : 30; + bdrkreg_t fcs_valid : 1; + } md_fandop_cac_stat1_fld_s; +} md_fandop_cac_stat1_u_t; + +#else + +typedef union md_fandop_cac_stat1_u { + bdrkreg_t md_fandop_cac_stat1_regval; + struct { + bdrkreg_t fcs_valid : 1; + bdrkreg_t fcs_reserved : 30; + bdrkreg_t fcs_addr : 27; + bdrkreg_t fcs_reserved_1 : 6; + } md_fandop_cac_stat1_fld_s; +} md_fandop_cac_stat1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Contains a number of fields to capture various * + * random memory/directory errors. For each 2-bit field, the LSB * + * indicates that additional information has been captured for the * + * error and the MSB indicates overrun, thus: * + * x1: bits 51...0 of this register contain additional information * + * for the message that caused this error * + * 1x: overrun occurred * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_misc0_error_u { + bdrkreg_t md_misc0_error_regval; + struct { + bdrkreg_t me_command : 7; + bdrkreg_t me_reserved_4 : 1; + bdrkreg_t me_source : 11; + bdrkreg_t me_reserved_3 : 1; + bdrkreg_t me_suppl : 11; + bdrkreg_t me_reserved_2 : 1; + bdrkreg_t me_virtual_channel : 2; + bdrkreg_t me_reserved_1 : 2; + bdrkreg_t me_tail : 1; + bdrkreg_t me_reserved : 11; + bdrkreg_t me_xb_error : 4; + bdrkreg_t me_bad_partial_data : 2; + bdrkreg_t me_missing_dv : 2; + bdrkreg_t me_short_pack : 2; + bdrkreg_t me_long_pack : 2; + bdrkreg_t me_ill_msg : 2; + bdrkreg_t me_ill_revision : 2; + } md_misc0_error_fld_s; +} md_misc0_error_u_t; + +#else + +typedef union md_misc0_error_u { + bdrkreg_t md_misc0_error_regval; + struct { + bdrkreg_t me_ill_revision : 2; + bdrkreg_t me_ill_msg : 2; + bdrkreg_t me_long_pack : 2; + bdrkreg_t me_short_pack : 2; + bdrkreg_t me_missing_dv : 2; + bdrkreg_t me_bad_partial_data : 2; + bdrkreg_t me_xb_error : 4; + bdrkreg_t me_reserved : 11; + bdrkreg_t me_tail : 1; + bdrkreg_t me_reserved_1 : 2; + bdrkreg_t me_virtual_channel : 2; + bdrkreg_t me_reserved_2 : 1; + bdrkreg_t me_suppl : 11; + bdrkreg_t me_reserved_3 : 1; + bdrkreg_t me_source : 11; + bdrkreg_t me_reserved_4 : 1; + bdrkreg_t me_command : 7; + } md_misc0_error_fld_s; +} md_misc0_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Address for error captured in MISC0_ERROR. Error valid bits are * + * repeated in both MISC0_ERROR and MISC1_ERROR (allowing them to be * + * read sequentially without missing any errors). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_misc1_error_u { + bdrkreg_t md_misc1_error_regval; + struct { + bdrkreg_t me_reserved_1 : 3; + bdrkreg_t me_address : 38; + bdrkreg_t me_reserved : 7; + bdrkreg_t me_xb_error : 4; + bdrkreg_t me_bad_partial_data : 2; + bdrkreg_t me_missing_dv : 2; + bdrkreg_t me_short_pack : 2; + bdrkreg_t me_long_pack : 2; + bdrkreg_t me_ill_msg : 2; + bdrkreg_t me_ill_revision : 2; + } md_misc1_error_fld_s; +} md_misc1_error_u_t; + +#else + +typedef union md_misc1_error_u { + bdrkreg_t md_misc1_error_regval; + struct { + bdrkreg_t me_ill_revision : 2; + bdrkreg_t me_ill_msg : 2; + bdrkreg_t me_long_pack : 2; + bdrkreg_t me_short_pack : 2; + bdrkreg_t me_missing_dv : 2; + bdrkreg_t me_bad_partial_data : 2; + bdrkreg_t me_xb_error : 4; + bdrkreg_t me_reserved : 7; + bdrkreg_t me_address : 38; + bdrkreg_t me_reserved_1 : 3; + } md_misc1_error_fld_s; +} md_misc1_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Address for error captured in MISC0_ERROR. Error valid bits are * + * repeated in both MISC0_ERROR and MISC1_ERROR (allowing them to be * + * read sequentially without missing any errors). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_misc1_error_clr_u { + bdrkreg_t md_misc1_error_clr_regval; + struct { + bdrkreg_t mec_reserved_1 : 3; + bdrkreg_t mec_address : 38; + bdrkreg_t mec_reserved : 7; + bdrkreg_t mec_xb_error : 4; + bdrkreg_t mec_bad_partial_data : 2; + bdrkreg_t mec_missing_dv : 2; + bdrkreg_t mec_short_pack : 2; + bdrkreg_t mec_long_pack : 2; + bdrkreg_t mec_ill_msg : 2; + bdrkreg_t mec_ill_revision : 2; + } md_misc1_error_clr_fld_s; +} md_misc1_error_clr_u_t; + +#else + +typedef union md_misc1_error_clr_u { + bdrkreg_t md_misc1_error_clr_regval; + struct { + bdrkreg_t mec_ill_revision : 2; + bdrkreg_t mec_ill_msg : 2; + bdrkreg_t mec_long_pack : 2; + bdrkreg_t mec_short_pack : 2; + bdrkreg_t mec_missing_dv : 2; + bdrkreg_t mec_bad_partial_data : 2; + bdrkreg_t mec_xb_error : 4; + bdrkreg_t mec_reserved : 7; + bdrkreg_t mec_address : 38; + bdrkreg_t mec_reserved_1 : 3; + } md_misc1_error_clr_fld_s; +} md_misc1_error_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: The MD no longer allows for arbitrarily sizing the * + * reply queues, so all of the fields in this register are read-only * + * and contain the reset default value of 12 for the MOQHs (for * + * headers) and 24 for the MOQDs (for data). * + * Reading from this register returns the values currently held in * + * the MD's credit counters. Writing to the register resets the * + * counters to the default reset values specified in the table below. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_outgoing_rp_queue_size_u { + bdrkreg_t md_outgoing_rp_queue_size_regval; + struct { + bdrkreg_t orqs_reserved_6 : 8; + bdrkreg_t orqs_moqh_p0_rp_size : 4; + bdrkreg_t orqs_reserved_5 : 4; + bdrkreg_t orqs_moqh_p1_rp_size : 4; + bdrkreg_t orqs_reserved_4 : 4; + bdrkreg_t orqs_moqh_np_rp_size : 4; + bdrkreg_t orqs_reserved_3 : 4; + bdrkreg_t orqs_moqd_pi0_rp_size : 5; + bdrkreg_t orqs_reserved_2 : 3; + bdrkreg_t orqs_moqd_pi1_rp_size : 5; + bdrkreg_t orqs_reserved_1 : 3; + bdrkreg_t orqs_moqd_np_rp_size : 5; + bdrkreg_t orqs_reserved : 11; + } md_outgoing_rp_queue_size_fld_s; +} md_outgoing_rp_queue_size_u_t; + +#else + +typedef union md_outgoing_rp_queue_size_u { + bdrkreg_t md_outgoing_rp_queue_size_regval; + struct { + bdrkreg_t orqs_reserved : 11; + bdrkreg_t orqs_moqd_np_rp_size : 5; + bdrkreg_t orqs_reserved_1 : 3; + bdrkreg_t orqs_moqd_pi1_rp_size : 5; + bdrkreg_t orqs_reserved_2 : 3; + bdrkreg_t orqs_moqd_pi0_rp_size : 5; + bdrkreg_t orqs_reserved_3 : 4; + bdrkreg_t orqs_moqh_np_rp_size : 4; + bdrkreg_t orqs_reserved_4 : 4; + bdrkreg_t orqs_moqh_p1_rp_size : 4; + bdrkreg_t orqs_reserved_5 : 4; + bdrkreg_t orqs_moqh_p0_rp_size : 4; + bdrkreg_t orqs_reserved_6 : 8; + } md_outgoing_rp_queue_size_fld_s; +} md_outgoing_rp_queue_size_u_t; + +#endif + + + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_perf_sel0_u { + bdrkreg_t md_perf_sel0_regval; + struct { + bdrkreg_t ps_cnt_mode : 2; + bdrkreg_t ps_reserved_2 : 2; + bdrkreg_t ps_activity : 4; + bdrkreg_t ps_source : 7; + bdrkreg_t ps_reserved_1 : 1; + bdrkreg_t ps_channel : 4; + bdrkreg_t ps_command : 40; + bdrkreg_t ps_reserved : 3; + bdrkreg_t ps_interrupt : 1; + } md_perf_sel0_fld_s; +} md_perf_sel0_u_t; + +#else + +typedef union md_perf_sel0_u { + bdrkreg_t md_perf_sel0_regval; + struct { + bdrkreg_t ps_interrupt : 1; + bdrkreg_t ps_reserved : 3; + bdrkreg_t ps_command : 40; + bdrkreg_t ps_channel : 4; + bdrkreg_t ps_reserved_1 : 1; + bdrkreg_t ps_source : 7; + bdrkreg_t ps_activity : 4; + bdrkreg_t ps_reserved_2 : 2; + bdrkreg_t ps_cnt_mode : 2; + } md_perf_sel0_fld_s; +} md_perf_sel0_u_t; + +#endif + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_perf_sel1_u { + bdrkreg_t md_perf_sel1_regval; + struct { + bdrkreg_t ps_cnt_mode : 2; + bdrkreg_t ps_reserved_2 : 2; + bdrkreg_t ps_activity : 4; + bdrkreg_t ps_source : 7; + bdrkreg_t ps_reserved_1 : 1; + bdrkreg_t ps_channel : 4; + bdrkreg_t ps_command : 40; + bdrkreg_t ps_reserved : 3; + bdrkreg_t ps_interrupt : 1; + } md_perf_sel1_fld_s; +} md_perf_sel1_u_t; + +#else + +typedef union md_perf_sel1_u { + bdrkreg_t md_perf_sel1_regval; + struct { + bdrkreg_t ps_interrupt : 1; + bdrkreg_t ps_reserved : 3; + bdrkreg_t ps_command : 40; + bdrkreg_t ps_channel : 4; + bdrkreg_t ps_reserved_1 : 1; + bdrkreg_t ps_source : 7; + bdrkreg_t ps_activity : 4; + bdrkreg_t ps_reserved_2 : 2; + bdrkreg_t ps_cnt_mode : 2; + } md_perf_sel1_fld_s; +} md_perf_sel1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Performance counter. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_perf_cnt0_u { + bdrkreg_t md_perf_cnt0_regval; + struct { + bdrkreg_t pc_perf_cnt : 41; + bdrkreg_t pc_reserved : 23; + } md_perf_cnt0_fld_s; +} md_perf_cnt0_u_t; + +#else + +typedef union md_perf_cnt0_u { + bdrkreg_t md_perf_cnt0_regval; + struct { + bdrkreg_t pc_reserved : 23; + bdrkreg_t pc_perf_cnt : 41; + } md_perf_cnt0_fld_s; +} md_perf_cnt0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Performance counter. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_perf_cnt1_u { + bdrkreg_t md_perf_cnt1_regval; + struct { + bdrkreg_t pc_perf_cnt : 41; + bdrkreg_t pc_reserved : 23; + } md_perf_cnt1_fld_s; +} md_perf_cnt1_u_t; + +#else + +typedef union md_perf_cnt1_u { + bdrkreg_t md_perf_cnt1_regval; + struct { + bdrkreg_t pc_reserved : 23; + bdrkreg_t pc_perf_cnt : 41; + } md_perf_cnt1_fld_s; +} md_perf_cnt1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register contains the control for * + * memory/directory refresh. Once the MEMORY_CONFIG register contains * + * the correct DIMM information, the hardware takes care of * + * refreshing all the banks in the system. Therefore, the value in * + * the counter threshold is corresponds exactly to the refresh value * + * required by the SDRAM parts (expressed in Bedrock clock cycles). * + * The refresh will execute whenever there is a free cycle and there * + * are still banks that have not been refreshed in the current * + * window. If the window expires with banks still waiting to be * + * refreshed, all other transactions are halted until the banks are * + * refreshed. * + * The upper order bit contains an enable, which may be needed for * + * correct initialization of the DIMMs (according to the specs, the * + * first operation to the DIMMs should be a mode register write, not * + * a refresh, so this bit is cleared on reset) and is also useful for * + * diagnostic purposes. * + * For the SDRAM parts used by Bedrock, 4096 refreshes need to be * + * issued during every 64 ms window, resulting in a refresh threshold * + * of 3125 Bedrock cycles. * + * The ENABLE and CNT_THRESH fields of this register are preserved * + * through soft-resets. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_refresh_control_u { + bdrkreg_t md_refresh_control_regval; + struct { + bdrkreg_t rc_cnt_thresh : 12; + bdrkreg_t rc_counter : 12; + bdrkreg_t rc_reserved : 39; + bdrkreg_t rc_enable : 1; + } md_refresh_control_fld_s; +} md_refresh_control_u_t; + +#else + +typedef union md_refresh_control_u { + bdrkreg_t md_refresh_control_regval; + struct { + bdrkreg_t rc_enable : 1; + bdrkreg_t rc_reserved : 39; + bdrkreg_t rc_counter : 12; + bdrkreg_t rc_cnt_thresh : 12; + } md_refresh_control_fld_s; +} md_refresh_control_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register controls the read and write timing for Flash PROM, * + * UART and Synergy junk bus devices. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_junk_bus_timing_u { + bdrkreg_t md_junk_bus_timing_regval; + struct { + bdrkreg_t jbt_fprom_setup_hold : 8; + bdrkreg_t jbt_fprom_enable : 8; + bdrkreg_t jbt_uart_setup_hold : 8; + bdrkreg_t jbt_uart_enable : 8; + bdrkreg_t jbt_synergy_setup_hold : 8; + bdrkreg_t jbt_synergy_enable : 8; + bdrkreg_t jbt_reserved : 16; + } md_junk_bus_timing_fld_s; +} md_junk_bus_timing_u_t; + +#else + +typedef union md_junk_bus_timing_u { + bdrkreg_t md_junk_bus_timing_regval; + struct { + bdrkreg_t jbt_reserved : 16; + bdrkreg_t jbt_synergy_enable : 8; + bdrkreg_t jbt_synergy_setup_hold : 8; + bdrkreg_t jbt_uart_enable : 8; + bdrkreg_t jbt_uart_setup_hold : 8; + bdrkreg_t jbt_fprom_enable : 8; + bdrkreg_t jbt_fprom_setup_hold : 8; + } md_junk_bus_timing_fld_s; +} md_junk_bus_timing_u_t; + +#endif + + + + +/************************************************************************ + * * + * Each of these addresses allows the value on one 8-bit bank of * + * LEDs to be read. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_led0_u { + bdrkreg_t md_led0_regval; + struct { + bdrkreg_t l_data : 8; + bdrkreg_t l_reserved : 56; + } md_led0_fld_s; +} md_led0_u_t; + +#else + +typedef union md_led0_u { + bdrkreg_t md_led0_regval; + struct { + bdrkreg_t l_reserved : 56; + bdrkreg_t l_data : 8; + } md_led0_fld_s; +} md_led0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Each of these addresses allows the value on one 8-bit bank of * + * LEDs to be read. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_led1_u { + bdrkreg_t md_led1_regval; + struct { + bdrkreg_t l_data : 8; + bdrkreg_t l_reserved : 56; + } md_led1_fld_s; +} md_led1_u_t; + +#else + +typedef union md_led1_u { + bdrkreg_t md_led1_regval; + struct { + bdrkreg_t l_reserved : 56; + bdrkreg_t l_data : 8; + } md_led1_fld_s; +} md_led1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Each of these addresses allows the value on one 8-bit bank of * + * LEDs to be read. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_led2_u { + bdrkreg_t md_led2_regval; + struct { + bdrkreg_t l_data : 8; + bdrkreg_t l_reserved : 56; + } md_led2_fld_s; +} md_led2_u_t; + +#else + +typedef union md_led2_u { + bdrkreg_t md_led2_regval; + struct { + bdrkreg_t l_reserved : 56; + bdrkreg_t l_data : 8; + } md_led2_fld_s; +} md_led2_u_t; + +#endif + + + + +/************************************************************************ + * * + * Each of these addresses allows the value on one 8-bit bank of * + * LEDs to be read. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_led3_u { + bdrkreg_t md_led3_regval; + struct { + bdrkreg_t l_data : 8; + bdrkreg_t l_reserved : 56; + } md_led3_fld_s; +} md_led3_u_t; + +#else + +typedef union md_led3_u { + bdrkreg_t md_led3_regval; + struct { + bdrkreg_t l_reserved : 56; + bdrkreg_t l_data : 8; + } md_led3_fld_s; +} md_led3_u_t; + +#endif + + + + +/************************************************************************ + * * + * Core control for the BIST function. Start and stop BIST at any * + * time. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_ctl_u { + bdrkreg_t md_bist_ctl_regval; + struct { + bdrkreg_t bc_bist_start : 1; + bdrkreg_t bc_bist_stop : 1; + bdrkreg_t bc_bist_reset : 1; + bdrkreg_t bc_reserved_1 : 1; + bdrkreg_t bc_bank_num : 1; + bdrkreg_t bc_dimm_num : 2; + bdrkreg_t bc_reserved : 57; + } md_bist_ctl_fld_s; +} md_bist_ctl_u_t; + +#else + +typedef union md_bist_ctl_u { + bdrkreg_t md_bist_ctl_regval; + struct { + bdrkreg_t bc_reserved : 57; + bdrkreg_t bc_dimm_num : 2; + bdrkreg_t bc_bank_num : 1; + bdrkreg_t bc_reserved_1 : 1; + bdrkreg_t bc_bist_reset : 1; + bdrkreg_t bc_bist_stop : 1; + bdrkreg_t bc_bist_start : 1; + } md_bist_ctl_fld_s; +} md_bist_ctl_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contain the initial BIST data nibble and the 4-bit data control * + * field.. * + * * + ************************************************************************/ + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_data_u { + bdrkreg_t md_bist_data_regval; + struct { + bdrkreg_t bd_bist_data : 4; + bdrkreg_t bd_bist_nibble : 1; + bdrkreg_t bd_bist_byte : 1; + bdrkreg_t bd_bist_cycle : 1; + bdrkreg_t bd_bist_write : 1; + bdrkreg_t bd_reserved : 56; + } md_bist_data_fld_s; +} md_bist_data_u_t; + +#else + +typedef union md_bist_data_u { + bdrkreg_t md_bist_data_regval; + struct { + bdrkreg_t bd_reserved : 56; + bdrkreg_t bd_bist_write : 1; + bdrkreg_t bd_bist_cycle : 1; + bdrkreg_t bd_bist_byte : 1; + bdrkreg_t bd_bist_nibble : 1; + bdrkreg_t bd_bist_data : 4; + } md_bist_data_fld_s; +} md_bist_data_u_t; + +#endif + + + + +/************************************************************************ + * * + * Captures the BIST error address and indicates whether it is an MB * + * error or DB error. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_ab_err_addr_u { + bdrkreg_t md_bist_ab_err_addr_regval; + struct { + bdrkreg_t baea_be_db_cas_addr : 15; + bdrkreg_t baea_reserved_3 : 1; + bdrkreg_t baea_be_mb_cas_addr : 15; + bdrkreg_t baea_reserved_2 : 1; + bdrkreg_t baea_be_ras_addr : 15; + bdrkreg_t baea_reserved_1 : 1; + bdrkreg_t baea_bist_mb_error : 1; + bdrkreg_t baea_bist_db_error : 1; + bdrkreg_t baea_reserved : 14; + } md_bist_ab_err_addr_fld_s; +} md_bist_ab_err_addr_u_t; + +#else + +typedef union md_bist_ab_err_addr_u { + bdrkreg_t md_bist_ab_err_addr_regval; + struct { + bdrkreg_t baea_reserved : 14; + bdrkreg_t baea_bist_db_error : 1; + bdrkreg_t baea_bist_mb_error : 1; + bdrkreg_t baea_reserved_1 : 1; + bdrkreg_t baea_be_ras_addr : 15; + bdrkreg_t baea_reserved_2 : 1; + bdrkreg_t baea_be_mb_cas_addr : 15; + bdrkreg_t baea_reserved_3 : 1; + bdrkreg_t baea_be_db_cas_addr : 15; + } md_bist_ab_err_addr_fld_s; +} md_bist_ab_err_addr_u_t; + +#endif + + + +/************************************************************************ + * * + * Contains information on BIST progress and memory bank currently * + * under BIST. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_status_u { + bdrkreg_t md_bist_status_regval; + struct { + bdrkreg_t bs_bist_passed : 1; + bdrkreg_t bs_bist_done : 1; + bdrkreg_t bs_reserved : 62; + } md_bist_status_fld_s; +} md_bist_status_u_t; + +#else + +typedef union md_bist_status_u { + bdrkreg_t md_bist_status_regval; + struct { + bdrkreg_t bs_reserved : 62; + bdrkreg_t bs_bist_done : 1; + bdrkreg_t bs_bist_passed : 1; + } md_bist_status_fld_s; +} md_bist_status_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains 3 bits that allow the selection of IB debug information * + * at the debug port (see design specification for available debug * + * information). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_ib_debug_u { + bdrkreg_t md_ib_debug_regval; + struct { + bdrkreg_t id_ib_debug_sel : 2; + bdrkreg_t id_reserved : 62; + } md_ib_debug_fld_s; +} md_ib_debug_u_t; + +#else + +typedef union md_ib_debug_u { + bdrkreg_t md_ib_debug_regval; + struct { + bdrkreg_t id_reserved : 62; + bdrkreg_t id_ib_debug_sel : 2; + } md_ib_debug_fld_s; +} md_ib_debug_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains the directory specific mode bits. The contents of this * + * register are preserved through soft-resets. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_dir_config_u { + bdrkreg_t md_dir_config_regval; + struct { + bdrkreg_t dc_dir_flavor : 1; + bdrkreg_t dc_ignore_dir_ecc : 1; + bdrkreg_t dc_reserved : 62; + } md_dir_config_fld_s; +} md_dir_config_u_t; + +#else + +typedef union md_dir_config_u { + bdrkreg_t md_dir_config_regval; + struct { + bdrkreg_t dc_reserved : 62; + bdrkreg_t dc_ignore_dir_ecc : 1; + bdrkreg_t dc_dir_flavor : 1; + } md_dir_config_fld_s; +} md_dir_config_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Contains information on uncorrectable and * + * correctable directory ECC errors, along with protection ECC * + * errors. The priority of ECC errors latched is: uncorrectable * + * directory, protection error, correctable directory. Thus the valid * + * bits signal: * + * 1xxx: uncorrectable directory ECC error (UCE) * + * 01xx: access protection double bit error (AE) * + * 001x: correctable directory ECC error (CE) * + * 0001: access protection correctable error (ACE) * + * If the UCE valid bit is set, the address field contains a pointer * + * to the Hspec address of the offending directory entry, the * + * syndrome field contains the bad syndrome, and the UCE overrun bit * + * indicates whether multiple double-bit errors were received. * + * If the UCE valid bit is clear but the AE valid bit is set, the * + * address field contains a pointer to the Hspec address of the * + * offending protection entry, the Bad Protection field contains the * + * 4-bit bad protection value, the PROT_INDEX field shows which of * + * the 8 protection values in the word was bad and the AE overrun bit * + * indicates whether multiple AE errors were received. * + * If the UCE and AE valid bits are clear, but the CE valid bit is * + * set, the address field contains a pointer to the Hspec address of * + * the offending directory entry, the syndrome field contains the bad * + * syndrome, and the CE overrun bit indicates whether multiple * + * single-bit errors were received. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_dir_error_u { + bdrkreg_t md_dir_error_regval; + struct { + bdrkreg_t de_reserved_3 : 3; + bdrkreg_t de_hspec_addr : 30; + bdrkreg_t de_reserved_2 : 7; + bdrkreg_t de_bad_syn : 7; + bdrkreg_t de_reserved_1 : 1; + bdrkreg_t de_bad_protect : 4; + bdrkreg_t de_prot_index : 3; + bdrkreg_t de_reserved : 1; + bdrkreg_t de_ace_overrun : 1; + bdrkreg_t de_ce_overrun : 1; + bdrkreg_t de_ae_overrun : 1; + bdrkreg_t de_uce_overrun : 1; + bdrkreg_t de_ace_valid : 1; + bdrkreg_t de_ce_valid : 1; + bdrkreg_t de_ae_valid : 1; + bdrkreg_t de_uce_valid : 1; + } md_dir_error_fld_s; +} md_dir_error_u_t; + +#else + +typedef union md_dir_error_u { + bdrkreg_t md_dir_error_regval; + struct { + bdrkreg_t de_uce_valid : 1; + bdrkreg_t de_ae_valid : 1; + bdrkreg_t de_ce_valid : 1; + bdrkreg_t de_ace_valid : 1; + bdrkreg_t de_uce_overrun : 1; + bdrkreg_t de_ae_overrun : 1; + bdrkreg_t de_ce_overrun : 1; + bdrkreg_t de_ace_overrun : 1; + bdrkreg_t de_reserved : 1; + bdrkreg_t de_prot_index : 3; + bdrkreg_t de_bad_protect : 4; + bdrkreg_t de_reserved_1 : 1; + bdrkreg_t de_bad_syn : 7; + bdrkreg_t de_reserved_2 : 7; + bdrkreg_t de_hspec_addr : 30; + bdrkreg_t de_reserved_3 : 3; + } md_dir_error_fld_s; +} md_dir_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Contains information on uncorrectable and * + * correctable directory ECC errors, along with protection ECC * + * errors. The priority of ECC errors latched is: uncorrectable * + * directory, protection error, correctable directory. Thus the valid * + * bits signal: * + * 1xxx: uncorrectable directory ECC error (UCE) * + * 01xx: access protection double bit error (AE) * + * 001x: correctable directory ECC error (CE) * + * 0001: access protection correctable error (ACE) * + * If the UCE valid bit is set, the address field contains a pointer * + * to the Hspec address of the offending directory entry, the * + * syndrome field contains the bad syndrome, and the UCE overrun bit * + * indicates whether multiple double-bit errors were received. * + * If the UCE valid bit is clear but the AE valid bit is set, the * + * address field contains a pointer to the Hspec address of the * + * offending protection entry, the Bad Protection field contains the * + * 4-bit bad protection value, the PROT_INDEX field shows which of * + * the 8 protection values in the word was bad and the AE overrun bit * + * indicates whether multiple AE errors were received. * + * If the UCE and AE valid bits are clear, but the CE valid bit is * + * set, the address field contains a pointer to the Hspec address of * + * the offending directory entry, the syndrome field contains the bad * + * syndrome, and the CE overrun bit indicates whether multiple * + * single-bit errors were received. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_dir_error_clr_u { + bdrkreg_t md_dir_error_clr_regval; + struct { + bdrkreg_t dec_reserved_3 : 3; + bdrkreg_t dec_hspec_addr : 30; + bdrkreg_t dec_reserved_2 : 7; + bdrkreg_t dec_bad_syn : 7; + bdrkreg_t dec_reserved_1 : 1; + bdrkreg_t dec_bad_protect : 4; + bdrkreg_t dec_prot_index : 3; + bdrkreg_t dec_reserved : 1; + bdrkreg_t dec_ace_overrun : 1; + bdrkreg_t dec_ce_overrun : 1; + bdrkreg_t dec_ae_overrun : 1; + bdrkreg_t dec_uce_overrun : 1; + bdrkreg_t dec_ace_valid : 1; + bdrkreg_t dec_ce_valid : 1; + bdrkreg_t dec_ae_valid : 1; + bdrkreg_t dec_uce_valid : 1; + } md_dir_error_clr_fld_s; +} md_dir_error_clr_u_t; + +#else + +typedef union md_dir_error_clr_u { + bdrkreg_t md_dir_error_clr_regval; + struct { + bdrkreg_t dec_uce_valid : 1; + bdrkreg_t dec_ae_valid : 1; + bdrkreg_t dec_ce_valid : 1; + bdrkreg_t dec_ace_valid : 1; + bdrkreg_t dec_uce_overrun : 1; + bdrkreg_t dec_ae_overrun : 1; + bdrkreg_t dec_ce_overrun : 1; + bdrkreg_t dec_ace_overrun : 1; + bdrkreg_t dec_reserved : 1; + bdrkreg_t dec_prot_index : 3; + bdrkreg_t dec_bad_protect : 4; + bdrkreg_t dec_reserved_1 : 1; + bdrkreg_t dec_bad_syn : 7; + bdrkreg_t dec_reserved_2 : 7; + bdrkreg_t dec_hspec_addr : 30; + bdrkreg_t dec_reserved_3 : 3; + } md_dir_error_clr_fld_s; +} md_dir_error_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains information on requests that encounter no valid protocol * + * table entry. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_protocol_error_u { + bdrkreg_t md_protocol_error_regval; + struct { + bdrkreg_t pe_overrun : 1; + bdrkreg_t pe_pointer_me : 1; + bdrkreg_t pe_reserved_1 : 1; + bdrkreg_t pe_address : 30; + bdrkreg_t pe_reserved : 1; + bdrkreg_t pe_ptr1_btmbits : 3; + bdrkreg_t pe_dir_format : 2; + bdrkreg_t pe_dir_state : 3; + bdrkreg_t pe_priority : 1; + bdrkreg_t pe_access : 1; + bdrkreg_t pe_msg_type : 8; + bdrkreg_t pe_initiator : 11; + bdrkreg_t pe_valid : 1; + } md_protocol_error_fld_s; +} md_protocol_error_u_t; + +#else + +typedef union md_protocol_error_u { + bdrkreg_t md_protocol_error_regval; + struct { + bdrkreg_t pe_valid : 1; + bdrkreg_t pe_initiator : 11; + bdrkreg_t pe_msg_type : 8; + bdrkreg_t pe_access : 1; + bdrkreg_t pe_priority : 1; + bdrkreg_t pe_dir_state : 3; + bdrkreg_t pe_dir_format : 2; + bdrkreg_t pe_ptr1_btmbits : 3; + bdrkreg_t pe_reserved : 1; + bdrkreg_t pe_address : 30; + bdrkreg_t pe_reserved_1 : 1; + bdrkreg_t pe_pointer_me : 1; + bdrkreg_t pe_overrun : 1; + } md_protocol_error_fld_s; +} md_protocol_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains information on requests that encounter no valid protocol * + * table entry. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_protocol_err_clr_u { + bdrkreg_t md_protocol_err_clr_regval; + struct { + bdrkreg_t pec_overrun : 1; + bdrkreg_t pec_pointer_me : 1; + bdrkreg_t pec_reserved_1 : 1; + bdrkreg_t pec_address : 30; + bdrkreg_t pec_reserved : 1; + bdrkreg_t pec_ptr1_btmbits : 3; + bdrkreg_t pec_dir_format : 2; + bdrkreg_t pec_dir_state : 3; + bdrkreg_t pec_priority : 1; + bdrkreg_t pec_access : 1; + bdrkreg_t pec_msg_type : 8; + bdrkreg_t pec_initiator : 11; + bdrkreg_t pec_valid : 1; + } md_protocol_err_clr_fld_s; +} md_protocol_err_clr_u_t; + +#else + +typedef union md_protocol_err_clr_u { + bdrkreg_t md_protocol_err_clr_regval; + struct { + bdrkreg_t pec_valid : 1; + bdrkreg_t pec_initiator : 11; + bdrkreg_t pec_msg_type : 8; + bdrkreg_t pec_access : 1; + bdrkreg_t pec_priority : 1; + bdrkreg_t pec_dir_state : 3; + bdrkreg_t pec_dir_format : 2; + bdrkreg_t pec_ptr1_btmbits : 3; + bdrkreg_t pec_reserved : 1; + bdrkreg_t pec_address : 30; + bdrkreg_t pec_reserved_1 : 1; + bdrkreg_t pec_pointer_me : 1; + bdrkreg_t pec_overrun : 1; + } md_protocol_err_clr_fld_s; +} md_protocol_err_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains the address of the page and the requestor which caused a * + * migration threshold to be exceeded. Also contains the type of * + * threshold exceeded and an overrun bit. For Value mode type * + * interrupts, it indicates whether the local or the remote counter * + * triggered the interrupt. Unlike most registers, when the overrun * + * bit is set the register contains information on the most recent * + * (the last) migration candidate. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mig_candidate_u { + bdrkreg_t md_mig_candidate_regval; + struct { + bdrkreg_t mc_address : 21; + bdrkreg_t mc_initiator : 11; + bdrkreg_t mc_overrun : 1; + bdrkreg_t mc_type : 1; + bdrkreg_t mc_local : 1; + bdrkreg_t mc_reserved : 28; + bdrkreg_t mc_valid : 1; + } md_mig_candidate_fld_s; +} md_mig_candidate_u_t; + +#else + +typedef union md_mig_candidate_u { + bdrkreg_t md_mig_candidate_regval; + struct { + bdrkreg_t mc_valid : 1; + bdrkreg_t mc_reserved : 28; + bdrkreg_t mc_local : 1; + bdrkreg_t mc_type : 1; + bdrkreg_t mc_overrun : 1; + bdrkreg_t mc_initiator : 11; + bdrkreg_t mc_address : 21; + } md_mig_candidate_fld_s; +} md_mig_candidate_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains the address of the page and the requestor which caused a * + * migration threshold to be exceeded. Also contains the type of * + * threshold exceeded and an overrun bit. For Value mode type * + * interrupts, it indicates whether the local or the remote counter * + * triggered the interrupt. Unlike most registers, when the overrun * + * bit is set the register contains information on the most recent * + * (the last) migration candidate. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mig_candidate_clr_u { + bdrkreg_t md_mig_candidate_clr_regval; + struct { + bdrkreg_t mcc_address : 21; + bdrkreg_t mcc_initiator : 11; + bdrkreg_t mcc_overrun : 1; + bdrkreg_t mcc_type : 1; + bdrkreg_t mcc_local : 1; + bdrkreg_t mcc_reserved : 28; + bdrkreg_t mcc_valid : 1; + } md_mig_candidate_clr_fld_s; +} md_mig_candidate_clr_u_t; + +#else + +typedef union md_mig_candidate_clr_u { + bdrkreg_t md_mig_candidate_clr_regval; + struct { + bdrkreg_t mcc_valid : 1; + bdrkreg_t mcc_reserved : 28; + bdrkreg_t mcc_local : 1; + bdrkreg_t mcc_type : 1; + bdrkreg_t mcc_overrun : 1; + bdrkreg_t mcc_initiator : 11; + bdrkreg_t mcc_address : 21; + } md_mig_candidate_clr_fld_s; +} md_mig_candidate_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Controls the generation of page-migration interrupts and loading * + * of the MIGRATION_CANDIDATE register for pages which are using the * + * difference between the requestor and home counts. If the * + * difference is greater-than or equal to than the threshold * + * contained in the register, and the valid bit is set, the migration * + * candidate is loaded (and an interrupt generated if enabled by the * + * page migration mode). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mig_diff_thresh_u { + bdrkreg_t md_mig_diff_thresh_regval; + struct { + bdrkreg_t mdt_threshold : 15; + bdrkreg_t mdt_reserved_1 : 17; + bdrkreg_t mdt_th_action : 3; + bdrkreg_t mdt_sat_action : 3; + bdrkreg_t mdt_reserved : 25; + bdrkreg_t mdt_valid : 1; + } md_mig_diff_thresh_fld_s; +} md_mig_diff_thresh_u_t; + +#else + +typedef union md_mig_diff_thresh_u { + bdrkreg_t md_mig_diff_thresh_regval; + struct { + bdrkreg_t mdt_valid : 1; + bdrkreg_t mdt_reserved : 25; + bdrkreg_t mdt_sat_action : 3; + bdrkreg_t mdt_th_action : 3; + bdrkreg_t mdt_reserved_1 : 17; + bdrkreg_t mdt_threshold : 15; + } md_mig_diff_thresh_fld_s; +} md_mig_diff_thresh_u_t; + +#endif + + + + +/************************************************************************ + * * + * Controls the generation of page-migration interrupts and loading * + * of the MIGRATION_CANDIDATE register for pages that are using the * + * absolute value of the requestor count. If the value is * + * greater-than or equal to the threshold contained in the register, * + * and the register valid bit is set, the migration candidate is * + * loaded and an interrupt generated. For the value mode of page * + * migration, there are two variations. In the first variation, * + * interrupts are only generated when the remote counter reaches the * + * threshold, not when the local counter reaches the threshold. In * + * the second mode, both the local counter and the remote counter * + * generate interrupts if they reach the threshold. This second mode * + * is useful for performance monitoring, to track the number of local * + * and remote references to a page. LOCAL_INT determines whether we * + * will generate interrupts when the local counter reaches the * + * threshold. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mig_value_thresh_u { + bdrkreg_t md_mig_value_thresh_regval; + struct { + bdrkreg_t mvt_threshold : 15; + bdrkreg_t mvt_reserved_1 : 17; + bdrkreg_t mvt_th_action : 3; + bdrkreg_t mvt_sat_action : 3; + bdrkreg_t mvt_reserved : 24; + bdrkreg_t mvt_local_int : 1; + bdrkreg_t mvt_valid : 1; + } md_mig_value_thresh_fld_s; +} md_mig_value_thresh_u_t; + +#else + +typedef union md_mig_value_thresh_u { + bdrkreg_t md_mig_value_thresh_regval; + struct { + bdrkreg_t mvt_valid : 1; + bdrkreg_t mvt_local_int : 1; + bdrkreg_t mvt_reserved : 24; + bdrkreg_t mvt_sat_action : 3; + bdrkreg_t mvt_th_action : 3; + bdrkreg_t mvt_reserved_1 : 17; + bdrkreg_t mvt_threshold : 15; + } md_mig_value_thresh_fld_s; +} md_mig_value_thresh_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains the controls for the sizing of the three MOQH request * + * queues. The maximum (and default) value is 4. Queue sizes are in * + * flits. One header equals one flit. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_outgoing_rq_queue_size_u { + bdrkreg_t md_outgoing_rq_queue_size_regval; + struct { + bdrkreg_t orqs_reserved_3 : 8; + bdrkreg_t orqs_moqh_p0_rq_size : 3; + bdrkreg_t orqs_reserved_2 : 5; + bdrkreg_t orqs_moqh_p1_rq_size : 3; + bdrkreg_t orqs_reserved_1 : 5; + bdrkreg_t orqs_moqh_np_rq_size : 3; + bdrkreg_t orqs_reserved : 37; + } md_outgoing_rq_queue_size_fld_s; +} md_outgoing_rq_queue_size_u_t; + +#else + +typedef union md_outgoing_rq_queue_size_u { + bdrkreg_t md_outgoing_rq_queue_size_regval; + struct { + bdrkreg_t orqs_reserved : 37; + bdrkreg_t orqs_moqh_np_rq_size : 3; + bdrkreg_t orqs_reserved_1 : 5; + bdrkreg_t orqs_moqh_p1_rq_size : 3; + bdrkreg_t orqs_reserved_2 : 5; + bdrkreg_t orqs_moqh_p0_rq_size : 3; + bdrkreg_t orqs_reserved_3 : 8; + } md_outgoing_rq_queue_size_fld_s; +} md_outgoing_rq_queue_size_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains the 32-bit directory word failing BIST. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_db_err_data_u { + bdrkreg_t md_bist_db_err_data_regval; + struct { + bdrkreg_t bded_db_er_d : 32; + bdrkreg_t bded_reserved : 32; + } md_bist_db_err_data_fld_s; +} md_bist_db_err_data_u_t; + +#else + +typedef union md_bist_db_err_data_u { + bdrkreg_t md_bist_db_err_data_regval; + struct { + bdrkreg_t bded_reserved : 32; + bdrkreg_t bded_db_er_d : 32; + } md_bist_db_err_data_fld_s; +} md_bist_db_err_data_u_t; + +#endif + + + +/************************************************************************ + * * + * Contains 2 bits that allow the selection of DB debug information * + * at the debug port (see the design specification for descrition of * + * the available debug information). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_db_debug_u { + bdrkreg_t md_db_debug_regval; + struct { + bdrkreg_t dd_db_debug_sel : 2; + bdrkreg_t dd_reserved : 62; + } md_db_debug_fld_s; +} md_db_debug_u_t; + +#else + +typedef union md_db_debug_u { + bdrkreg_t md_db_debug_regval; + struct { + bdrkreg_t dd_reserved : 62; + bdrkreg_t dd_db_debug_sel : 2; + } md_db_debug_fld_s; +} md_db_debug_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains the IgnoreECC bit. When this bit is set, all ECC errors * + * are ignored. ECC bits will still be generated on writebacks. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mb_ecc_config_u { + bdrkreg_t md_mb_ecc_config_regval; + struct { + bdrkreg_t mec_ignore_dataecc : 1; + bdrkreg_t mec_reserved : 63; + } md_mb_ecc_config_fld_s; +} md_mb_ecc_config_u_t; + +#else + +typedef union md_mb_ecc_config_u { + bdrkreg_t md_mb_ecc_config_regval; + struct { + bdrkreg_t mec_reserved : 63; + bdrkreg_t mec_ignore_dataecc : 1; + } md_mb_ecc_config_fld_s; +} md_mb_ecc_config_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Contains information on read memory errors (both * + * correctable and uncorrectable) and write memory errors (always * + * uncorrectable). The errors are prioritized as follows: * + * highest: uncorrectable read error (READ_UCE) * + * middle: write error (WRITE_UCE) * + * lowest: correctable read error (READ_CE) * + * Each type of error maintains a two-bit valid/overrun field * + * (READ_UCE, WRITE_UCE, or READ_CE). Bit 0 of each two-bit field * + * corresponds to the valid bit, and bit 1 of each two-bit field * + * corresponds to the overrun bit. * + * The rule for the valid bit is that it gets set whenever that error * + * occurs, regardless of whether a higher priority error has occured. * + * The rule for the overrun bit is that it gets set whenever we are * + * unable to record the address information for this particular * + * error, due to a previous error of the same or higher priority. * + * Note that the syndrome and address information always corresponds * + * to the earliest, highest priority error. * + * Finally, the UCE_DIFF_ADDR bit is set whenever there have been * + * several uncorrectable errors, to different cache line addresses. * + * If all the UCEs were to the same cache line address, then * + * UCE_DIFF_ADDR will be 0. This allows the operating system to * + * detect the case where a UCE error is read exclusively, and then * + * written back by the processor. If the bit is 0, it indicates that * + * no information has been lost about UCEs on other cache lines. In * + * particular, partial writes do a read modify write of the cache * + * line. A UCE read error will be set when the cache line is read, * + * and a UCE write error will occur when the cache line is written * + * back, but the UCE_DIFF_ADDR will not be set. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mem_error_u { + bdrkreg_t md_mem_error_regval; + struct { + bdrkreg_t me_reserved_5 : 3; + bdrkreg_t me_address : 30; + bdrkreg_t me_reserved_4 : 7; + bdrkreg_t me_bad_syn : 8; + bdrkreg_t me_reserved_3 : 4; + bdrkreg_t me_read_ce : 2; + bdrkreg_t me_reserved_2 : 2; + bdrkreg_t me_write_uce : 2; + bdrkreg_t me_reserved_1 : 2; + bdrkreg_t me_read_uce : 2; + bdrkreg_t me_reserved : 1; + bdrkreg_t me_uce_diff_addr : 1; + } md_mem_error_fld_s; +} md_mem_error_u_t; + +#else + +typedef union md_mem_error_u { + bdrkreg_t md_mem_error_regval; + struct { + bdrkreg_t me_uce_diff_addr : 1; + bdrkreg_t me_reserved : 1; + bdrkreg_t me_read_uce : 2; + bdrkreg_t me_reserved_1 : 2; + bdrkreg_t me_write_uce : 2; + bdrkreg_t me_reserved_2 : 2; + bdrkreg_t me_read_ce : 2; + bdrkreg_t me_reserved_3 : 4; + bdrkreg_t me_bad_syn : 8; + bdrkreg_t me_reserved_4 : 7; + bdrkreg_t me_address : 30; + bdrkreg_t me_reserved_5 : 3; + } md_mem_error_fld_s; +} md_mem_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Contains information on read memory errors (both * + * correctable and uncorrectable) and write memory errors (always * + * uncorrectable). The errors are prioritized as follows: * + * highest: uncorrectable read error (READ_UCE) * + * middle: write error (WRITE_UCE) * + * lowest: correctable read error (READ_CE) * + * Each type of error maintains a two-bit valid/overrun field * + * (READ_UCE, WRITE_UCE, or READ_CE). Bit 0 of each two-bit field * + * corresponds to the valid bit, and bit 1 of each two-bit field * + * corresponds to the overrun bit. * + * The rule for the valid bit is that it gets set whenever that error * + * occurs, regardless of whether a higher priority error has occured. * + * The rule for the overrun bit is that it gets set whenever we are * + * unable to record the address information for this particular * + * error, due to a previous error of the same or higher priority. * + * Note that the syndrome and address information always corresponds * + * to the earliest, highest priority error. * + * Finally, the UCE_DIFF_ADDR bit is set whenever there have been * + * several uncorrectable errors, to different cache line addresses. * + * If all the UCEs were to the same cache line address, then * + * UCE_DIFF_ADDR will be 0. This allows the operating system to * + * detect the case where a UCE error is read exclusively, and then * + * written back by the processor. If the bit is 0, it indicates that * + * no information has been lost about UCEs on other cache lines. In * + * particular, partial writes do a read modify write of the cache * + * line. A UCE read error will be set when the cache line is read, * + * and a UCE write error will occur when the cache line is written * + * back, but the UCE_DIFF_ADDR will not be set. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mem_error_clr_u { + bdrkreg_t md_mem_error_clr_regval; + struct { + bdrkreg_t mec_reserved_5 : 3; + bdrkreg_t mec_address : 30; + bdrkreg_t mec_reserved_4 : 7; + bdrkreg_t mec_bad_syn : 8; + bdrkreg_t mec_reserved_3 : 4; + bdrkreg_t mec_read_ce : 2; + bdrkreg_t mec_reserved_2 : 2; + bdrkreg_t mec_write_uce : 2; + bdrkreg_t mec_reserved_1 : 2; + bdrkreg_t mec_read_uce : 2; + bdrkreg_t mec_reserved : 1; + bdrkreg_t mec_uce_diff_addr : 1; + } md_mem_error_clr_fld_s; +} md_mem_error_clr_u_t; + +#else + +typedef union md_mem_error_clr_u { + bdrkreg_t md_mem_error_clr_regval; + struct { + bdrkreg_t mec_uce_diff_addr : 1; + bdrkreg_t mec_reserved : 1; + bdrkreg_t mec_read_uce : 2; + bdrkreg_t mec_reserved_1 : 2; + bdrkreg_t mec_write_uce : 2; + bdrkreg_t mec_reserved_2 : 2; + bdrkreg_t mec_read_ce : 2; + bdrkreg_t mec_reserved_3 : 4; + bdrkreg_t mec_bad_syn : 8; + bdrkreg_t mec_reserved_4 : 7; + bdrkreg_t mec_address : 30; + bdrkreg_t mec_reserved_5 : 3; + } md_mem_error_clr_fld_s; +} md_mem_error_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains one-quarter of the error memory line failing BIST. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_mb_err_data_0_u { + bdrkreg_t md_bist_mb_err_data_0_regval; + struct { + bdrkreg_t bmed0_mb_er_d : 36; + bdrkreg_t bmed0_reserved : 28; + } md_bist_mb_err_data_0_fld_s; +} md_bist_mb_err_data_0_u_t; + +#else + +typedef union md_bist_mb_err_data_0_u { + bdrkreg_t md_bist_mb_err_data_0_regval; + struct { + bdrkreg_t bmed0_reserved : 28; + bdrkreg_t bmed0_mb_er_d : 36; + } md_bist_mb_err_data_0_fld_s; +} md_bist_mb_err_data_0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains one-quarter of the error memory line failing BIST. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_mb_err_data_1_u { + bdrkreg_t md_bist_mb_err_data_1_regval; + struct { + bdrkreg_t bmed1_mb_er_d : 36; + bdrkreg_t bmed1_reserved : 28; + } md_bist_mb_err_data_1_fld_s; +} md_bist_mb_err_data_1_u_t; + +#else + +typedef union md_bist_mb_err_data_1_u { + bdrkreg_t md_bist_mb_err_data_1_regval; + struct { + bdrkreg_t bmed1_reserved : 28; + bdrkreg_t bmed1_mb_er_d : 36; + } md_bist_mb_err_data_1_fld_s; +} md_bist_mb_err_data_1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains one-quarter of the error memory line failing BIST. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_mb_err_data_2_u { + bdrkreg_t md_bist_mb_err_data_2_regval; + struct { + bdrkreg_t bmed2_mb_er_d : 36; + bdrkreg_t bmed2_reserved : 28; + } md_bist_mb_err_data_2_fld_s; +} md_bist_mb_err_data_2_u_t; + +#else + +typedef union md_bist_mb_err_data_2_u { + bdrkreg_t md_bist_mb_err_data_2_regval; + struct { + bdrkreg_t bmed2_reserved : 28; + bdrkreg_t bmed2_mb_er_d : 36; + } md_bist_mb_err_data_2_fld_s; +} md_bist_mb_err_data_2_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains one-quarter of the error memory line failing BIST. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_bist_mb_err_data_3_u { + bdrkreg_t md_bist_mb_err_data_3_regval; + struct { + bdrkreg_t bmed3_mb_er_d : 36; + bdrkreg_t bmed3_reserved : 28; + } md_bist_mb_err_data_3_fld_s; +} md_bist_mb_err_data_3_u_t; + +#else + +typedef union md_bist_mb_err_data_3_u { + bdrkreg_t md_bist_mb_err_data_3_regval; + struct { + bdrkreg_t bmed3_reserved : 28; + bdrkreg_t bmed3_mb_er_d : 36; + } md_bist_mb_err_data_3_fld_s; +} md_bist_mb_err_data_3_u_t; + +#endif + + + + +/************************************************************************ + * * + * Contains 1 bit that allow the selection of MB debug information * + * at the debug port (see the design specification for the available * + * debug information). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union md_mb_debug_u { + bdrkreg_t md_mb_debug_regval; + struct { + bdrkreg_t md_mb_debug_sel : 1; + bdrkreg_t md_reserved : 63; + } md_mb_debug_fld_s; +} md_mb_debug_u_t; + +#else + +typedef union md_mb_debug_u { + bdrkreg_t md_mb_debug_regval; + struct { + bdrkreg_t md_reserved : 63; + bdrkreg_t md_mb_debug_sel : 1; + } md_mb_debug_fld_s; +} md_mb_debug_u_t; + +#endif + + + + + + +#endif /* _LANGUAGE_C */ + +/************************************************************************ + * * + * MAKE ALL ADDITIONS AFTER THIS LINE * + * * + ************************************************************************/ + + + + +#endif /* _ASM_SN_SN1_HUBMD_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubmd_next.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubmd_next.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubmd_next.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubmd_next.h Wed Dec 6 21:56:14 2000 @@ -0,0 +1,815 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBMD_NEXT_H +#define _ASM_SN_SN1_HUBMD_NEXT_H + +#ifdef BRINGUP +/* XXX moved over from SN/SN0/hubmd.h -- each should be checked for SN1 */ +/* In fact, most of this stuff is wrong. Some is correct, such as + * MD_PAGE_SIZE and MD_PAGE_NUM_SHFT. + */ + +#define MD_PERF_COUNTERS 6 +#define MD_PERF_SETS 6 + +#define MD_SIZE_EMPTY 0 +#define MD_SIZE_64MB 1 +#define MD_SIZE_128MB 2 +#define MD_SIZE_256MB 3 +#define MD_SIZE_512MB 4 +#define MD_SIZE_1GB 5 + +#define MD_SIZE_BYTES(size) ((size) == 0 ? 0 : 0x2000000L << (size)) +#define MD_SIZE_MBYTES(size) ((size) == 0 ? 0 : 0x20 << (size)) +#define MD_NUM_ENABLED(_x) ((_x & 0x1) + ((_x >> 1) & 0x1) + \ + ((_x >> 2) & 0x1) + ((_x >> 3) & 0x1)) + + +/* Hardware page size and shift */ + +#define MD_PAGE_SIZE 16384 /* Page size in bytes */ +#define MD_PAGE_NUM_SHFT 14 /* Address to page number shift */ + +#define MMC_IO_PROT (UINT64_CAST 1 << 45) + +/* Register offsets from LOCAL_HUB or REMOTE_HUB */ +#define MD_PERF_SEL 0x210000 /* Select perf monitor events */ + +/* MD_MIG_VALUE_THRESH bit definitions */ + +#define MD_MIG_VALUE_THRES_VALID_MASK (UINT64_CAST 0x1 << 63) +#define MD_MIG_VALUE_THRES_VALUE_MASK (UINT64_CAST 0xfffff) + +/* MD_MIG_CANDIDATE bit definitions */ + +#define MD_MIG_CANDIDATE_VALID_MASK (UINT64_CAST 0x1 << 63) +#define MD_MIG_CANDIDATE_VALID_SHFT 63 +#define MD_MIG_CANDIDATE_TYPE_MASK (UINT64_CAST 0x1 << 30) +#define MD_MIG_CANDIDATE_TYPE_SHFT 30 +#define MD_MIG_CANDIDATE_OVERRUN_MASK (UINT64_CAST 0x1 << 29) +#define MD_MIG_CANDIDATE_OVERRUN_SHFT 29 +#define MD_MIG_CANDIDATE_NODEID_MASK (UINT64_CAST 0x1ff << 20) +#define MD_MIG_CANDIDATE_NODEID_SHFT 20 +#define MD_MIG_CANDIDATE_ADDR_MASK (UINT64_CAST 0x3ffff) + + +/* XXX protection and migration are completely revised on SN1. On + SN0, the reference count and protection fields were accessed in the + same word, but on SN1 they reside at different addresses. The + users of these macros will need to be rewritten. Also, the MD page + size is 16K on SN1 but 4K on SN0. */ + +/* Premium SIMM protection entry shifts and masks. */ + +#define MD_PPROT_SHFT 0 /* Prot. field */ +#define MD_PPROT_MASK 0xf +#define MD_PPROT_REFCNT_SHFT 5 /* Reference count */ +#define MD_PPROT_REFCNT_WIDTH 0x7ffff +#define MD_PPROT_REFCNT_MASK (MD_PPROT_REFCNT_WIDTH << 5) + +#define MD_PPROT_IO_SHFT 8 /* I/O Prot field */ + +/* Standard SIMM protection entry shifts and masks. */ + +#define MD_SPROT_SHFT 0 /* Prot. field */ +#define MD_SPROT_MASK 0xf +#define MD_SPROT_IO_SHFT 8 +#define MD_SPROT_REFCNT_SHFT 5 /* Reference count */ +#define MD_SPROT_REFCNT_WIDTH 0x7ff +#define MD_SPROT_REFCNT_MASK (MD_SPROT_REFCNT_WIDTH << 5) + +/* Migration modes used in protection entries */ + +#define MD_PROT_MIGMD_IREL (UINT64_CAST 0x3 << 3) +#define MD_PROT_MIGMD_IABS (UINT64_CAST 0x2 << 3) +#define MD_PROT_MIGMD_PREL (UINT64_CAST 0x1 << 3) +#define MD_PROT_MIGMD_OFF (UINT64_CAST 0x0 << 3) + +/* + * Operations on Memory/Directory DIMM control register + */ + +#define DIRTYPE_PREMIUM 1 +#define DIRTYPE_STANDARD 0 + +/* + * Operations on page migration count difference and absolute threshold + * registers + */ + +#define MD_MIG_VALUE_THRESH_GET(region) ( \ + REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) & \ + MD_MIG_VALUE_THRES_VALUE_MASK) + +#define MD_MIG_VALUE_THRESH_SET(region, value) ( \ + REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH, \ + MD_MIG_VALUE_THRES_VALID_MASK | (value))) + +#define MD_MIG_VALUE_THRESH_ENABLE(region) ( \ + REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH, \ + REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) \ + | MD_MIG_VALUE_THRES_VALID_MASK)) + +/* + * Operations on page migration candidate register + */ + +#define MD_MIG_CANDIDATE_GET(my_region_id) ( \ + REMOTE_HUB_L((my_region_id), MD_MIG_CANDIDATE_CLR)) + +#define MD_MIG_CANDIDATE_HWPFN(value) ((value) & MD_MIG_CANDIDATE_ADDR_MASK) + +#define MD_MIG_CANDIDATE_NODEID(value) ( \ + ((value) & MD_MIG_CANDIDATE_NODEID_MASK) >> MD_MIG_CANDIDATE_NODEID_SHFT) + +#define MD_MIG_CANDIDATE_TYPE(value) ( \ + ((value) & MD_MIG_CANDIDATE_TYPE_MASK) >> MD_MIG_CANDIDATE_TYPE_SHFT) + +#define MD_MIG_CANDIDATE_VALID(value) ( \ + ((value) & MD_MIG_CANDIDATE_VALID_MASK) >> MD_MIG_CANDIDATE_VALID_SHFT) + +/* + * Macros to retrieve fields in the protection entry + */ + +/* for Premium SIMM */ +#define MD_PPROT_REFCNT_GET(value) ( \ + ((value) & MD_PPROT_REFCNT_MASK) >> MD_PPROT_REFCNT_SHFT) + +/* for Standard SIMM */ +#define MD_SPROT_REFCNT_GET(value) ( \ + ((value) & MD_SPROT_REFCNT_MASK) >> MD_SPROT_REFCNT_SHFT) + +#if _LANGUAGE_C +#ifdef LITTLE_ENDIAN + +typedef union md_perf_sel { + uint64_t perf_sel_reg; + struct { + uint64_t perf_sel : 3, + perf_en : 1, + perf_rsvd : 60; + } perf_sel_bits; +} md_perf_sel_t; + +#else + +typedef union md_perf_sel { + uint64_t perf_sel_reg; + struct { + uint64_t perf_rsvd : 60, + perf_en : 1, + perf_sel : 3; + } perf_sel_bits; +} md_perf_sel_t; + +#endif +#endif /* _LANGUAGE_C */ + +#endif /* BRINGUP */ + +/* Like SN0, SN1 supports a mostly-flat address space with 8 + CPU-visible, evenly spaced, contiguous regions, or "software + banks". On SN1, software bank n begins at addresses n * 1GB, + 0 <= n < 8. + + Physically (and very unlike SN0), each SN1 node board contains 8 + dimm sockets, arranged as 4 "DIMM banks" of 2 dimms each. DIMM + size and width (x4/x8) is assigned per dimm bank. Each DIMM bank + consists of 2 "physical banks", one on the front sides of the 2 + DIMMs and the other on the back sides. Therefore a node has a + total of 8 ( = 4 * 2) physical banks. They are collectively + referred to as "locational banks", since the locational bank number + depends on the physical location of the DIMMs on the board. + + Dimm bank 0, Phys bank 0a (locational bank 0a) + Slot D0 ---------------------------------------------- + Dimm bank 0, Phys bank 1a (locational bank 1a) + + Dimm bank 1, Phys bank 0a (locational bank 2a) + Slot D1 ---------------------------------------------- + Dimm bank 1, Phys bank 1a (locational bank 3a) + + Dimm bank 2, Phys bank 0a (locational bank 4a) + Slot D2 ---------------------------------------------- + Dimm bank 2, Phys bank 1a (locational bank 5a) + + Dimm bank 3, Phys bank 0a (locational bank 6a) + Slot D3 ---------------------------------------------- + Dimm bank 3, Phys bank 1a (locational bank 7a) + + Dimm bank 0, Phys bank 0b (locational bank 0b) + Slot D4 ---------------------------------------------- + Dimm bank 0, Phys bank 1b (locational bank 1b) + + Dimm bank 1, Phys bank 0b (locational bank 2b) + Slot D5 ---------------------------------------------- + Dimm bank 1, Phys bank 1b (locational bank 3b) + + Dimm bank 2, Phys bank 0b (locational bank 4b) + Slot D6 ---------------------------------------------- + Dimm bank 2, Phys bank 1b (locational bank 5b) + + Dimm bank 3, Phys bank 0b (locational bank 6b) + Slot D7 ---------------------------------------------- + Dimm bank 3, Phys bank 1b (locational bank 7b) + + Since bank size is assigned per DIMM bank, each pair of locational + banks must have the same size. However, they may be + enabled/disabled individually. + + The locational banks map to the software banks via the dimm0_sel + field in MD_MEMORY_CONFIG. When the field is 0 (the usual case), + the mapping is direct: eg. locational bank 1 (dimm bank 0, + physical bank 1, which is the back side of the first DIMM pair) + corresponds to software bank 1, at node offset 1GB. More + generally, locational bank = software bank XOR dimm0_sel. + + All the PROM's data structures (promlog variables, klconfig, etc.) + track memory by the locational bank number. The kernel usually + tracks memory by the software bank number. + memsupport.c:slot_psize_compute() performs the mapping. + + (Note: the terms "locational bank" and "software bank" are not + offical in any way, but I've tried to make the PROM use them + consistently -- bjj.) + */ + +#define MD_MEM_BANKS 8 +#define MD_MEM_DIMM_BANKS 4 +#define MD_BANK_SHFT 30 /* log2(1 GB) */ +#define MD_BANK_MASK (UINT64_CAST 0x7 << 30) +#define MD_BANK_SIZE (UINT64_CAST 1 << MD_BANK_SHFT) /* 1 GB */ +#define MD_BANK_OFFSET(_b) (UINT64_CAST (_b) << MD_BANK_SHFT) +#define MD_BANK_GET(addr) (((addr) & MD_BANK_MASK) >> MD_BANK_SHFT) +#define MD_BANK_TO_DIMM_BANK(_b) (( (_b) >> 1) & 0x3) +#define MD_BANK_TO_PHYS_BANK(_b) (( (_b) >> 0) & 0x1) +#define MD_DIMM_BANK_GET(addr) MD_BANK_TO_DIMM_BANK(MD_BANK_GET(addr)) +#define MD_PHYS_BANK_GET(addr) MD_BANK_TO_PHYS_BANK(MD_BANK_GET(addr)) + + +/* Split an MD pointer (or message source & suppl. fields) into node, device */ + +#define MD_PTR_NODE_SHFT 3 +#define MD_PTR_DEVICE_MASK 0x7 +#define MD_PTR_SUBNODE0_MASK 0x1 +#define MD_PTR_SUBNODE1_MASK 0x4 + + +/********************************************************************** + + Backdoor protection and page counter structures + +**********************************************************************/ + +/* Protection entries and page counters are interleaved at 4 separate + addresses, 0x10 apart. Software must read/write all four. */ + +#define BD_ITLV_COUNT 4 +#define BD_ITLV_STRIDE 0x10 + +/* Protection entries */ + +/* (these macros work for standard (_rgn < 32) or premium DIMMs) */ +#define MD_PROT_SHFT(_rgn, _io) ((((_rgn) & 0x20) >> 2 | \ + ((_rgn) & 0x01) << 2 | \ + ((_io) & 0x1) << 1) * 8) +#define MD_PROT_MASK(_rgn, _io) (0xff << MD_PROT_SHFT(_rgn, _io)) +#define MD_PROT_GET(_val, _rgn, _io) \ + (((_val) & MD_PROT_MASK(_rgn, _io)) >> MD_PROT_SHFT(_rgn, _io)) + +/* Protection field values */ + +#define MD_PROT_RW (UINT64_CAST 0xff) +#define MD_PROT_RO (UINT64_CAST 0x0f) +#define MD_PROT_NO (UINT64_CAST 0x00) + + + + +/********************************************************************** + + Directory format structures + +***********************************************************************/ + +#ifdef _LANGUAGE_C + +/* Standard Directory Entries */ + +#ifdef LITTLE_ENDIAN + +struct md_sdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */ + bdrkreg_t sdp_format : 2; + bdrkreg_t sdp_state : 3; + bdrkreg_t sdp_priority : 3; + bdrkreg_t sdp_pointer1 : 8; + bdrkreg_t sdp_ecc : 6; + bdrkreg_t sdp_locprot : 1; + bdrkreg_t sdp_reserved : 1; + bdrkreg_t sdp_crit_word_off : 3; + bdrkreg_t sdp_pointer2 : 5; + bdrkreg_t sdp_fill : 32; +}; + +#else + +struct md_sdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */ + bdrkreg_t sdp_fill : 32; + bdrkreg_t sdp_pointer2 : 5; + bdrkreg_t sdp_crit_word_off : 3; + bdrkreg_t sdp_reserved : 1; + bdrkreg_t sdp_locprot : 1; + bdrkreg_t sdp_ecc : 6; + bdrkreg_t sdp_pointer1 : 8; + bdrkreg_t sdp_priority : 3; + bdrkreg_t sdp_state : 3; + bdrkreg_t sdp_format : 2; +}; + +#endif + +#ifdef LITTLE_ENDIAN + +struct md_sdir_fine_fmt { /* shared (fine) */ + bdrkreg_t sdf_format : 2; + bdrkreg_t sdf_tag1 : 3; + bdrkreg_t sdf_tag2 : 3; + bdrkreg_t sdf_vector1 : 8; + bdrkreg_t sdf_ecc : 6; + bdrkreg_t sdf_locprot : 1; + bdrkreg_t sdf_tag2valid : 1; + bdrkreg_t sdf_vector2 : 8; + bdrkreg_t sdf_fill : 32; +}; + +#else + +struct md_sdir_fine_fmt { /* shared (fine) */ + bdrkreg_t sdf_fill : 32; + bdrkreg_t sdf_vector2 : 8; + bdrkreg_t sdf_tag2valid : 1; + bdrkreg_t sdf_locprot : 1; + bdrkreg_t sdf_ecc : 6; + bdrkreg_t sdf_vector1 : 8; + bdrkreg_t sdf_tag2 : 3; + bdrkreg_t sdf_tag1 : 3; + bdrkreg_t sdf_format : 2; +}; + +#endif + +#ifdef LITTLE_ENDIAN + +struct md_sdir_coarse_fmt { /* shared (coarse) */ + bdrkreg_t sdc_format : 2; + bdrkreg_t sdc_reserved_1 : 6; + bdrkreg_t sdc_vector_a : 8; + bdrkreg_t sdc_ecc : 6; + bdrkreg_t sdc_locprot : 1; + bdrkreg_t sdc_reserved : 1; + bdrkreg_t sdc_vector_b : 8; + bdrkreg_t sdc_fill : 32; +}; + +#else + +struct md_sdir_coarse_fmt { /* shared (coarse) */ + bdrkreg_t sdc_fill : 32; + bdrkreg_t sdc_vector_b : 8; + bdrkreg_t sdc_reserved : 1; + bdrkreg_t sdc_locprot : 1; + bdrkreg_t sdc_ecc : 6; + bdrkreg_t sdc_vector_a : 8; + bdrkreg_t sdc_reserved_1 : 6; + bdrkreg_t sdc_format : 2; +}; + +#endif + +typedef union md_sdir { + /* The 32 bits of standard directory, in bits 31:0 */ + uint64_t sd_val; + struct md_sdir_pointer_fmt sdp_fmt; + struct md_sdir_fine_fmt sdf_fmt; + struct md_sdir_coarse_fmt sdc_fmt; +} md_sdir_t; + + +/* Premium Directory Entries */ + +#ifdef LITTLE_ENDIAN + +struct md_pdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */ + bdrkreg_t pdp_format : 2; + bdrkreg_t pdp_state : 3; + bdrkreg_t pdp_priority : 3; + bdrkreg_t pdp_pointer1_a : 8; + bdrkreg_t pdp_reserved_4 : 6; + bdrkreg_t pdp_pointer1_b : 3; + bdrkreg_t pdp_reserved_3 : 7; + bdrkreg_t pdp_ecc_a : 6; + bdrkreg_t pdp_locprot : 1; + bdrkreg_t pdp_reserved_2 : 1; + bdrkreg_t pdp_crit_word_off : 3; + bdrkreg_t pdp_pointer2_a : 5; + bdrkreg_t pdp_ecc_b : 1; + bdrkreg_t pdp_reserved_1 : 5; + bdrkreg_t pdp_pointer2_b : 3; + bdrkreg_t pdp_reserved : 7; +}; + +#else + +struct md_pdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */ + bdrkreg_t pdp_reserved : 7; + bdrkreg_t pdp_pointer2_b : 3; + bdrkreg_t pdp_reserved_1 : 5; + bdrkreg_t pdp_ecc_b : 1; + bdrkreg_t pdp_pointer2_a : 5; + bdrkreg_t pdp_crit_word_off : 3; + bdrkreg_t pdp_reserved_2 : 1; + bdrkreg_t pdp_locprot : 1; + bdrkreg_t pdp_ecc_a : 6; + bdrkreg_t pdp_reserved_3 : 7; + bdrkreg_t pdp_pointer1_b : 3; + bdrkreg_t pdp_reserved_4 : 6; + bdrkreg_t pdp_pointer1_a : 8; + bdrkreg_t pdp_priority : 3; + bdrkreg_t pdp_state : 3; + bdrkreg_t pdp_format : 2; +}; + +#endif + +#ifdef LITTLE_ENDIAN + +struct md_pdir_fine_fmt { /* shared (fine) */ + bdrkreg_t pdf_format : 2; + bdrkreg_t pdf_tag1_a : 3; + bdrkreg_t pdf_tag2_a : 3; + bdrkreg_t pdf_vector1_a : 8; + bdrkreg_t pdf_reserved_1 : 6; + bdrkreg_t pdf_tag1_b : 2; + bdrkreg_t pdf_vector1_b : 8; + bdrkreg_t pdf_ecc_a : 6; + bdrkreg_t pdf_locprot : 1; + bdrkreg_t pdf_tag2valid : 1; + bdrkreg_t pdf_vector2_a : 8; + bdrkreg_t pdf_ecc_b : 1; + bdrkreg_t pdf_reserved : 5; + bdrkreg_t pdf_tag2_b : 2; + bdrkreg_t pdf_vector2_b : 8; +}; + +#else + +struct md_pdir_fine_fmt { /* shared (fine) */ + bdrkreg_t pdf_vector2_b : 8; + bdrkreg_t pdf_tag2_b : 2; + bdrkreg_t pdf_reserved : 5; + bdrkreg_t pdf_ecc_b : 1; + bdrkreg_t pdf_vector2_a : 8; + bdrkreg_t pdf_tag2valid : 1; + bdrkreg_t pdf_locprot : 1; + bdrkreg_t pdf_ecc_a : 6; + bdrkreg_t pdf_vector1_b : 8; + bdrkreg_t pdf_tag1_b : 2; + bdrkreg_t pdf_reserved_1 : 6; + bdrkreg_t pdf_vector1_a : 8; + bdrkreg_t pdf_tag2_a : 3; + bdrkreg_t pdf_tag1_a : 3; + bdrkreg_t pdf_format : 2; +}; + +#endif + +#ifdef LITTLE_ENDIAN + +struct md_pdir_sparse_fmt { /* shared (sparse) */ + bdrkreg_t pds_format : 2; + bdrkreg_t pds_column_a : 6; + bdrkreg_t pds_row_a : 8; + bdrkreg_t pds_column_b : 16; + bdrkreg_t pds_ecc_a : 6; + bdrkreg_t pds_locprot : 1; + bdrkreg_t pds_reserved_1 : 1; + bdrkreg_t pds_row_b : 8; + bdrkreg_t pds_ecc_b : 1; + bdrkreg_t pds_column_c : 10; + bdrkreg_t pds_reserved : 5; +}; + +#else + +struct md_pdir_sparse_fmt { /* shared (sparse) */ + bdrkreg_t pds_reserved : 5; + bdrkreg_t pds_column_c : 10; + bdrkreg_t pds_ecc_b : 1; + bdrkreg_t pds_row_b : 8; + bdrkreg_t pds_reserved_1 : 1; + bdrkreg_t pds_locprot : 1; + bdrkreg_t pds_ecc_a : 6; + bdrkreg_t pds_column_b : 16; + bdrkreg_t pds_row_a : 8; + bdrkreg_t pds_column_a : 6; + bdrkreg_t pds_format : 2; +}; + +#endif + +typedef union md_pdir { + /* The 64 bits of premium directory */ + uint64_t pd_val; + struct md_pdir_pointer_fmt pdp_fmt; + struct md_pdir_fine_fmt pdf_fmt; + struct md_pdir_sparse_fmt pds_fmt; +} md_pdir_t; + +#endif /* _LANGUAGE_C */ + + +/********************************************************************** + + The defines for backdoor directory and backdoor ECC. + +***********************************************************************/ + +/* Directory formats, for each format's "format" field */ + +#define MD_FORMAT_UNOWNED (UINT64_CAST 0x0) /* 00 */ +#define MD_FORMAT_POINTER (UINT64_CAST 0x1) /* 01 */ +#define MD_FORMAT_SHFINE (UINT64_CAST 0x2) /* 10 */ +#define MD_FORMAT_SHCOARSE (UINT64_CAST 0x3) /* 11 */ + /* Shared coarse (standard) and shared sparse (premium) both use fmt 0x3 */ + + +/* + * Cacheline state values. + * + * These are really *software* notions of the "state" of a cacheline; but the + * actual values have been carefully chosen to align with some hardware values! + * The MD_FMT_ST_TO_STATE macro is used to convert from hardware format/state + * pairs in the directory entried into one of these cacheline state values. + */ + +#define MD_DIR_EXCLUSIVE (UINT64_CAST 0x0) /* ptr format, hw-defined */ +#define MD_DIR_UNOWNED (UINT64_CAST 0x1) /* format=0 */ +#define MD_DIR_SHARED (UINT64_CAST 0x2) /* format=2,3 */ +#define MD_DIR_BUSY_SHARED (UINT64_CAST 0x4) /* ptr format, hw-defined */ +#define MD_DIR_BUSY_EXCL (UINT64_CAST 0x5) /* ptr format, hw-defined */ +#define MD_DIR_WAIT (UINT64_CAST 0x6) /* ptr format, hw-defined */ +#define MD_DIR_POISONED (UINT64_CAST 0x7) /* ptr format, hw-defined */ + +#ifdef _LANGUAGE_C + +/* Convert format and state fields into a single "cacheline state" value, defined above */ + +#define MD_FMT_ST_TO_STATE(fmt, state) \ + ((fmt) == MD_FORMAT_POINTER ? (state) : \ + (fmt) == MD_FORMAT_UNOWNED ? MD_DIR_UNOWNED : \ + MD_DIR_SHARED) +#define MD_DIR_STATE(x) MD_FMT_ST_TO_STATE(MD_DIR_FORMAT(x), MD_DIR_STVAL(x)) + +#endif /* _LANGUAGE_C */ + + + +/* Directory field shifts and masks */ + +/* Standard */ + +#define MD_SDIR_FORMAT_SHFT 0 /* All formats */ +#define MD_SDIR_FORMAT_MASK (0x3 << 0) +#define MD_SDIR_STATE_SHFT 2 /* Pointer fmt. only */ +#define MD_SDIR_STATE_MASK (0x7 << 2) + +/* Premium */ + +#define MD_PDIR_FORMAT_SHFT 0 /* All formats */ +#define MD_PDIR_FORMAT_MASK (0x3 << 0) +#define MD_PDIR_STATE_SHFT 2 /* Pointer fmt. only */ +#define MD_PDIR_STATE_MASK (0x7 << 2) + +/* Generic */ + +#define MD_FORMAT_SHFT 0 /* All formats */ +#define MD_FORMAT_MASK (0x3 << 0) +#define MD_STATE_SHFT 2 /* Pointer fmt. only */ +#define MD_STATE_MASK (0x7 << 2) + + +/* Special shifts to reconstruct fields from the _a and _b parts */ + +/* Standard: only shared coarse has split fields */ + +#define MD_SDC_VECTORB_SHFT 8 /* eg: sdc_vector_a is 8 bits */ + +/* Premium: pointer, shared fine, shared sparse */ + +#define MD_PDP_POINTER1A_MASK 0xFF +#define MD_PDP_POINTER1B_SHFT 8 +#define MD_PDP_POINTER2B_SHFT 5 +#define MD_PDP_ECCB_SHFT 6 + +#define MD_PDF_VECTOR1B_SHFT 8 +#define MD_PDF_VECTOR2B_SHFT 8 +#define MD_PDF_TAG1B_SHFT 3 +#define MD_PDF_TAG2B_SHFT 3 +#define MD_PDF_ECC_SHFT 6 + +#define MD_PDS_ROWB_SHFT 8 +#define MD_PDS_COLUMNB_SHFT 6 +#define MD_PDS_COLUMNC_SHFT (MD_PDS_COLUMNB_SHFT + 16) +#define MD_PDS_ECC_SHFT 6 + + + +/* + * Directory/protection/counter initialization values, premium and standard + */ + +#define MD_PDIR_INIT 0 +#define MD_PDIR_INIT_CNT 0 +#define MD_PDIR_INIT_PROT 0 + +#define MD_SDIR_INIT 0 +#define MD_SDIR_INIT_CNT 0 +#define MD_SDIR_INIT_PROT 0 + +#define MD_PDIR_MASK 0xffffffffffffffff +#define MD_SDIR_MASK 0xffffffff + +/* When premium mode is on for probing but standard directory memory + is installed, the vaild directory bits depend on the phys. bank */ +#define MD_PDIR_PROBE_MASK(pb) 0xffffffffffffffff +#define MD_SDIR_PROBE_MASK(pb) (0xffff0000ffff << ((pb) ? 16 : 0)) + + +/* + * Misc. field extractions and conversions + */ + +/* Convert an MD pointer (or message source, supplemental fields) */ + +#define MD_PTR_NODE(x) ((x) >> MD_PTR_NODE_SHFT) +#define MD_PTR_DEVICE(x) ((x) & MD_PTR_DEVICE_MASK) +#define MD_PTR_SLICE(x) (((x) & MD_PTR_SUBNODE0_MASK) | \ + ((x) & MD_PTR_SUBNODE1_MASK) >> 1) +#define MD_PTR_OWNER_CPU(x) (! ((x) & 2)) +#define MD_PTR_OWNER_IO(x) ((x) & 2) + +/* Extract format and raw state from a directory entry */ + +#define MD_DIR_FORMAT(x) ((x) >> MD_SDIR_FORMAT_SHFT & \ + MD_SDIR_FORMAT_MASK >> MD_SDIR_FORMAT_SHFT) +#define MD_DIR_STVAL(x) ((x) >> MD_SDIR_STATE_SHFT & \ + MD_SDIR_STATE_MASK >> MD_SDIR_STATE_SHFT) + +/* Mask & Shift to get HSPEC_ADDR from MD DIR_ERROR register */ +#define ERROR_ADDR_SHFT 3 +#define ERROR_HSPEC_SHFT 3 +#define DIR_ERR_HSPEC_MASK 0x1fffffff8 + +/* + * DIR_ERR* and MEM_ERR* defines are used to avoid ugly + * #ifdefs for SN0 and SN1 in memerror.c code. See SN0/hubmd.h + * for corresponding SN0 definitions. + */ +#define md_dir_error_t md_dir_error_u_t +#define md_mem_error_t md_mem_error_u_t +#define derr_reg md_dir_error_regval +#define merr_reg md_mem_error_regval + +#define DIR_ERR_UCE_VALID dir_err.md_dir_error_fld_s.de_uce_valid +#define DIR_ERR_AE_VALID dir_err.md_dir_error_fld_s.de_ae_valid +#define DIR_ERR_BAD_SYN dir_err.md_dir_error_fld_s.de_bad_syn +#define DIR_ERR_CE_OVERRUN dir_err.md_dir_error_fld_s.de_ce_overrun +#define MEM_ERR_ADDRESS mem_err.md_mem_error_fld_s.me_address + /* BRINGUP Can the overrun bit be set without the valid bit? */ +#define MEM_ERR_CE_OVERRUN (mem_err.md_mem_error_fld_s.me_read_ce >> 1) +#define MEM_ERR_BAD_SYN mem_err.md_mem_error_fld_s.me_bad_syn +#define MEM_ERR_UCE_VALID (mem_err.md_mem_error_fld_s.me_read_uce & 1) + + + +/********************************************************************* + + We have the shift and masks of various fields defined below. + + *********************************************************************/ + +/* MD_REFRESH_CONTROL fields */ + +#define MRC_ENABLE_SHFT 63 +#define MRC_ENABLE_MASK (UINT64_CAST 1 << 63) +#define MRC_ENABLE (UINT64_CAST 1 << 63) +#define MRC_COUNTER_SHFT 12 +#define MRC_COUNTER_MASK (UINT64_CAST 0xfff << 12) +#define MRC_CNT_THRESH_MASK 0xfff +#define MRC_RESET_DEFAULTS (UINT64_CAST 0x800) + +/* MD_DIR_CONFIG fields */ + +#define MDC_DIR_PREMIUM (UINT64_CAST 1 << 0) +#define MDC_IGNORE_ECC_SHFT 1 +#define MDC_IGNORE_ECC_MASK (UINT64_CAST 1 << 1) + +/* MD_MEMORY_CONFIG fields */ + +#define MMC_RP_CONFIG_SHFT 61 +#define MMC_RP_CONFIG_MASK (UINT64_CAST 1 << 61) +#define MMC_RCD_CONFIG_SHFT 60 +#define MMC_RCD_CONFIG_MASK (UINT64_CAST 1 << 60) +#define MMC_MB_NEG_EDGE_SHFT 56 +#define MMC_MB_NEG_EDGE_MASK (UINT64_CAST 0x7 << 56) +#define MMC_SAMPLE_TIME_SHFT 52 +#define MMC_SAMPLE_TIME_MASK (UINT64_CAST 0x3 << 52) +#define MMC_DELAY_MUX_SEL_SHFT 50 +#define MMC_DELAY_MUX_SEL_MASK (UINT64_CAST 0x3 << 50) +#define MMC_PHASE_DELAY_SHFT 49 +#define MMC_PHASE_DELAY_MASK (UINT64_CAST 1 << 49) +#define MMC_DB_NEG_EDGE_SHFT 48 +#define MMC_DB_NEG_EDGE_MASK (UINT64_CAST 1 << 48) +#define MMC_CPU_PROT_IGNORE_SHFT 47 +#define MMC_CPU_PROT_IGNORE_MASK (UINT64_CAST 1 << 47) +#define MMC_IO_PROT_IGNORE_SHFT 46 +#define MMC_IO_PROT_IGNORE_MASK (UINT64_CAST 1 << 46) +#define MMC_IO_PROT_EN_SHFT 45 +#define MMC_IO_PROT_EN_MASK (UINT64_CAST 1 << 45) +#define MMC_CC_ENABLE_SHFT 44 +#define MMC_CC_ENABLE_MASK (UINT64_CAST 1 << 44) +#define MMC_DIMM0_SEL_SHFT 32 +#define MMC_DIMM0_SEL_MASK (UINT64_CAST 0x3 << 32) +#define MMC_DIMM_SIZE_SHFT(_dimm) ((_dimm << 3) + 4) +#define MMC_DIMM_SIZE_MASK(_dimm) (UINT64_CAST 0xf << MMC_DIMM_SIZE_SHFT(_dimm)) +#define MMC_DIMM_WIDTH_SHFT(_dimm) ((_dimm << 3) + 3) +#define MMC_DIMM_WIDTH_MASK(_dimm) (UINT64_CAST 0x1 << MMC_DIMM_WIDTH_SHFT(_dimm)) +#define MMC_DIMM_BANKS_SHFT(_dimm) (_dimm << 3) +#define MMC_DIMM_BANKS_MASK(_dimm) (UINT64_CAST 0x3 << MMC_DIMM_BANKS_SHFT(_dimm)) +#define MMC_BANK_ALL_MASK 0xffffffffLL +/* Default values for write-only bits in MD_MEMORY_CONFIG */ +#define MMC_DEFAULT_BITS (UINT64_CAST 0x7 << MMC_MB_NEG_EDGE_SHFT) + +/* MD_MB_ECC_CONFIG fields */ + +#define MEC_IGNORE_ECC (UINT64_CAST 0x1 << 0) + +/* MD_BIST_DATA fields */ + +#define MBD_BIST_WRITE (UINT64_CAST 1 << 7) +#define MBD_BIST_CYCLE (UINT64_CAST 1 << 6) +#define MBD_BIST_BYTE (UINT64_CAST 1 << 5) +#define MBD_BIST_NIBBLE (UINT64_CAST 1 << 4) +#define MBD_BIST_DATA_MASK 0xf + +/* MD_BIST_CTL fields */ + +#define MBC_DIMM_SHFT 5 +#define MBC_DIMM_MASK (UINT64_CAST 0x3 << 5) +#define MBC_BANK_SHFT 4 +#define MBC_BANK_MASK (UINT64_CAST 0x1 << 4) +#define MBC_BIST_RESET (UINT64_CAST 0x1 << 2) +#define MBC_BIST_STOP (UINT64_CAST 0x1 << 1) +#define MBC_BIST_START (UINT64_CAST 0x1 << 0) + +#define MBC_GO(dimm, bank) \ + (((dimm) << MBC_DIMM_SHFT) & MBC_DIMM_MASK | \ + ((bank) << MBC_BANK_SHFT) & MBC_BANK_MASK | \ + MBC_BIST_START) + +/* MD_BIST_STATUS fields */ + +#define MBS_BIST_DONE (UINT64_CAST 0X1 << 1) +#define MBS_BIST_PASSED (UINT64_CAST 0X1 << 0) + +/* MD_JUNK_BUS_TIMING fields */ + +#define MJT_SYNERGY_ENABLE_SHFT 40 +#define MJT_SYNERGY_ENABLE_MASK (UINT64_CAST 0Xff << MJT_SYNERGY_ENABLE_SHFT) +#define MJT_SYNERGY_SETUP_SHFT 32 +#define MJT_SYNERGY_SETUP_MASK (UINT64_CAST 0Xff << MJT_SYNERGY_SETUP_SHFT) +#define MJT_UART_ENABLE_SHFT 24 +#define MJT_UART_ENABLE_MASK (UINT64_CAST 0Xff << MJT_UART_ENABLE_SHFT) +#define MJT_UART_SETUP_SHFT 16 +#define MJT_UART_SETUP_MASK (UINT64_CAST 0Xff << MJT_UART_SETUP_SHFT) +#define MJT_FPROM_ENABLE_SHFT 8 +#define MJT_FPROM_ENABLE_MASK (UINT64_CAST 0Xff << MJT_FPROM_ENABLE_SHFT) +#define MJT_FPROM_SETUP_SHFT 0 +#define MJT_FPROM_SETUP_MASK (UINT64_CAST 0Xff << MJT_FPROM_SETUP_SHFT) + +#define MEM_ERROR_VALID_CE 1 + + +/* MD_FANDOP_CAC_STAT0, MD_FANDOP_CAC_STAT1 addr field shift */ + +#define MFC_ADDR_SHFT 6 + +#endif /* _ASM_SN_SN1_HUBMD_NEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubni.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubni.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubni.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubni.h Wed Dec 6 21:56:14 2000 @@ -0,0 +1,1782 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBNI_H +#define _ASM_SN_SN1_HUBNI_H + + +/************************************************************************ + * * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! * + * * + * This file is created by an automated script. Any (minimal) changes * + * made manually to this file should be made with care. * + * * + * MAKE ALL ADDITIONS TO THE END OF THIS FILE * + * * + ************************************************************************/ + +#define NI_PORT_STATUS 0x00680000 /* LLP Status */ + + + +#define NI_PORT_RESET 0x00680008 /* + * Reset the Network + * Interface + */ + + + +#define NI_RESET_ENABLE 0x00680010 /* Warm Reset Enable */ + + + +#define NI_DIAG_PARMS 0x00680018 /* + * Diagnostic + * Parameters + */ + + + +#define NI_CHANNEL_CONTROL 0x00680020 /* + * Virtual channel + * control + */ + + + +#define NI_CHANNEL_TEST 0x00680028 /* LLP Test Control. */ + + + +#define NI_PORT_PARMS 0x00680030 /* LLP Parameters */ + + + +#define NI_CHANNEL_AGE 0x00680038 /* + * Network age + * injection control + */ + + + +#define NI_PORT_ERRORS 0x00680100 /* Errors */ + + + +#define NI_PORT_HEADER_A 0x00680108 /* + * Error Header first + * half + */ + + + +#define NI_PORT_HEADER_B 0x00680110 /* + * Error Header second + * half + */ + + + +#define NI_PORT_SIDEBAND 0x00680118 /* Error Sideband */ + + + +#define NI_PORT_ERROR_CLEAR 0x00680120 /* + * Clear the Error + * bits + */ + + + +#define NI_LOCAL_TABLE_0 0x00681000 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_1 0x00681008 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_2 0x00681010 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_3 0x00681018 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_4 0x00681020 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_5 0x00681028 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_6 0x00681030 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_7 0x00681038 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_8 0x00681040 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_9 0x00681048 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_10 0x00681050 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_11 0x00681058 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_12 0x00681060 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_13 0x00681068 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_14 0x00681070 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_15 0x00681078 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_16 0x00681080 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_17 0x00681088 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_18 0x00681090 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_19 0x00681098 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_20 0x006810A0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_21 0x006810A8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_22 0x006810B0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_23 0x006810B8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_24 0x006810C0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_25 0x006810C8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_26 0x006810D0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_27 0x006810D8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_28 0x006810E0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_29 0x006810E8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_30 0x006810F0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_31 0x006810F8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_32 0x00681100 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_33 0x00681108 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_34 0x00681110 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_35 0x00681118 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_36 0x00681120 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_37 0x00681128 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_38 0x00681130 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_39 0x00681138 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_40 0x00681140 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_41 0x00681148 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_42 0x00681150 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_43 0x00681158 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_44 0x00681160 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_45 0x00681168 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_46 0x00681170 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_47 0x00681178 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_48 0x00681180 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_49 0x00681188 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_50 0x00681190 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_51 0x00681198 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_52 0x006811A0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_53 0x006811A8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_54 0x006811B0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_55 0x006811B8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_56 0x006811C0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_57 0x006811C8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_58 0x006811D0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_59 0x006811D8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_60 0x006811E0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_61 0x006811E8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_62 0x006811F0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_63 0x006811F8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_64 0x00681200 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_65 0x00681208 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_66 0x00681210 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_67 0x00681218 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_68 0x00681220 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_69 0x00681228 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_70 0x00681230 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_71 0x00681238 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_72 0x00681240 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_73 0x00681248 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_74 0x00681250 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_75 0x00681258 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_76 0x00681260 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_77 0x00681268 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_78 0x00681270 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_79 0x00681278 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_80 0x00681280 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_81 0x00681288 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_82 0x00681290 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_83 0x00681298 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_84 0x006812A0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_85 0x006812A8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_86 0x006812B0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_87 0x006812B8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_88 0x006812C0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_89 0x006812C8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_90 0x006812D0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_91 0x006812D8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_92 0x006812E0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_93 0x006812E8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_94 0x006812F0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_95 0x006812F8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_96 0x00681300 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_97 0x00681308 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_98 0x00681310 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_99 0x00681318 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_100 0x00681320 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_101 0x00681328 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_102 0x00681330 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_103 0x00681338 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_104 0x00681340 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_105 0x00681348 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_106 0x00681350 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_107 0x00681358 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_108 0x00681360 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_109 0x00681368 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_110 0x00681370 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_111 0x00681378 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_112 0x00681380 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_113 0x00681388 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_114 0x00681390 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_115 0x00681398 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_116 0x006813A0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_117 0x006813A8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_118 0x006813B0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_119 0x006813B8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_120 0x006813C0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_121 0x006813C8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_122 0x006813D0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_123 0x006813D8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_124 0x006813E0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_125 0x006813E8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_126 0x006813F0 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_LOCAL_TABLE_127 0x006813F8 /* + * Base of Local + * Mapping Table 0-127 + */ + + + +#define NI_GLOBAL_TABLE 0x00682000 /* + * Base of Global + * Mapping Table + */ + + + + + +#ifdef _LANGUAGE_C + +/************************************************************************ + * * + * This register describes the LLP status. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_status_u { + bdrkreg_t ni_port_status_regval; + struct { + bdrkreg_t ps_port_status : 2; + bdrkreg_t ps_remote_power : 1; + bdrkreg_t ps_rsvd : 61; + } ni_port_status_fld_s; +} ni_port_status_u_t; + +#else + +typedef union ni_port_status_u { + bdrkreg_t ni_port_status_regval; + struct { + bdrkreg_t ps_rsvd : 61; + bdrkreg_t ps_remote_power : 1; + bdrkreg_t ps_port_status : 2; + } ni_port_status_fld_s; +} ni_port_status_u_t; + +#endif + + + + +/************************************************************************ + * * + * Writing this register issues a reset to the network interface. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_reset_u { + bdrkreg_t ni_port_reset_regval; + struct { + bdrkreg_t pr_link_reset_out : 1; + bdrkreg_t pr_port_reset : 1; + bdrkreg_t pr_local_reset : 1; + bdrkreg_t pr_rsvd : 61; + } ni_port_reset_fld_s; +} ni_port_reset_u_t; + +#else + +typedef union ni_port_reset_u { + bdrkreg_t ni_port_reset_regval; + struct { + bdrkreg_t pr_rsvd : 61; + bdrkreg_t pr_local_reset : 1; + bdrkreg_t pr_port_reset : 1; + bdrkreg_t pr_link_reset_out : 1; + } ni_port_reset_fld_s; +} ni_port_reset_u_t; + +#endif + + + +/************************************************************************ + * * + * This register contains the warm reset enable bit. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_reset_enable_u { + bdrkreg_t ni_reset_enable_regval; + struct { + bdrkreg_t re_reset_ok : 1; + bdrkreg_t re_rsvd : 63; + } ni_reset_enable_fld_s; +} ni_reset_enable_u_t; + +#else + +typedef union ni_reset_enable_u { + bdrkreg_t ni_reset_enable_regval; + struct { + bdrkreg_t re_rsvd : 63; + bdrkreg_t re_reset_ok : 1; + } ni_reset_enable_fld_s; +} ni_reset_enable_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains parameters for diagnostics. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_diag_parms_u { + bdrkreg_t ni_diag_parms_regval; + struct { + bdrkreg_t dp_send_data_error : 1; + bdrkreg_t dp_port_disable : 1; + bdrkreg_t dp_send_err_off : 1; + bdrkreg_t dp_rsvd : 61; + } ni_diag_parms_fld_s; +} ni_diag_parms_u_t; + +#else + +typedef union ni_diag_parms_u { + bdrkreg_t ni_diag_parms_regval; + struct { + bdrkreg_t dp_rsvd : 61; + bdrkreg_t dp_send_err_off : 1; + bdrkreg_t dp_port_disable : 1; + bdrkreg_t dp_send_data_error : 1; + } ni_diag_parms_fld_s; +} ni_diag_parms_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the virtual channel selection control for * + * outgoing messages from the Bedrock. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_channel_control_u { + bdrkreg_t ni_channel_control_regval; + struct { + bdrkreg_t cc_vch_one_request : 1; + bdrkreg_t cc_vch_two_request : 1; + bdrkreg_t cc_vch_nine_request : 1; + bdrkreg_t cc_vch_vector_request : 1; + bdrkreg_t cc_vch_one_reply : 1; + bdrkreg_t cc_vch_two_reply : 1; + bdrkreg_t cc_vch_nine_reply : 1; + bdrkreg_t cc_vch_vector_reply : 1; + bdrkreg_t cc_send_vch_sel : 1; + bdrkreg_t cc_rsvd : 55; + } ni_channel_control_fld_s; +} ni_channel_control_u_t; + +#else + +typedef union ni_channel_control_u { + bdrkreg_t ni_channel_control_regval; + struct { + bdrkreg_t cc_rsvd : 55; + bdrkreg_t cc_send_vch_sel : 1; + bdrkreg_t cc_vch_vector_reply : 1; + bdrkreg_t cc_vch_nine_reply : 1; + bdrkreg_t cc_vch_two_reply : 1; + bdrkreg_t cc_vch_one_reply : 1; + bdrkreg_t cc_vch_vector_request : 1; + bdrkreg_t cc_vch_nine_request : 1; + bdrkreg_t cc_vch_two_request : 1; + bdrkreg_t cc_vch_one_request : 1; + } ni_channel_control_fld_s; +} ni_channel_control_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register allows access to the LLP test logic. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_channel_test_u { + bdrkreg_t ni_channel_test_regval; + struct { + bdrkreg_t ct_testseed : 20; + bdrkreg_t ct_testmask : 8; + bdrkreg_t ct_testdata : 20; + bdrkreg_t ct_testvalid : 1; + bdrkreg_t ct_testcberr : 1; + bdrkreg_t ct_testflit : 3; + bdrkreg_t ct_testclear : 1; + bdrkreg_t ct_testerrcapture : 1; + bdrkreg_t ct_rsvd : 9; + } ni_channel_test_fld_s; +} ni_channel_test_u_t; + +#else + +typedef union ni_channel_test_u { + bdrkreg_t ni_channel_test_regval; + struct { + bdrkreg_t ct_rsvd : 9; + bdrkreg_t ct_testerrcapture : 1; + bdrkreg_t ct_testclear : 1; + bdrkreg_t ct_testflit : 3; + bdrkreg_t ct_testcberr : 1; + bdrkreg_t ct_testvalid : 1; + bdrkreg_t ct_testdata : 20; + bdrkreg_t ct_testmask : 8; + bdrkreg_t ct_testseed : 20; + } ni_channel_test_fld_s; +} ni_channel_test_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains LLP port parameters and enables for the * + * capture of header data. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_parms_u { + bdrkreg_t ni_port_parms_regval; + struct { + bdrkreg_t pp_max_burst : 10; + bdrkreg_t pp_null_timeout : 6; + bdrkreg_t pp_max_retry : 10; + bdrkreg_t pp_d_avail_sel : 2; + bdrkreg_t pp_rsvd_1 : 1; + bdrkreg_t pp_first_err_enable : 1; + bdrkreg_t pp_squash_err_enable : 1; + bdrkreg_t pp_vch_err_enable : 4; + bdrkreg_t pp_rsvd : 29; + } ni_port_parms_fld_s; +} ni_port_parms_u_t; + +#else + +typedef union ni_port_parms_u { + bdrkreg_t ni_port_parms_regval; + struct { + bdrkreg_t pp_rsvd : 29; + bdrkreg_t pp_vch_err_enable : 4; + bdrkreg_t pp_squash_err_enable : 1; + bdrkreg_t pp_first_err_enable : 1; + bdrkreg_t pp_rsvd_1 : 1; + bdrkreg_t pp_d_avail_sel : 2; + bdrkreg_t pp_max_retry : 10; + bdrkreg_t pp_null_timeout : 6; + bdrkreg_t pp_max_burst : 10; + } ni_port_parms_fld_s; +} ni_port_parms_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains the age at which request and reply packets * + * are injected into the network. This feature allows replies to be * + * given a higher fixed priority than requests, which can be * + * important in some network saturation situations. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_channel_age_u { + bdrkreg_t ni_channel_age_regval; + struct { + bdrkreg_t ca_request_inject_age : 8; + bdrkreg_t ca_reply_inject_age : 8; + bdrkreg_t ca_rsvd : 48; + } ni_channel_age_fld_s; +} ni_channel_age_u_t; + +#else + +typedef union ni_channel_age_u { + bdrkreg_t ni_channel_age_regval; + struct { + bdrkreg_t ca_rsvd : 48; + bdrkreg_t ca_reply_inject_age : 8; + bdrkreg_t ca_request_inject_age : 8; + } ni_channel_age_fld_s; +} ni_channel_age_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains latched LLP port and problematic message * + * errors. The contents are the same information as the * + * NI_PORT_ERROR_CLEAR register, but, in this register read accesses * + * are non-destructive. Bits [52:24] assert the NI interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_errors_u { + bdrkreg_t ni_port_errors_regval; + struct { + bdrkreg_t pe_sn_error_count : 8; + bdrkreg_t pe_cb_error_count : 8; + bdrkreg_t pe_retry_count : 8; + bdrkreg_t pe_tail_timeout : 4; + bdrkreg_t pe_fifo_overflow : 4; + bdrkreg_t pe_external_short : 4; + bdrkreg_t pe_external_long : 4; + bdrkreg_t pe_external_bad_header : 4; + bdrkreg_t pe_internal_short : 4; + bdrkreg_t pe_internal_long : 4; + bdrkreg_t pe_link_reset_in : 1; + bdrkreg_t pe_rsvd : 11; + } ni_port_errors_fld_s; +} ni_port_errors_u_t; + +#else + +typedef union ni_port_errors_u { + bdrkreg_t ni_port_errors_regval; + struct { + bdrkreg_t pe_rsvd : 11; + bdrkreg_t pe_link_reset_in : 1; + bdrkreg_t pe_internal_long : 4; + bdrkreg_t pe_internal_short : 4; + bdrkreg_t pe_external_bad_header : 4; + bdrkreg_t pe_external_long : 4; + bdrkreg_t pe_external_short : 4; + bdrkreg_t pe_fifo_overflow : 4; + bdrkreg_t pe_tail_timeout : 4; + bdrkreg_t pe_retry_count : 8; + bdrkreg_t pe_cb_error_count : 8; + bdrkreg_t pe_sn_error_count : 8; + } ni_port_errors_fld_s; +} ni_port_errors_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register provides the sideband data associated with the * + * NI_PORT_HEADER registers and also additional data for error * + * processing. This register is not cleared on reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_sideband_u { + bdrkreg_t ni_port_sideband_regval; + struct { + bdrkreg_t ps_sideband : 8; + bdrkreg_t ps_bad_dest : 1; + bdrkreg_t ps_bad_prexsel : 1; + bdrkreg_t ps_rcv_error : 1; + bdrkreg_t ps_bad_message : 1; + bdrkreg_t ps_squash : 1; + bdrkreg_t ps_sn_status : 1; + bdrkreg_t ps_cb_status : 1; + bdrkreg_t ps_send_error : 1; + bdrkreg_t ps_vch_active : 4; + bdrkreg_t ps_rsvd : 44; + } ni_port_sideband_fld_s; +} ni_port_sideband_u_t; + +#else + +typedef union ni_port_sideband_u { + bdrkreg_t ni_port_sideband_regval; + struct { + bdrkreg_t ps_rsvd : 44; + bdrkreg_t ps_vch_active : 4; + bdrkreg_t ps_send_error : 1; + bdrkreg_t ps_cb_status : 1; + bdrkreg_t ps_sn_status : 1; + bdrkreg_t ps_squash : 1; + bdrkreg_t ps_bad_message : 1; + bdrkreg_t ps_rcv_error : 1; + bdrkreg_t ps_bad_prexsel : 1; + bdrkreg_t ps_bad_dest : 1; + bdrkreg_t ps_sideband : 8; + } ni_port_sideband_fld_s; +} ni_port_sideband_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register contains latched LLP port and problematic message * + * errors. The contents are the same information as the * + * NI_PORT_ERROR_CLEAR register, but, in this register read accesses * + * are non-destructive. Bits [52:24] assert the NI interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_error_clear_u { + bdrkreg_t ni_port_error_clear_regval; + struct { + bdrkreg_t pec_sn_error_count : 8; + bdrkreg_t pec_cb_error_count : 8; + bdrkreg_t pec_retry_count : 8; + bdrkreg_t pec_tail_timeout : 4; + bdrkreg_t pec_fifo_overflow : 4; + bdrkreg_t pec_external_short : 4; + bdrkreg_t pec_external_long : 4; + bdrkreg_t pec_external_bad_header : 4; + bdrkreg_t pec_internal_short : 4; + bdrkreg_t pec_internal_long : 4; + bdrkreg_t pec_link_reset_in : 1; + bdrkreg_t pec_rsvd : 11; + } ni_port_error_clear_fld_s; +} ni_port_error_clear_u_t; + +#else + +typedef union ni_port_error_clear_u { + bdrkreg_t ni_port_error_clear_regval; + struct { + bdrkreg_t pec_rsvd : 11; + bdrkreg_t pec_link_reset_in : 1; + bdrkreg_t pec_internal_long : 4; + bdrkreg_t pec_internal_short : 4; + bdrkreg_t pec_external_bad_header : 4; + bdrkreg_t pec_external_long : 4; + bdrkreg_t pec_external_short : 4; + bdrkreg_t pec_fifo_overflow : 4; + bdrkreg_t pec_tail_timeout : 4; + bdrkreg_t pec_retry_count : 8; + bdrkreg_t pec_cb_error_count : 8; + bdrkreg_t pec_sn_error_count : 8; + } ni_port_error_clear_fld_s; +} ni_port_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Lookup table for the next hop's exit port. The table entry * + * selection is based on the 7-bit LocalCube routing destination. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_local_table_0_u { + bdrkreg_t ni_local_table_0_regval; + struct { + bdrkreg_t lt0_next_exit_port : 4; + bdrkreg_t lt0_next_vch_lsb : 1; + bdrkreg_t lt0_rsvd : 59; + } ni_local_table_0_fld_s; +} ni_local_table_0_u_t; + +#else + +typedef union ni_local_table_0_u { + bdrkreg_t ni_local_table_0_regval; + struct { + bdrkreg_t lt0_rsvd : 59; + bdrkreg_t lt0_next_vch_lsb : 1; + bdrkreg_t lt0_next_exit_port : 4; + } ni_local_table_0_fld_s; +} ni_local_table_0_u_t; + +#endif + + + + +/************************************************************************ + * * + * Lookup table for the next hop's exit port. The table entry * + * selection is based on the 7-bit LocalCube routing destination. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_local_table_127_u { + bdrkreg_t ni_local_table_127_regval; + struct { + bdrkreg_t lt1_next_exit_port : 4; + bdrkreg_t lt1_next_vch_lsb : 1; + bdrkreg_t lt1_rsvd : 59; + } ni_local_table_127_fld_s; +} ni_local_table_127_u_t; + +#else + +typedef union ni_local_table_127_u { + bdrkreg_t ni_local_table_127_regval; + struct { + bdrkreg_t lt1_rsvd : 59; + bdrkreg_t lt1_next_vch_lsb : 1; + bdrkreg_t lt1_next_exit_port : 4; + } ni_local_table_127_fld_s; +} ni_local_table_127_u_t; + +#endif + + + + +/************************************************************************ + * * + * Lookup table for the next hop's exit port. The table entry * + * selection is based on the 1-bit MetaCube routing destination. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union ni_global_table_u { + bdrkreg_t ni_global_table_regval; + struct { + bdrkreg_t gt_next_exit_port : 4; + bdrkreg_t gt_next_vch_lsb : 1; + bdrkreg_t gt_rsvd : 59; + } ni_global_table_fld_s; +} ni_global_table_u_t; + +#else + +typedef union ni_global_table_u { + bdrkreg_t ni_global_table_regval; + struct { + bdrkreg_t gt_rsvd : 59; + bdrkreg_t gt_next_vch_lsb : 1; + bdrkreg_t gt_next_exit_port : 4; + } ni_global_table_fld_s; +} ni_global_table_u_t; + +#endif + + + + + + +#endif /* _LANGUAGE_C */ + +/************************************************************************ + * * + * The following defines which were not formed into structures are * + * probably indentical to another register, and the name of the * + * register is provided against each of these registers. This * + * information needs to be checked carefully * + * * + * NI_LOCAL_TABLE_1 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_2 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_3 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_4 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_5 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_6 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_7 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_8 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_9 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_10 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_11 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_12 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_13 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_14 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_15 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_16 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_17 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_18 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_19 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_20 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_21 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_22 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_23 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_24 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_25 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_26 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_27 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_28 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_29 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_30 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_31 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_32 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_33 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_34 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_35 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_36 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_37 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_38 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_39 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_40 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_41 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_42 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_43 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_44 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_45 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_46 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_47 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_48 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_49 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_50 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_51 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_52 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_53 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_54 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_55 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_56 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_57 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_58 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_59 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_60 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_61 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_62 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_63 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_64 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_65 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_66 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_67 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_68 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_69 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_70 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_71 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_72 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_73 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_74 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_75 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_76 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_77 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_78 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_79 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_80 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_81 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_82 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_83 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_84 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_85 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_86 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_87 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_88 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_89 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_90 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_91 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_92 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_93 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_94 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_95 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_96 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_97 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_98 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_99 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_100 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_101 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_102 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_103 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_104 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_105 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_106 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_107 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_108 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_109 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_110 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_111 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_112 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_113 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_114 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_115 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_116 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_117 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_118 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_119 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_120 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_121 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_122 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_123 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_124 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_125 NI_LOCAL_TABLE_0 * + * NI_LOCAL_TABLE_126 NI_LOCAL_TABLE_0 * + * * + ************************************************************************/ + + +/************************************************************************ + * * + * The following defines were not formed into structures * + * * + * This could be because the document did not contain details of the * + * register, or because the automated script did not recognize the * + * register details in the documentation. If these register need * + * structure definition, please create them manually * + * * + * NI_PORT_HEADER_A 0x680108 * + * NI_PORT_HEADER_B 0x680110 * + * * + ************************************************************************/ + + +/************************************************************************ + * * + * MAKE ALL ADDITIONS AFTER THIS LINE * + * * + ************************************************************************/ + + + + + +#endif /* _ASM_SN_SN1_HUBNI_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubni_next.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubni_next.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubni_next.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubni_next.h Wed Dec 6 21:56:14 2000 @@ -0,0 +1,175 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBNI_NEXT_H +#define _ASM_SN_SN1_HUBNI_NEXT_H + +#define NI_LOCAL_ENTRIES 128 +#define NI_META_ENTRIES 1 + +#define NI_LOCAL_TABLE(_x) (NI_LOCAL_TABLE_0 + (8 * (_x))) +#define NI_META_TABLE(_x) (NI_GLOBAL_TABLE + (8 * (_x))) + +/************************************************************** + + Masks and shifts for NI registers are defined below. + +**************************************************************/ + +#define NPS_LINKUP_SHFT 1 +#define NPS_LINKUP_MASK (UINT64_CAST 0x1 << 1) + + +#define NPR_LOCALRESET (UINT64_CAST 1 << 2) /* Reset loc. bdrck */ +#define NPR_PORTRESET (UINT64_CAST 1 << 1) /* Send warm reset */ +#define NPR_LINKRESET (UINT64_CAST 1 << 0) /* Send link reset */ + +/* NI_DIAG_PARMS bit definitions */ +#define NDP_SENDERROR (UINT64_CAST 1 << 0) /* Send data error */ +#define NDP_PORTDISABLE (UINT64_CAST 1 << 1) /* Port disable */ +#define NDP_SENDERROFF (UINT64_CAST 1 << 2) /* Disable send error recovery */ + + +/* NI_PORT_ERROR mask and shift definitions (some are not present in SN0) */ + +#define NPE_LINKRESET (UINT64_CAST 1 << 52) +#define NPE_INTLONG_SHFT 48 +#define NPE_INTLONG_MASK (UINT64_CAST 0xf << NPE_INTLONG_SHFT) +#define NPE_INTSHORT_SHFT 44 +#define NPE_INTSHORT_MASK (UINT64_CAST 0xf << NPE_INTSHORT_SHFT) +#define NPE_EXTBADHEADER_SHFT 40 +#define NPE_EXTBADHEADER_MASK (UINT64_CAST 0xf << NPE_EXTBADHEADER_SHFT) +#define NPE_EXTLONG_SHFT 36 +#define NPE_EXTLONG_MASK (UINT64_CAST 0xf << NPE_EXTLONG_SHFT) +#define NPE_EXTSHORT_SHFT 32 +#define NPE_EXTSHORT_MASK (UINT64_CAST 0xf << NPE_EXTSHORT_SHFT) +#define NPE_FIFOOVFLOW_SHFT 28 +#define NPE_FIFOOVFLOW_MASK (UINT64_CAST 0xf << NPE_FIFOOVFLOW_SHFT) +#define NPE_TAILTO_SHFT 24 +#define NPE_TAILTO_MASK (UINT64_CAST 0xf << NPE_TAILTO_SHFT) +#define NPE_RETRYCOUNT_SHFT 16 +#define NPE_RETRYCOUNT_MASK (UINT64_CAST 0xff << NPE_RETRYCOUNT_SHFT) +#define NPE_CBERRCOUNT_SHFT 8 +#define NPE_CBERRCOUNT_MASK (UINT64_CAST 0xff << NPE_CBERRCOUNT_SHFT) +#define NPE_SNERRCOUNT_SHFT 0 +#define NPE_SNERRCOUNT_MASK (UINT64_CAST 0xff << NPE_SNERRCOUNT_SHFT) + +#define NPE_COUNT_MAX 0xff + +#define NPE_FATAL_ERRORS (NPE_LINKRESET | NPE_INTLONG_MASK |\ + NPE_INTSHORT_MASK | NPE_EXTBADHEADER_MASK |\ + NPE_EXTLONG_MASK | NPE_EXTSHORT_MASK |\ + NPE_FIFOOVFLOW_MASK | NPE_TAILTO_MASK) + +#ifdef _LANGUAGE_C +/* NI_PORT_HEADER[AB] registers (not automatically generated) */ + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_header_a_u { + bdrkreg_t ni_port_header_a_regval; + struct { + bdrkreg_t pha_v : 1; + bdrkreg_t pha_age : 8; + bdrkreg_t pha_direction : 4; + bdrkreg_t pha_destination : 8; + bdrkreg_t pha_reserved_1 : 3; + bdrkreg_t pha_command : 8; + bdrkreg_t pha_prexsel : 3; + bdrkreg_t pha_address_b : 27; + bdrkreg_t pha_reserved : 2; + } ni_port_header_a_fld_s; +} ni_port_header_a_u_t; + +#else + +typedef union ni_port_header_a_u { + bdrkreg_t ni_port_header_a_regval; + struct { + bdrkreg_t pha_reserved : 2; + bdrkreg_t pha_address_b : 27; + bdrkreg_t pha_prexsel : 3; + bdrkreg_t pha_command : 8; + bdrkreg_t pha_reserved_1 : 3; + bdrkreg_t pha_destination : 8; + bdrkreg_t pha_direction : 4; + bdrkreg_t pha_age : 8; + bdrkreg_t pha_v : 1; + } ni_port_header_a_fld_s; +} ni_port_header_a_u_t; + +#endif + +#ifdef LITTLE_ENDIAN + +typedef union ni_port_header_b_u { + bdrkreg_t ni_port_header_b_regval; + struct { + bdrkreg_t phb_supplemental : 11; + bdrkreg_t phb_reserved_2 : 5; + bdrkreg_t phb_source : 11; + bdrkreg_t phb_reserved_1 : 8; + bdrkreg_t phb_address_a : 3; + bdrkreg_t phb_address_c : 8; + bdrkreg_t phb_reserved : 18; + } ni_port_header_b_fld_s; +} ni_port_header_b_u_t; + +#else + +typedef union ni_port_header_b_u { + bdrkreg_t ni_port_header_b_regval; + struct { + bdrkreg_t phb_reserved : 18; + bdrkreg_t phb_address_c : 8; + bdrkreg_t phb_address_a : 3; + bdrkreg_t phb_reserved_1 : 8; + bdrkreg_t phb_source : 11; + bdrkreg_t phb_reserved_2 : 5; + bdrkreg_t phb_supplemental : 11; + } ni_port_header_b_fld_s; +} ni_port_header_b_u_t; + +#endif +#endif + +/* NI_RESET_ENABLE mask definitions */ + +#define NRE_RESETOK (UINT64_CAST 1) /* Let LLP reset bedrock */ + +/* NI PORT_ERRORS, Max number of RETRY_COUNT, Check Bit, and Sequence */ +/* Number errors (8 bit counters that do not wrap). */ +#define NI_LLP_RETRY_MAX 0xff +#define NI_LLP_CB_MAX 0xff +#define NI_LLP_SN_MAX 0xff + +/* NI_PORT_PARMS shift and mask definitions */ + +#define NPP_VCH_ERR_EN_SHFT 31 +#define NPP_VCH_ERR_EN_MASK (0xf << NPP_VCH_ERR_EN_SHFT) +#define NPP_SQUASH_ERR_EN_SHFT 30 +#define NPP_SQUASH_ERR_EN_MASK (0x1 << NPP_SQUASH_ERR_EN_SHFT) +#define NPP_FIRST_ERR_EN_SHFT 29 +#define NPP_FIRST_ERR_EN_MASK (0x1 << NPP_FIRST_ERR_EN_SHFT) +#define NPP_D_AVAIL_SEL_SHFT 26 +#define NPP_D_AVAIL_SEL_MASK (0x3 << NPP_D_AVAIL_SEL_SHFT) +#define NPP_MAX_RETRY_SHFT 16 +#define NPP_MAX_RETRY_MASK (0x3ff << NPP_MAX_RETRY_SHFT) +#define NPP_NULL_TIMEOUT_SHFT 10 +#define NPP_NULL_TIMEOUT_MASK (0x3f << NPP_NULL_TIMEOUT_SHFT) +#define NPP_MAX_BURST_SHFT 0 +#define NPP_MAX_BURST_MASK (0x3ff << NPP_MAX_BURST_SHFT) + +#define NPP_RESET_DEFAULTS (0xf << NPP_VCH_ERR_EN_SHFT | \ + 0x1 << NPP_FIRST_ERR_EN_SHFT | \ + 0x3ff << NPP_MAX_RETRY_SHFT | \ + 0x6 << NPP_NULL_TIMEOUT_SHFT | \ + 0x3f0 << NPP_MAX_BURST_SHFT) + +#endif /* _ASM_SN_SN1_HUBNI_NEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubpi.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubpi.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubpi.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubpi.h Wed Dec 6 21:56:15 2000 @@ -0,0 +1,4264 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBPI_H +#define _ASM_SN_SN1_HUBPI_H + +/************************************************************************ + * * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! * + * * + * This file is created by an automated script. Any (minimal) changes * + * made manually to this file should be made with care. * + * * + * MAKE ALL ADDITIONS TO THE END OF THIS FILE * + * * + ************************************************************************/ + + +#define PI_CPU_PROTECT 0x00000000 /* CPU Protection */ + + + +#define PI_PROT_OVRRD 0x00000008 /* + * Clear CPU + * Protection bit in + * CPU_PROTECT + */ + + + +#define PI_IO_PROTECT 0x00000010 /* + * Interrupt Pending + * Protection for IO + * access + */ + + + +#define PI_REGION_PRESENT 0x00000018 /* Region present */ + + + +#define PI_CPU_NUM 0x00000020 /* CPU Number ID */ + + + +#define PI_CALIAS_SIZE 0x00000028 /* Cached Alias Size */ + + + +#define PI_MAX_CRB_TIMEOUT 0x00000030 /* + * Maximum Timeout for + * CRB + */ + + + +#define PI_CRB_SFACTOR 0x00000038 /* + * Scale Factor for + * CRB Timeout + */ + + + +#define PI_CPU_PRESENT_A 0x00000040 /* + * CPU Present for + * CPU_A + */ + + + +#define PI_CPU_PRESENT_B 0x00000048 /* + * CPU Present for + * CPU_B + */ + + + +#define PI_CPU_ENABLE_A 0x00000050 /* + * CPU Enable for + * CPU_A + */ + + + +#define PI_CPU_ENABLE_B 0x00000058 /* + * CPU Enable for + * CPU_B + */ + + + +#define PI_REPLY_LEVEL 0x00010060 /* + * Reply FIFO Priority + * Control + */ + + + +#define PI_GFX_CREDIT_MODE 0x00020068 /* + * Graphics Credit + * Mode + */ + + + +#define PI_NMI_A 0x00000070 /* + * Non-maskable + * Interrupt to CPU A + */ + + + +#define PI_NMI_B 0x00000078 /* + * Non-maskable + * Interrupt to CPU B + */ + + + +#define PI_INT_PEND_MOD 0x00000090 /* + * Interrupt Pending + * Modify + */ + + + +#define PI_INT_PEND0 0x00000098 /* Interrupt Pending 0 */ + + + +#define PI_INT_PEND1 0x000000A0 /* Interrupt Pending 1 */ + + + +#define PI_INT_MASK0_A 0x000000A8 /* + * Interrupt Mask 0 + * for CPU A + */ + + + +#define PI_INT_MASK1_A 0x000000B0 /* + * Interrupt Mask 1 + * for CPU A + */ + + + +#define PI_INT_MASK0_B 0x000000B8 /* + * Interrupt Mask 0 + * for CPU B + */ + + + +#define PI_INT_MASK1_B 0x000000C0 /* + * Interrupt Mask 1 + * for CPU B + */ + + + +#define PI_CC_PEND_SET_A 0x000000C8 /* + * CC Interrupt + * Pending for CPU A + */ + + + +#define PI_CC_PEND_SET_B 0x000000D0 /* + * CC Interrupt + * Pending for CPU B + */ + + + +#define PI_CC_PEND_CLR_A 0x000000D8 /* + * CPU to CPU + * Interrupt Pending + * Clear for CPU A + */ + + + +#define PI_CC_PEND_CLR_B 0x000000E0 /* + * CPU to CPU + * Interrupt Pending + * Clear for CPU B + */ + + + +#define PI_CC_MASK 0x000000E8 /* + * Mask of both + * CC_PENDs + */ + + + +#define PI_INT_PEND1_REMAP 0x000000F0 /* + * Remap Interrupt + * Pending + */ + + + +#define PI_RT_COUNTER 0x00030100 /* Real Time Counter */ + + + +#define PI_RT_COMPARE_A 0x00000108 /* Real Time Compare A */ + + + +#define PI_RT_COMPARE_B 0x00000110 /* Real Time Compare B */ + + + +#define PI_PROFILE_COMPARE 0x00000118 /* Profiling Compare */ + + + +#define PI_RT_INT_PEND_A 0x00000120 /* + * RT interrupt + * pending + */ + + + +#define PI_RT_INT_PEND_B 0x00000128 /* + * RT interrupt + * pending + */ + + + +#define PI_PROF_INT_PEND_A 0x00000130 /* + * Profiling interrupt + * pending + */ + + + +#define PI_PROF_INT_PEND_B 0x00000138 /* + * Profiling interrupt + * pending + */ + + + +#define PI_RT_INT_EN_A 0x00000140 /* RT Interrupt Enable */ + + + +#define PI_RT_INT_EN_B 0x00000148 /* RT Interrupt Enable */ + + + +#define PI_PROF_INT_EN_A 0x00000150 /* + * Profiling Interrupt + * Enable + */ + + + +#define PI_PROF_INT_EN_B 0x00000158 /* + * Profiling Interrupt + * Enable + */ + + + +#define PI_DEBUG_SEL 0x00000160 /* PI Debug Select */ + + + +#define PI_INT_PEND_MOD_ALIAS 0x00000180 /* + * Interrupt Pending + * Modify + */ + + + +#define PI_PERF_CNTL_A 0x00040200 /* + * Performance Counter + * Control A + */ + + + +#define PI_PERF_CNTR0_A 0x00040208 /* + * Performance Counter + * 0 A + */ + + + +#define PI_PERF_CNTR1_A 0x00040210 /* + * Performance Counter + * 1 A + */ + + + +#define PI_PERF_CNTL_B 0x00050200 /* + * Performance Counter + * Control B + */ + + + +#define PI_PERF_CNTR0_B 0x00050208 /* + * Performance Counter + * 0 B + */ + + + +#define PI_PERF_CNTR1_B 0x00050210 /* + * Performance Counter + * 1 B + */ + + + +#define PI_GFX_PAGE_A 0x00000300 /* Graphics Page */ + + + +#define PI_GFX_CREDIT_CNTR_A 0x00000308 /* + * Graphics Credit + * Counter + */ + + + +#define PI_GFX_BIAS_A 0x00000310 /* TRex+ BIAS */ + + + +#define PI_GFX_INT_CNTR_A 0x00000318 /* + * Graphics Interrupt + * Counter + */ + + + +#define PI_GFX_INT_CMP_A 0x00000320 /* + * Graphics Interrupt + * Compare + */ + + + +#define PI_GFX_PAGE_B 0x00000328 /* Graphics Page */ + + + +#define PI_GFX_CREDIT_CNTR_B 0x00000330 /* + * Graphics Credit + * Counter + */ + + + +#define PI_GFX_BIAS_B 0x00000338 /* TRex+ BIAS */ + + + +#define PI_GFX_INT_CNTR_B 0x00000340 /* + * Graphics Interrupt + * Counter + */ + + + +#define PI_GFX_INT_CMP_B 0x00000348 /* + * Graphics Interrupt + * Compare + */ + + + +#define PI_ERR_INT_PEND_WR 0x000003F8 /* + * Error Interrupt + * Pending (Writable) + */ + + + +#define PI_ERR_INT_PEND 0x00000400 /* + * Error Interrupt + * Pending + */ + + + +#define PI_ERR_INT_MASK_A 0x00000408 /* + * Error Interrupt + * Mask CPU_A + */ + + + +#define PI_ERR_INT_MASK_B 0x00000410 /* + * Error Interrupt + * Mask CPU_B + */ + + + +#define PI_ERR_STACK_ADDR_A 0x00000418 /* + * Error Stack Address + * Pointer + */ + + + +#define PI_ERR_STACK_ADDR_B 0x00000420 /* + * Error Stack Address + * Pointer + */ + + + +#define PI_ERR_STACK_SIZE 0x00000428 /* Error Stack Size */ + + + +#define PI_ERR_STATUS0_A 0x00000430 /* Error Status 0 */ + + + +#define PI_ERR_STATUS0_A_CLR 0x00000438 /* Error Status 0 */ + + + +#define PI_ERR_STATUS1_A 0x00000440 /* Error Status 1 */ + + + +#define PI_ERR_STATUS1_A_CLR 0x00000448 /* Error Status 1 */ + + + +#define PI_ERR_STATUS0_B 0x00000450 /* Error Status 0 */ + + + +#define PI_ERR_STATUS0_B_CLR 0x00000458 /* Error Status 0 */ + + + +#define PI_ERR_STATUS1_B 0x00000460 /* Error Status 1 */ + + + +#define PI_ERR_STATUS1_B_CLR 0x00000468 /* Error Status 1 */ + + + +#define PI_SPOOL_CMP_A 0x00000470 /* Spool Compare */ + + + +#define PI_SPOOL_CMP_B 0x00000478 /* Spool Compare */ + + + +#define PI_CRB_TIMEOUT_A 0x00000480 /* + * CRB entries which + * have timed out but + * are still valid + */ + + + +#define PI_CRB_TIMEOUT_B 0x00000488 /* + * CRB entries which + * have timed out but + * are still valid + */ + + + +#define PI_SYSAD_ERRCHK_EN 0x00000490 /* + * enables + * sysad/cmd/state + * error checking + */ + + + +#define PI_FORCE_BAD_CHECK_BIT_A 0x00000498 /* + * force SysAD Check + * Bit error + */ + + + +#define PI_FORCE_BAD_CHECK_BIT_B 0x000004A0 /* + * force SysAD Check + * Bit error + */ + + + +#define PI_NACK_CNT_A 0x000004A8 /* + * consecutive NACK + * counter + */ + + + +#define PI_NACK_CNT_B 0x000004B0 /* + * consecutive NACK + * counter + */ + + + +#define PI_NACK_CMP 0x000004B8 /* NACK count compare */ + + + +#define PI_SPOOL_MASK 0x000004C0 /* Spool error mask */ + + + +#define PI_SPURIOUS_HDR_0 0x000004C8 /* Spurious Error 0 */ + + + +#define PI_SPURIOUS_HDR_1 0x000004D0 /* Spurious Error 1 */ + + + +#define PI_ERR_INJECT 0x000004D8 /* + * SysAD bus error + * injection + */ + + + + + +#ifdef _LANGUAGE_C + +/************************************************************************ + * * + * Description: This read/write register determines on a * + * bit-per-region basis whether incoming CPU-initiated PIO Read and * + * Write to local PI registers are allowed. If access is allowed, the * + * PI's response to a partial read is a PRPLY message, and the * + * response to a partial write is a PACK message. If access is not * + * allowed, the PI's response to a partial read is a PRERR message, * + * and the response to a partial write is a PWERR message. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +typedef union pi_cpu_protect_u { + bdrkreg_t pi_cpu_protect_regval; + struct { + bdrkreg_t cp_cpu_protect : 64; + } pi_cpu_protect_fld_s; +} pi_cpu_protect_u_t; + + + + +/************************************************************************ + * * + * A write with a special data pattern allows any CPU to set its * + * region's bit in CPU_PROTECT. This register has data pattern * + * protection. * + * * + ************************************************************************/ + + + + +typedef union pi_prot_ovrrd_u { + bdrkreg_t pi_prot_ovrrd_regval; + struct { + bdrkreg_t po_prot_ovrrd : 64; + } pi_prot_ovrrd_fld_s; +} pi_prot_ovrrd_u_t; + + + + +/************************************************************************ + * * + * Description: This read/write register determines on a * + * bit-per-region basis whether incoming IO-initiated interrupts are * + * allowed to set bits in INT_PEND0 and INT_PEND1. If access is * + * allowed, the PI's response to a partial read is a PRPLY message, * + * and the response to a partial write is a PACK message. If access * + * is not allowed, the PI's response to a partial read is a PRERR * + * message, and the response to a partial write is a PWERR message. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +typedef union pi_io_protect_u { + bdrkreg_t pi_io_protect_regval; + struct { + bdrkreg_t ip_io_protect : 64; + } pi_io_protect_fld_s; +} pi_io_protect_u_t; + + + + +/************************************************************************ + * * + * Description: This read/write register determines on a * + * bit-per-region basis whether read access from a local processor to * + * the region is permissible. For example, setting a bit to 0 * + * prevents speculative reads to that non-existent node. If a read * + * request to a non-present region occurs, an ERR response is issued * + * to the TRex+ (no PI error registers are modified). It is up to * + * software to load this register with the proper contents. * + * Region-present checking is only done for coherent read requests - * + * partial reads/writes will be issued to a non-present region. The * + * setting of these bits does not affect a node's access to its * + * CALIAS space. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +typedef union pi_region_present_u { + bdrkreg_t pi_region_present_regval; + struct { + bdrkreg_t rp_region_present : 64; + } pi_region_present_fld_s; +} pi_region_present_u_t; + + + + +/************************************************************************ + * * + * A read to the location will allow a CPU to identify itself as * + * either CPU_A or CPU_B, and will indicate whether the CPU is * + * connected to PI 0 or PI 1. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_cpu_num_u { + bdrkreg_t pi_cpu_num_regval; + struct { + bdrkreg_t cn_cpu_num : 1; + bdrkreg_t cn_pi_id : 1; + bdrkreg_t cn_rsvd : 62; + } pi_cpu_num_fld_s; +} pi_cpu_num_u_t; + +#else + +typedef union pi_cpu_num_u { + bdrkreg_t pi_cpu_num_regval; + struct { + bdrkreg_t cn_rsvd : 62; + bdrkreg_t cn_pi_id : 1; + bdrkreg_t cn_cpu_num : 1; + } pi_cpu_num_fld_s; +} pi_cpu_num_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This read/write location determines the size of the * + * Calias Space. * + * This register is not reset by a soft reset. * + * NOTE: For predictable behavior, all Calias spaces in a system must * + * be set to the same size. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_calias_size_u { + bdrkreg_t pi_calias_size_regval; + struct { + bdrkreg_t cs_calias_size : 4; + bdrkreg_t cs_rsvd : 60; + } pi_calias_size_fld_s; +} pi_calias_size_u_t; + +#else + +typedef union pi_calias_size_u { + bdrkreg_t pi_calias_size_regval; + struct { + bdrkreg_t cs_rsvd : 60; + bdrkreg_t cs_calias_size : 4; + } pi_calias_size_fld_s; +} pi_calias_size_u_t; + +#endif + + + + +/************************************************************************ + * * + * This Read/Write location determines at which value (increment) * + * the CRB Timeout Counters cause a timeout error to occur. See * + * Section 3.4.2.2, "Time-outs in RRB and WRB" in the * + * Processor Interface chapter, volume 1 of this document for more * + * details. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_max_crb_timeout_u { + bdrkreg_t pi_max_crb_timeout_regval; + struct { + bdrkreg_t mct_max_timeout : 8; + bdrkreg_t mct_rsvd : 56; + } pi_max_crb_timeout_fld_s; +} pi_max_crb_timeout_u_t; + +#else + +typedef union pi_max_crb_timeout_u { + bdrkreg_t pi_max_crb_timeout_regval; + struct { + bdrkreg_t mct_rsvd : 56; + bdrkreg_t mct_max_timeout : 8; + } pi_max_crb_timeout_fld_s; +} pi_max_crb_timeout_u_t; + +#endif + + + + +/************************************************************************ + * * + * This Read/Write location determines how often a valid CRB's * + * Timeout Counter is incremented. See Section 3.4.2.2, * + * "Time-outs in RRB and WRB" in the Processor Interface * + * chapter, volume 1 of this document for more details. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_crb_sfactor_u { + bdrkreg_t pi_crb_sfactor_regval; + struct { + bdrkreg_t cs_sfactor : 24; + bdrkreg_t cs_rsvd : 40; + } pi_crb_sfactor_fld_s; +} pi_crb_sfactor_u_t; + +#else + +typedef union pi_crb_sfactor_u { + bdrkreg_t pi_crb_sfactor_regval; + struct { + bdrkreg_t cs_rsvd : 40; + bdrkreg_t cs_sfactor : 24; + } pi_crb_sfactor_fld_s; +} pi_crb_sfactor_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. The PI sets this * + * bit when it sees the first transaction initiated by the associated * + * CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_cpu_present_a_u { + bdrkreg_t pi_cpu_present_a_regval; + struct { + bdrkreg_t cpa_cpu_present : 1; + bdrkreg_t cpa_rsvd : 63; + } pi_cpu_present_a_fld_s; +} pi_cpu_present_a_u_t; + +#else + +typedef union pi_cpu_present_a_u { + bdrkreg_t pi_cpu_present_a_regval; + struct { + bdrkreg_t cpa_rsvd : 63; + bdrkreg_t cpa_cpu_present : 1; + } pi_cpu_present_a_fld_s; +} pi_cpu_present_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. The PI sets this * + * bit when it sees the first transaction initiated by the associated * + * CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_cpu_present_b_u { + bdrkreg_t pi_cpu_present_b_regval; + struct { + bdrkreg_t cpb_cpu_present : 1; + bdrkreg_t cpb_rsvd : 63; + } pi_cpu_present_b_fld_s; +} pi_cpu_present_b_u_t; + +#else + +typedef union pi_cpu_present_b_u { + bdrkreg_t pi_cpu_present_b_regval; + struct { + bdrkreg_t cpb_rsvd : 63; + bdrkreg_t cpb_cpu_present : 1; + } pi_cpu_present_b_fld_s; +} pi_cpu_present_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There is one of these registers for each CPU. This * + * Read/Write location determines whether the associated CPU is * + * enabled to issue external requests. When this bit is zero for a * + * processor, the PI ignores SysReq_L from that processor, and so * + * never grants it the bus. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_cpu_enable_a_u { + bdrkreg_t pi_cpu_enable_a_regval; + struct { + bdrkreg_t cea_cpu_enable : 1; + bdrkreg_t cea_rsvd : 63; + } pi_cpu_enable_a_fld_s; +} pi_cpu_enable_a_u_t; + +#else + +typedef union pi_cpu_enable_a_u { + bdrkreg_t pi_cpu_enable_a_regval; + struct { + bdrkreg_t cea_rsvd : 63; + bdrkreg_t cea_cpu_enable : 1; + } pi_cpu_enable_a_fld_s; +} pi_cpu_enable_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There is one of these registers for each CPU. This * + * Read/Write location determines whether the associated CPU is * + * enabled to issue external requests. When this bit is zero for a * + * processor, the PI ignores SysReq_L from that processor, and so * + * never grants it the bus. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_cpu_enable_b_u { + bdrkreg_t pi_cpu_enable_b_regval; + struct { + bdrkreg_t ceb_cpu_enable : 1; + bdrkreg_t ceb_rsvd : 63; + } pi_cpu_enable_b_fld_s; +} pi_cpu_enable_b_u_t; + +#else + +typedef union pi_cpu_enable_b_u { + bdrkreg_t pi_cpu_enable_b_regval; + struct { + bdrkreg_t ceb_rsvd : 63; + bdrkreg_t ceb_cpu_enable : 1; + } pi_cpu_enable_b_fld_s; +} pi_cpu_enable_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. A write to this * + * location will cause an NMI to be issued to the CPU. * + * * + ************************************************************************/ + + + + +typedef union pi_nmi_a_u { + bdrkreg_t pi_nmi_a_regval; + struct { + bdrkreg_t na_nmi_cpu : 64; + } pi_nmi_a_fld_s; +} pi_nmi_a_u_t; + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. A write to this * + * location will cause an NMI to be issued to the CPU. * + * * + ************************************************************************/ + + + + +typedef union pi_nmi_b_u { + bdrkreg_t pi_nmi_b_regval; + struct { + bdrkreg_t nb_nmi_cpu : 64; + } pi_nmi_b_fld_s; +} pi_nmi_b_u_t; + + + + +/************************************************************************ + * * + * A write to this register allows a single bit in the INT_PEND0 or * + * INT_PEND1 registers to be set or cleared. If 6 is clear, a bit is * + * modified in INT_PEND0, while if 6 is set, a bit is modified in * + * INT_PEND1. The value in 5:0 (ranging from 63 to 0) will determine * + * which bit in the register is effected. The value of 8 will * + * determine whether the desired bit is set (8=1) or cleared (8=0). * + * This is the only register which is accessible by IO issued PWRI * + * command and is protected through the IO_PROTECT register. If the * + * region bit in the IO_PROTECT is not set then a WERR reply is * + * issued. CPU access is controlled through CPU_PROTECT. The contents * + * of this register are masked with the contents of INT_MASK_A * + * (INT_MASK_B) to determine whether an L2 interrupt is issued to * + * CPU_A (CPU_B). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_pend_mod_u { + bdrkreg_t pi_int_pend_mod_regval; + struct { + bdrkreg_t ipm_bit_select : 6; + bdrkreg_t ipm_reg_select : 1; + bdrkreg_t ipm_rsvd_1 : 1; + bdrkreg_t ipm_value : 1; + bdrkreg_t ipm_rsvd : 55; + } pi_int_pend_mod_fld_s; +} pi_int_pend_mod_u_t; + +#else + +typedef union pi_int_pend_mod_u { + bdrkreg_t pi_int_pend_mod_regval; + struct { + bdrkreg_t ipm_rsvd : 55; + bdrkreg_t ipm_value : 1; + bdrkreg_t ipm_rsvd_1 : 1; + bdrkreg_t ipm_reg_select : 1; + bdrkreg_t ipm_bit_select : 6; + } pi_int_pend_mod_fld_s; +} pi_int_pend_mod_u_t; + +#endif + + + + +/************************************************************************ + * * + * This read-only register provides information about interrupts * + * that are currently pending. The interrupts in this register map to * + * interrupt level 2 (L2). The GFX_INT_A/B bits are set by hardware * + * but must be cleared by software. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_pend0_u { + bdrkreg_t pi_int_pend0_regval; + struct { + bdrkreg_t ip_int_pend0_lo : 1; + bdrkreg_t ip_gfx_int_a : 1; + bdrkreg_t ip_gfx_int_b : 1; + bdrkreg_t ip_page_migration : 1; + bdrkreg_t ip_uart_ucntrl : 1; + bdrkreg_t ip_or_cc_pend_a : 1; + bdrkreg_t ip_or_cc_pend_b : 1; + bdrkreg_t ip_int_pend0_hi : 57; + } pi_int_pend0_fld_s; +} pi_int_pend0_u_t; + +#else + +typedef union pi_int_pend0_u { + bdrkreg_t pi_int_pend0_regval; + struct { + bdrkreg_t ip_int_pend0_hi : 57; + bdrkreg_t ip_or_cc_pend_b : 1; + bdrkreg_t ip_or_cc_pend_a : 1; + bdrkreg_t ip_uart_ucntrl : 1; + bdrkreg_t ip_page_migration : 1; + bdrkreg_t ip_gfx_int_b : 1; + bdrkreg_t ip_gfx_int_a : 1; + bdrkreg_t ip_int_pend0_lo : 1; + } pi_int_pend0_fld_s; +} pi_int_pend0_u_t; + +#endif + + + + +/************************************************************************ + * * + * This read-only register provides information about interrupts * + * that are currently pending. The interrupts in this register map to * + * interrupt level 3 (L3), unless remapped by the INT_PEND1_REMAP * + * register. The SYS_COR_ERR_A/B, RTC_DROP_OUT, and NACK_INT_A/B bits * + * are set by hardware but must be cleared by software. The * + * SYSTEM_SHUTDOWN, NI_ERROR, LB_ERROR and XB_ERROR bits just reflect * + * the value of other logic, and cannot be changed by PI register * + * writes. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_pend1_u { + bdrkreg_t pi_int_pend1_regval; + struct { + bdrkreg_t ip_int_pend1 : 54; + bdrkreg_t ip_xb_error : 1; + bdrkreg_t ip_lb_error : 1; + bdrkreg_t ip_nack_int_a : 1; + bdrkreg_t ip_nack_int_b : 1; + bdrkreg_t ip_perf_cntr_oflow : 1; + bdrkreg_t ip_sys_cor_err_b : 1; + bdrkreg_t ip_sys_cor_err_a : 1; + bdrkreg_t ip_md_corr_error : 1; + bdrkreg_t ip_ni_error : 1; + bdrkreg_t ip_system_shutdown : 1; + } pi_int_pend1_fld_s; +} pi_int_pend1_u_t; + +#else + +typedef union pi_int_pend1_u { + bdrkreg_t pi_int_pend1_regval; + struct { + bdrkreg_t ip_system_shutdown : 1; + bdrkreg_t ip_ni_error : 1; + bdrkreg_t ip_md_corr_error : 1; + bdrkreg_t ip_sys_cor_err_a : 1; + bdrkreg_t ip_sys_cor_err_b : 1; + bdrkreg_t ip_perf_cntr_oflow : 1; + bdrkreg_t ip_nack_int_b : 1; + bdrkreg_t ip_nack_int_a : 1; + bdrkreg_t ip_lb_error : 1; + bdrkreg_t ip_xb_error : 1; + bdrkreg_t ip_int_pend1 : 54; + } pi_int_pend1_fld_s; +} pi_int_pend1_u_t; + +#endif + + + + +/************************************************************************ + * * + * This read/write register masks the contents of INT_PEND0 to * + * determine whether an L2 interrupt (bit 10 of the processor's Cause * + * register) is sent to CPU_A if the same bit in the INT_PEND0 * + * register is also set. Only one processor in a Bedrock should * + * enable the PAGE_MIGRATION bit/interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_mask0_a_u { + bdrkreg_t pi_int_mask0_a_regval; + struct { + bdrkreg_t ima_int_mask0_lo : 1; + bdrkreg_t ima_gfx_int_a : 1; + bdrkreg_t ima_gfx_int_b : 1; + bdrkreg_t ima_page_migration : 1; + bdrkreg_t ima_uart_ucntrl : 1; + bdrkreg_t ima_or_ccp_mask_a : 1; + bdrkreg_t ima_or_ccp_mask_b : 1; + bdrkreg_t ima_int_mask0_hi : 57; + } pi_int_mask0_a_fld_s; +} pi_int_mask0_a_u_t; + +#else + +typedef union pi_int_mask0_a_u { + bdrkreg_t pi_int_mask0_a_regval; + struct { + bdrkreg_t ima_int_mask0_hi : 57; + bdrkreg_t ima_or_ccp_mask_b : 1; + bdrkreg_t ima_or_ccp_mask_a : 1; + bdrkreg_t ima_uart_ucntrl : 1; + bdrkreg_t ima_page_migration : 1; + bdrkreg_t ima_gfx_int_b : 1; + bdrkreg_t ima_gfx_int_a : 1; + bdrkreg_t ima_int_mask0_lo : 1; + } pi_int_mask0_a_fld_s; +} pi_int_mask0_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * This read/write register masks the contents of INT_PEND1 to * + * determine whether an interrupt should be sent. Bits 63:32 always * + * generate an L3 interrupt (bit 11 of the processor's Cause * + * register) is sent to CPU_A if the same bit in the INT_PEND1 * + * register is set. Bits 31:0 can generate either an L3 or L2 * + * interrupt, depending on the value of INT_PEND1_REMAP[3:0]. Only * + * one processor in a Bedrock should enable the NI_ERROR, LB_ERROR, * + * XB_ERROR and MD_CORR_ERROR bits. * + * * + ************************************************************************/ + + + + +typedef union pi_int_mask1_a_u { + bdrkreg_t pi_int_mask1_a_regval; + struct { + bdrkreg_t ima_int_mask1 : 64; + } pi_int_mask1_a_fld_s; +} pi_int_mask1_a_u_t; + + + + +/************************************************************************ + * * + * This read/write register masks the contents of INT_PEND0 to * + * determine whether an L2 interrupt (bit 10 of the processor's Cause * + * register) is sent to CPU_B if the same bit in the INT_PEND0 * + * register is also set. Only one processor in a Bedrock should * + * enable the PAGE_MIGRATION bit/interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_mask0_b_u { + bdrkreg_t pi_int_mask0_b_regval; + struct { + bdrkreg_t imb_int_mask0_lo : 1; + bdrkreg_t imb_gfx_int_a : 1; + bdrkreg_t imb_gfx_int_b : 1; + bdrkreg_t imb_page_migration : 1; + bdrkreg_t imb_uart_ucntrl : 1; + bdrkreg_t imb_or_ccp_mask_a : 1; + bdrkreg_t imb_or_ccp_mask_b : 1; + bdrkreg_t imb_int_mask0_hi : 57; + } pi_int_mask0_b_fld_s; +} pi_int_mask0_b_u_t; + +#else + +typedef union pi_int_mask0_b_u { + bdrkreg_t pi_int_mask0_b_regval; + struct { + bdrkreg_t imb_int_mask0_hi : 57; + bdrkreg_t imb_or_ccp_mask_b : 1; + bdrkreg_t imb_or_ccp_mask_a : 1; + bdrkreg_t imb_uart_ucntrl : 1; + bdrkreg_t imb_page_migration : 1; + bdrkreg_t imb_gfx_int_b : 1; + bdrkreg_t imb_gfx_int_a : 1; + bdrkreg_t imb_int_mask0_lo : 1; + } pi_int_mask0_b_fld_s; +} pi_int_mask0_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This read/write register masks the contents of INT_PEND1 to * + * determine whether an interrupt should be sent. Bits 63:32 always * + * generate an L3 interrupt (bit 11 of the processor's Cause * + * register) is sent to CPU_B if the same bit in the INT_PEND1 * + * register is set. Bits 31:0 can generate either an L3 or L2 * + * interrupt, depending on the value of INT_PEND1_REMAP[3:0]. Only * + * one processor in a Bedrock should enable the NI_ERROR, LB_ERROR, * + * XB_ERROR and MD_CORR_ERROR bits. * + * * + ************************************************************************/ + + + + +typedef union pi_int_mask1_b_u { + bdrkreg_t pi_int_mask1_b_regval; + struct { + bdrkreg_t imb_int_mask1 : 64; + } pi_int_mask1_b_fld_s; +} pi_int_mask1_b_u_t; + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. These registers do * + * not have access protection. A store to this location by a CPU will * + * cause the bit corresponding to the source's region to be set in * + * CC_PEND_A (or CC_PEND_B). The contents of CC_PEND_A (or CC_PEND_B) * + * determines on a bit-per-region basis whether a CPU-to-CPU * + * interrupt is pending CPU_A (or CPU_B). * + * * + ************************************************************************/ + + + + +typedef union pi_cc_pend_set_a_u { + bdrkreg_t pi_cc_pend_set_a_regval; + struct { + bdrkreg_t cpsa_cc_pend : 64; + } pi_cc_pend_set_a_fld_s; +} pi_cc_pend_set_a_u_t; + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. These registers do * + * not have access protection. A store to this location by a CPU will * + * cause the bit corresponding to the source's region to be set in * + * CC_PEND_A (or CC_PEND_B). The contents of CC_PEND_A (or CC_PEND_B) * + * determines on a bit-per-region basis whether a CPU-to-CPU * + * interrupt is pending CPU_A (or CPU_B). * + * * + ************************************************************************/ + + + + +typedef union pi_cc_pend_set_b_u { + bdrkreg_t pi_cc_pend_set_b_regval; + struct { + bdrkreg_t cpsb_cc_pend : 64; + } pi_cc_pend_set_b_fld_s; +} pi_cc_pend_set_b_u_t; + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Reading this * + * location will return the contents of CC_PEND_A (or CC_PEND_B). * + * Writing this location will clear the bits corresponding to which * + * data bits are driven high during the store; therefore, storing all * + * ones would clear all bits. * + * * + ************************************************************************/ + + + + +typedef union pi_cc_pend_clr_a_u { + bdrkreg_t pi_cc_pend_clr_a_regval; + struct { + bdrkreg_t cpca_cc_pend : 64; + } pi_cc_pend_clr_a_fld_s; +} pi_cc_pend_clr_a_u_t; + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Reading this * + * location will return the contents of CC_PEND_A (or CC_PEND_B). * + * Writing this location will clear the bits corresponding to which * + * data bits are driven high during the store; therefore, storing all * + * ones would clear all bits. * + * * + ************************************************************************/ + + + + +typedef union pi_cc_pend_clr_b_u { + bdrkreg_t pi_cc_pend_clr_b_regval; + struct { + bdrkreg_t cpcb_cc_pend : 64; + } pi_cc_pend_clr_b_fld_s; +} pi_cc_pend_clr_b_u_t; + + + + +/************************************************************************ + * * + * This read/write register masks the contents of both CC_PEND_A and * + * CC_PEND_B. * + * * + ************************************************************************/ + + + + +typedef union pi_cc_mask_u { + bdrkreg_t pi_cc_mask_regval; + struct { + bdrkreg_t cm_cc_mask : 64; + } pi_cc_mask_fld_s; +} pi_cc_mask_u_t; + + + + +/************************************************************************ + * * + * This read/write register redirects INT_PEND1[31:0] from L3 to L2 * + * interrupt level.Bit 4 in this register is used to enable error * + * interrupt forwarding to the II. When this bit is set, if any of * + * the three memory interrupts (correctable error, uncorrectable * + * error, or page migration), or the NI, LB or XB error interrupts * + * are set, the PI_II_ERROR_INT wire will be asserted. When this wire * + * is asserted, the II will send an interrupt to the node specified * + * in its IIDSR (Interrupt Destination Register). This allows these * + * interrupts to be forwarded to another node. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_pend1_remap_u { + bdrkreg_t pi_int_pend1_remap_regval; + struct { + bdrkreg_t ipr_remap_0 : 1; + bdrkreg_t ipr_remap_1 : 1; + bdrkreg_t ipr_remap_2 : 1; + bdrkreg_t ipr_remap_3 : 1; + bdrkreg_t ipr_error_forward : 1; + bdrkreg_t ipr_reserved : 59; + } pi_int_pend1_remap_fld_s; +} pi_int_pend1_remap_u_t; + +#else + +typedef union pi_int_pend1_remap_u { + bdrkreg_t pi_int_pend1_remap_regval; + struct { + bdrkreg_t ipr_reserved : 59; + bdrkreg_t ipr_error_forward : 1; + bdrkreg_t ipr_remap_3 : 1; + bdrkreg_t ipr_remap_2 : 1; + bdrkreg_t ipr_remap_1 : 1; + bdrkreg_t ipr_remap_0 : 1; + } pi_int_pend1_remap_fld_s; +} pi_int_pend1_remap_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. When the real time * + * counter (RT_Counter) is equal to the value in this register, the * + * RT_INT_PEND register is set, which causes a Level-4 interrupt to * + * be sent to the processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_compare_a_u { + bdrkreg_t pi_rt_compare_a_regval; + struct { + bdrkreg_t rca_rt_compare : 55; + bdrkreg_t rca_rsvd : 9; + } pi_rt_compare_a_fld_s; +} pi_rt_compare_a_u_t; + +#else + +typedef union pi_rt_compare_a_u { + bdrkreg_t pi_rt_compare_a_regval; + struct { + bdrkreg_t rca_rsvd : 9; + bdrkreg_t rca_rt_compare : 55; + } pi_rt_compare_a_fld_s; +} pi_rt_compare_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. When the real time * + * counter (RT_Counter) is equal to the value in this register, the * + * RT_INT_PEND register is set, which causes a Level-4 interrupt to * + * be sent to the processor. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_compare_b_u { + bdrkreg_t pi_rt_compare_b_regval; + struct { + bdrkreg_t rcb_rt_compare : 55; + bdrkreg_t rcb_rsvd : 9; + } pi_rt_compare_b_fld_s; +} pi_rt_compare_b_u_t; + +#else + +typedef union pi_rt_compare_b_u { + bdrkreg_t pi_rt_compare_b_regval; + struct { + bdrkreg_t rcb_rsvd : 9; + bdrkreg_t rcb_rt_compare : 55; + } pi_rt_compare_b_fld_s; +} pi_rt_compare_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * When the least significant 32 bits of the real time counter * + * (RT_Counter) are equal to the value in this register, the * + * PROF_INT_PEND_A and PROF_INT_PEND_B registers are set to 0x1. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_profile_compare_u { + bdrkreg_t pi_profile_compare_regval; + struct { + bdrkreg_t pc_profile_compare : 32; + bdrkreg_t pc_rsvd : 32; + } pi_profile_compare_fld_s; +} pi_profile_compare_u_t; + +#else + +typedef union pi_profile_compare_u { + bdrkreg_t pi_profile_compare_regval; + struct { + bdrkreg_t pc_rsvd : 32; + bdrkreg_t pc_profile_compare : 32; + } pi_profile_compare_fld_s; +} pi_profile_compare_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. If the bit in the * + * corresponding RT_INT_EN_A/B register is set, the processor's level * + * 5 interrupt is set to the value of the RTC_INT_PEND bit in this * + * register. Storing any value to this location will clear the * + * RTC_INT_PEND bit in the register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_int_pend_a_u { + bdrkreg_t pi_rt_int_pend_a_regval; + struct { + bdrkreg_t ripa_rtc_int_pend : 1; + bdrkreg_t ripa_rsvd : 63; + } pi_rt_int_pend_a_fld_s; +} pi_rt_int_pend_a_u_t; + +#else + +typedef union pi_rt_int_pend_a_u { + bdrkreg_t pi_rt_int_pend_a_regval; + struct { + bdrkreg_t ripa_rsvd : 63; + bdrkreg_t ripa_rtc_int_pend : 1; + } pi_rt_int_pend_a_fld_s; +} pi_rt_int_pend_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. If the bit in the * + * corresponding RT_INT_EN_A/B register is set, the processor's level * + * 5 interrupt is set to the value of the RTC_INT_PEND bit in this * + * register. Storing any value to this location will clear the * + * RTC_INT_PEND bit in the register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_int_pend_b_u { + bdrkreg_t pi_rt_int_pend_b_regval; + struct { + bdrkreg_t ripb_rtc_int_pend : 1; + bdrkreg_t ripb_rsvd : 63; + } pi_rt_int_pend_b_fld_s; +} pi_rt_int_pend_b_u_t; + +#else + +typedef union pi_rt_int_pend_b_u { + bdrkreg_t pi_rt_int_pend_b_regval; + struct { + bdrkreg_t ripb_rsvd : 63; + bdrkreg_t ripb_rtc_int_pend : 1; + } pi_rt_int_pend_b_fld_s; +} pi_rt_int_pend_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Both registers are * + * set when the PROFILE_COMPARE register is equal to bits [31:0] of * + * the RT_Counter. If the bit in the corresponding PROF_INT_EN_A/B * + * register is set, the processor's level 5 interrupt is set to the * + * value of the PROF_INT_PEND bit in this register. Storing any value * + * to this location will clear the PROF_INT_PEND bit in the register. * + * The reason for having A and B versions of this register is that * + * they need to be cleared independently. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_prof_int_pend_a_u { + bdrkreg_t pi_prof_int_pend_a_regval; + struct { + bdrkreg_t pipa_prof_int_pend : 1; + bdrkreg_t pipa_rsvd : 63; + } pi_prof_int_pend_a_fld_s; +} pi_prof_int_pend_a_u_t; + +#else + +typedef union pi_prof_int_pend_a_u { + bdrkreg_t pi_prof_int_pend_a_regval; + struct { + bdrkreg_t pipa_rsvd : 63; + bdrkreg_t pipa_prof_int_pend : 1; + } pi_prof_int_pend_a_fld_s; +} pi_prof_int_pend_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Both registers are * + * set when the PROFILE_COMPARE register is equal to bits [31:0] of * + * the RT_Counter. If the bit in the corresponding PROF_INT_EN_A/B * + * register is set, the processor's level 5 interrupt is set to the * + * value of the PROF_INT_PEND bit in this register. Storing any value * + * to this location will clear the PROF_INT_PEND bit in the register. * + * The reason for having A and B versions of this register is that * + * they need to be cleared independently. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_prof_int_pend_b_u { + bdrkreg_t pi_prof_int_pend_b_regval; + struct { + bdrkreg_t pipb_prof_int_pend : 1; + bdrkreg_t pipb_rsvd : 63; + } pi_prof_int_pend_b_fld_s; +} pi_prof_int_pend_b_u_t; + +#else + +typedef union pi_prof_int_pend_b_u { + bdrkreg_t pi_prof_int_pend_b_regval; + struct { + bdrkreg_t pipb_rsvd : 63; + bdrkreg_t pipb_prof_int_pend : 1; + } pi_prof_int_pend_b_fld_s; +} pi_prof_int_pend_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Enables RTC * + * interrupt to the associated CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_int_en_a_u { + bdrkreg_t pi_rt_int_en_a_regval; + struct { + bdrkreg_t riea_rtc_int_en : 1; + bdrkreg_t riea_rsvd : 63; + } pi_rt_int_en_a_fld_s; +} pi_rt_int_en_a_u_t; + +#else + +typedef union pi_rt_int_en_a_u { + bdrkreg_t pi_rt_int_en_a_regval; + struct { + bdrkreg_t riea_rsvd : 63; + bdrkreg_t riea_rtc_int_en : 1; + } pi_rt_int_en_a_fld_s; +} pi_rt_int_en_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Enables RTC * + * interrupt to the associated CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_int_en_b_u { + bdrkreg_t pi_rt_int_en_b_regval; + struct { + bdrkreg_t rieb_rtc_int_en : 1; + bdrkreg_t rieb_rsvd : 63; + } pi_rt_int_en_b_fld_s; +} pi_rt_int_en_b_u_t; + +#else + +typedef union pi_rt_int_en_b_u { + bdrkreg_t pi_rt_int_en_b_regval; + struct { + bdrkreg_t rieb_rsvd : 63; + bdrkreg_t rieb_rtc_int_en : 1; + } pi_rt_int_en_b_fld_s; +} pi_rt_int_en_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Enables profiling * + * interrupt to the associated CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_prof_int_en_a_u { + bdrkreg_t pi_prof_int_en_a_regval; + struct { + bdrkreg_t piea_prof_int_en : 1; + bdrkreg_t piea_rsvd : 63; + } pi_prof_int_en_a_fld_s; +} pi_prof_int_en_a_u_t; + +#else + +typedef union pi_prof_int_en_a_u { + bdrkreg_t pi_prof_int_en_a_regval; + struct { + bdrkreg_t piea_rsvd : 63; + bdrkreg_t piea_prof_int_en : 1; + } pi_prof_int_en_a_fld_s; +} pi_prof_int_en_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. Enables profiling * + * interrupt to the associated CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_prof_int_en_b_u { + bdrkreg_t pi_prof_int_en_b_regval; + struct { + bdrkreg_t pieb_prof_int_en : 1; + bdrkreg_t pieb_rsvd : 63; + } pi_prof_int_en_b_fld_s; +} pi_prof_int_en_b_u_t; + +#else + +typedef union pi_prof_int_en_b_u { + bdrkreg_t pi_prof_int_en_b_regval; + struct { + bdrkreg_t pieb_rsvd : 63; + bdrkreg_t pieb_prof_int_en : 1; + } pi_prof_int_en_b_fld_s; +} pi_prof_int_en_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register controls operation of the debug data from the PI, * + * along with Debug_Sel[2:0] from the Debug module. For some values * + * of Debug_Sel[2:0], the B_SEL bit selects whether the debug bits * + * are looking at the processor A or processor B logic. The remaining * + * bits select which signal(s) are ORed to create DebugData bits 31 * + * and 30 for all of the PI debug selections. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_debug_sel_u { + bdrkreg_t pi_debug_sel_regval; + struct { + bdrkreg_t ds_low_t5cc_a : 1; + bdrkreg_t ds_low_t5cc_b : 1; + bdrkreg_t ds_low_totcc_a : 1; + bdrkreg_t ds_low_totcc_b : 1; + bdrkreg_t ds_low_reqcc_a : 1; + bdrkreg_t ds_low_reqcc_b : 1; + bdrkreg_t ds_low_rplcc_a : 1; + bdrkreg_t ds_low_rplcc_b : 1; + bdrkreg_t ds_low_intcc : 1; + bdrkreg_t ds_low_perf_inc_a_0 : 1; + bdrkreg_t ds_low_perf_inc_a_1 : 1; + bdrkreg_t ds_low_perf_inc_b_0 : 1; + bdrkreg_t ds_low_perf_inc_b_1 : 1; + bdrkreg_t ds_high_t5cc_a : 1; + bdrkreg_t ds_high_t5cc_b : 1; + bdrkreg_t ds_high_totcc_a : 1; + bdrkreg_t ds_high_totcc_b : 1; + bdrkreg_t ds_high_reqcc_a : 1; + bdrkreg_t ds_high_reqcc_b : 1; + bdrkreg_t ds_high_rplcc_a : 1; + bdrkreg_t ds_high_rplcc_b : 1; + bdrkreg_t ds_high_intcc : 1; + bdrkreg_t ds_high_perf_inc_a_0 : 1; + bdrkreg_t ds_high_perf_inc_a_1 : 1; + bdrkreg_t ds_high_perf_inc_b_0 : 1; + bdrkreg_t ds_high_perf_inc_b_1 : 1; + bdrkreg_t ds_b_sel : 1; + bdrkreg_t ds_rsvd : 37; + } pi_debug_sel_fld_s; +} pi_debug_sel_u_t; + +#else + +typedef union pi_debug_sel_u { + bdrkreg_t pi_debug_sel_regval; + struct { + bdrkreg_t ds_rsvd : 37; + bdrkreg_t ds_b_sel : 1; + bdrkreg_t ds_high_perf_inc_b_1 : 1; + bdrkreg_t ds_high_perf_inc_b_0 : 1; + bdrkreg_t ds_high_perf_inc_a_1 : 1; + bdrkreg_t ds_high_perf_inc_a_0 : 1; + bdrkreg_t ds_high_intcc : 1; + bdrkreg_t ds_high_rplcc_b : 1; + bdrkreg_t ds_high_rplcc_a : 1; + bdrkreg_t ds_high_reqcc_b : 1; + bdrkreg_t ds_high_reqcc_a : 1; + bdrkreg_t ds_high_totcc_b : 1; + bdrkreg_t ds_high_totcc_a : 1; + bdrkreg_t ds_high_t5cc_b : 1; + bdrkreg_t ds_high_t5cc_a : 1; + bdrkreg_t ds_low_perf_inc_b_1 : 1; + bdrkreg_t ds_low_perf_inc_b_0 : 1; + bdrkreg_t ds_low_perf_inc_a_1 : 1; + bdrkreg_t ds_low_perf_inc_a_0 : 1; + bdrkreg_t ds_low_intcc : 1; + bdrkreg_t ds_low_rplcc_b : 1; + bdrkreg_t ds_low_rplcc_a : 1; + bdrkreg_t ds_low_reqcc_b : 1; + bdrkreg_t ds_low_reqcc_a : 1; + bdrkreg_t ds_low_totcc_b : 1; + bdrkreg_t ds_low_totcc_a : 1; + bdrkreg_t ds_low_t5cc_b : 1; + bdrkreg_t ds_low_t5cc_a : 1; + } pi_debug_sel_fld_s; +} pi_debug_sel_u_t; + +#endif + + +/************************************************************************ + * * + * A write to this register allows a single bit in the INT_PEND0 or * + * INT_PEND1 registers to be set or cleared. If 6 is clear, a bit is * + * modified in INT_PEND0, while if 6 is set, a bit is modified in * + * INT_PEND1. The value in 5:0 (ranging from 63 to 0) will determine * + * which bit in the register is effected. The value of 8 will * + * determine whether the desired bit is set (8=1) or cleared (8=0). * + * This is the only register which is accessible by IO issued PWRI * + * command and is protected through the IO_PROTECT register. If the * + * region bit in the IO_PROTECT is not set then a WERR reply is * + * issued. CPU access is controlled through CPU_PROTECT. The contents * + * of this register are masked with the contents of INT_MASK_A * + * (INT_MASK_B) to determine whether an L2 interrupt is issued to * + * CPU_A (CPU_B). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_int_pend_mod_alias_u { + bdrkreg_t pi_int_pend_mod_alias_regval; + struct { + bdrkreg_t ipma_bit_select : 6; + bdrkreg_t ipma_reg_select : 1; + bdrkreg_t ipma_rsvd_1 : 1; + bdrkreg_t ipma_value : 1; + bdrkreg_t ipma_rsvd : 55; + } pi_int_pend_mod_alias_fld_s; +} pi_int_pend_mod_alias_u_t; + +#else + +typedef union pi_int_pend_mod_alias_u { + bdrkreg_t pi_int_pend_mod_alias_regval; + struct { + bdrkreg_t ipma_rsvd : 55; + bdrkreg_t ipma_value : 1; + bdrkreg_t ipma_rsvd_1 : 1; + bdrkreg_t ipma_reg_select : 1; + bdrkreg_t ipma_bit_select : 6; + } pi_int_pend_mod_alias_fld_s; +} pi_int_pend_mod_alias_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. This register * + * specifies the value of the Graphics Page. Uncached writes into the * + * Graphics Page (with uncached attribute of IO) are done with GFXWS * + * commands rather than the normal PWRI commands. GFXWS commands are * + * tracked with the graphics credit counters. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_page_a_u { + bdrkreg_t pi_gfx_page_a_regval; + struct { + bdrkreg_t gpa_rsvd_1 : 17; + bdrkreg_t gpa_gfx_page_addr : 23; + bdrkreg_t gpa_en_gfx_page : 1; + bdrkreg_t gpa_rsvd : 23; + } pi_gfx_page_a_fld_s; +} pi_gfx_page_a_u_t; + +#else + +typedef union pi_gfx_page_a_u { + bdrkreg_t pi_gfx_page_a_regval; + struct { + bdrkreg_t gpa_rsvd : 23; + bdrkreg_t gpa_en_gfx_page : 1; + bdrkreg_t gpa_gfx_page_addr : 23; + bdrkreg_t gpa_rsvd_1 : 17; + } pi_gfx_page_a_fld_s; +} pi_gfx_page_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. This register * + * counts graphics credits. This counter is decremented for each * + * doubleword sent to graphics with GFXWS or GFXWL commands. It is * + * incremented for each doubleword acknowledge from graphics. When * + * this counter has a smaller value than the GFX_BIAS register, * + * SysWrRdy_L is deasserted, an interrupt is sent to the processor, * + * and SysWrRdy_L is allowed to be asserted again. This is the basic * + * mechanism for flow-controlling graphics writes. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_credit_cntr_a_u { + bdrkreg_t pi_gfx_credit_cntr_a_regval; + struct { + bdrkreg_t gcca_gfx_credit_cntr : 12; + bdrkreg_t gcca_rsvd : 52; + } pi_gfx_credit_cntr_a_fld_s; +} pi_gfx_credit_cntr_a_u_t; + +#else + +typedef union pi_gfx_credit_cntr_a_u { + bdrkreg_t pi_gfx_credit_cntr_a_regval; + struct { + bdrkreg_t gcca_rsvd : 52; + bdrkreg_t gcca_gfx_credit_cntr : 12; + } pi_gfx_credit_cntr_a_fld_s; +} pi_gfx_credit_cntr_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. When the graphics * + * credit counter is less than or equal to this value, a flow control * + * interrupt is sent. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_bias_a_u { + bdrkreg_t pi_gfx_bias_a_regval; + struct { + bdrkreg_t gba_gfx_bias : 12; + bdrkreg_t gba_rsvd : 52; + } pi_gfx_bias_a_fld_s; +} pi_gfx_bias_a_u_t; + +#else + +typedef union pi_gfx_bias_a_u { + bdrkreg_t pi_gfx_bias_a_regval; + struct { + bdrkreg_t gba_rsvd : 52; + bdrkreg_t gba_gfx_bias : 12; + } pi_gfx_bias_a_fld_s; +} pi_gfx_bias_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There is one of these registers for each CPU. When * + * this counter reaches the value of the GFX_INT_CMP register, an * + * interrupt is sent to the associated processor. At each clock * + * cycle, the value in this register can be changed by any one of the * + * following actions: * + * - Written by software. * + * - Loaded with the value of GFX_INT_CMP, when an interrupt, NMI, or * + * soft reset occurs, thus preventing an additional interrupt. * + * - Zeroed, when the GFX_CREDIT_CNTR rises above the bias value. * + * - Incremented (by one at each clock) for each clock that the * + * GFX_CREDIT_CNTR is less than or equal to zero. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_int_cntr_a_u { + bdrkreg_t pi_gfx_int_cntr_a_regval; + struct { + bdrkreg_t gica_gfx_int_cntr : 26; + bdrkreg_t gica_rsvd : 38; + } pi_gfx_int_cntr_a_fld_s; +} pi_gfx_int_cntr_a_u_t; + +#else + +typedef union pi_gfx_int_cntr_a_u { + bdrkreg_t pi_gfx_int_cntr_a_regval; + struct { + bdrkreg_t gica_rsvd : 38; + bdrkreg_t gica_gfx_int_cntr : 26; + } pi_gfx_int_cntr_a_fld_s; +} pi_gfx_int_cntr_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. The value in this * + * register is loaded into the GFX_INT_CNTR register when an * + * interrupt, NMI, or soft reset is sent to the processor. The value * + * in this register is compared to the value of GFX_INT_CNTR and an * + * interrupt is sent when they become equal. * + * * + ************************************************************************/ + + + + +#ifdef LINUX + +typedef union pi_gfx_int_cmp_a_u { + bdrkreg_t pi_gfx_int_cmp_a_regval; + struct { + bdrkreg_t gica_gfx_int_cmp : 26; + bdrkreg_t gica_rsvd : 38; + } pi_gfx_int_cmp_a_fld_s; +} pi_gfx_int_cmp_a_u_t; + +#else + +typedef union pi_gfx_int_cmp_a_u { + bdrkreg_t pi_gfx_int_cmp_a_regval; + struct { + bdrkreg_t gica_rsvd : 38; + bdrkreg_t gica_gfx_int_cmp : 26; + } pi_gfx_int_cmp_a_fld_s; +} pi_gfx_int_cmp_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. This register * + * specifies the value of the Graphics Page. Uncached writes into the * + * Graphics Page (with uncached attribute of IO) are done with GFXWS * + * commands rather than the normal PWRI commands. GFXWS commands are * + * tracked with the graphics credit counters. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_page_b_u { + bdrkreg_t pi_gfx_page_b_regval; + struct { + bdrkreg_t gpb_rsvd_1 : 17; + bdrkreg_t gpb_gfx_page_addr : 23; + bdrkreg_t gpb_en_gfx_page : 1; + bdrkreg_t gpb_rsvd : 23; + } pi_gfx_page_b_fld_s; +} pi_gfx_page_b_u_t; + +#else + +typedef union pi_gfx_page_b_u { + bdrkreg_t pi_gfx_page_b_regval; + struct { + bdrkreg_t gpb_rsvd : 23; + bdrkreg_t gpb_en_gfx_page : 1; + bdrkreg_t gpb_gfx_page_addr : 23; + bdrkreg_t gpb_rsvd_1 : 17; + } pi_gfx_page_b_fld_s; +} pi_gfx_page_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. This register * + * counts graphics credits. This counter is decremented for each * + * doubleword sent to graphics with GFXWS or GFXWL commands. It is * + * incremented for each doubleword acknowledge from graphics. When * + * this counter has a smaller value than the GFX_BIAS register, * + * SysWrRdy_L is deasserted, an interrupt is sent to the processor, * + * and SysWrRdy_L is allowed to be asserted again. This is the basic * + * mechanism for flow-controlling graphics writes. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_credit_cntr_b_u { + bdrkreg_t pi_gfx_credit_cntr_b_regval; + struct { + bdrkreg_t gccb_gfx_credit_cntr : 12; + bdrkreg_t gccb_rsvd : 52; + } pi_gfx_credit_cntr_b_fld_s; +} pi_gfx_credit_cntr_b_u_t; + +#else + +typedef union pi_gfx_credit_cntr_b_u { + bdrkreg_t pi_gfx_credit_cntr_b_regval; + struct { + bdrkreg_t gccb_rsvd : 52; + bdrkreg_t gccb_gfx_credit_cntr : 12; + } pi_gfx_credit_cntr_b_fld_s; +} pi_gfx_credit_cntr_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. When the graphics * + * credit counter is less than or equal to this value, a flow control * + * interrupt is sent. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_bias_b_u { + bdrkreg_t pi_gfx_bias_b_regval; + struct { + bdrkreg_t gbb_gfx_bias : 12; + bdrkreg_t gbb_rsvd : 52; + } pi_gfx_bias_b_fld_s; +} pi_gfx_bias_b_u_t; + +#else + +typedef union pi_gfx_bias_b_u { + bdrkreg_t pi_gfx_bias_b_regval; + struct { + bdrkreg_t gbb_rsvd : 52; + bdrkreg_t gbb_gfx_bias : 12; + } pi_gfx_bias_b_fld_s; +} pi_gfx_bias_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There is one of these registers for each CPU. When * + * this counter reaches the value of the GFX_INT_CMP register, an * + * interrupt is sent to the associated processor. At each clock * + * cycle, the value in this register can be changed by any one of the * + * following actions: * + * - Written by software. * + * - Loaded with the value of GFX_INT_CMP, when an interrupt, NMI, or * + * soft reset occurs, thus preventing an additional interrupt. * + * - Zeroed, when the GFX_CREDIT_CNTR rises above the bias value. * + * - Incremented (by one at each clock) for each clock that the * + * GFX_CREDIT_CNTR is less than or equal to zero. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_int_cntr_b_u { + bdrkreg_t pi_gfx_int_cntr_b_regval; + struct { + bdrkreg_t gicb_gfx_int_cntr : 26; + bdrkreg_t gicb_rsvd : 38; + } pi_gfx_int_cntr_b_fld_s; +} pi_gfx_int_cntr_b_u_t; + +#else + +typedef union pi_gfx_int_cntr_b_u { + bdrkreg_t pi_gfx_int_cntr_b_regval; + struct { + bdrkreg_t gicb_rsvd : 38; + bdrkreg_t gicb_gfx_int_cntr : 26; + } pi_gfx_int_cntr_b_fld_s; +} pi_gfx_int_cntr_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. The value in this * + * register is loaded into the GFX_INT_CNTR register when an * + * interrupt, NMI, or soft reset is sent to the processor. The value * + * in this register is compared to the value of GFX_INT_CNTR and an * + * interrupt is sent when they become equal. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_int_cmp_b_u { + bdrkreg_t pi_gfx_int_cmp_b_regval; + struct { + bdrkreg_t gicb_gfx_int_cmp : 26; + bdrkreg_t gicb_rsvd : 38; + } pi_gfx_int_cmp_b_fld_s; +} pi_gfx_int_cmp_b_u_t; + +#else + +typedef union pi_gfx_int_cmp_b_u { + bdrkreg_t pi_gfx_int_cmp_b_regval; + struct { + bdrkreg_t gicb_rsvd : 38; + bdrkreg_t gicb_gfx_int_cmp : 26; + } pi_gfx_int_cmp_b_fld_s; +} pi_gfx_int_cmp_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: A read of this register returns all sources of * + * Bedrock Error Interrupts. Storing to the write-with-clear location * + * clears any bit for which a one appears on the data bus. Storing to * + * the writable location does a direct write to all unreserved bits * + * (except for MEM_UNC). * + * In Synergy mode, the processor that is the source of the command * + * that got an error is independent of the A or B SysAD bus. So in * + * Synergy mode, Synergy provides the source processor number in bit * + * 52 of the SysAD bus in all commands. The PI saves this in the RRB * + * or WRB entry, and uses that value to determine which error bit (A * + * or B) to set, as well as which ERR_STATUS and spool registers to * + * use, for all error types in this register that are specified as an * + * error to CPU_A or CPU_B. * + * This register is not cleared at reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_int_pend_wr_u { + bdrkreg_t pi_err_int_pend_wr_regval; + struct { + bdrkreg_t eipw_spool_comp_b : 1; + bdrkreg_t eipw_spool_comp_a : 1; + bdrkreg_t eipw_spurious_b : 1; + bdrkreg_t eipw_spurious_a : 1; + bdrkreg_t eipw_wrb_terr_b : 1; + bdrkreg_t eipw_wrb_terr_a : 1; + bdrkreg_t eipw_wrb_werr_b : 1; + bdrkreg_t eipw_wrb_werr_a : 1; + bdrkreg_t eipw_sysstate_par_b : 1; + bdrkreg_t eipw_sysstate_par_a : 1; + bdrkreg_t eipw_sysad_data_ecc_b : 1; + bdrkreg_t eipw_sysad_data_ecc_a : 1; + bdrkreg_t eipw_sysad_addr_ecc_b : 1; + bdrkreg_t eipw_sysad_addr_ecc_a : 1; + bdrkreg_t eipw_syscmd_data_par_b : 1; + bdrkreg_t eipw_syscmd_data_par_a : 1; + bdrkreg_t eipw_syscmd_addr_par_b : 1; + bdrkreg_t eipw_syscmd_addr_par_a : 1; + bdrkreg_t eipw_spool_err_b : 1; + bdrkreg_t eipw_spool_err_a : 1; + bdrkreg_t eipw_ue_uncached_b : 1; + bdrkreg_t eipw_ue_uncached_a : 1; + bdrkreg_t eipw_sysstate_tag_b : 1; + bdrkreg_t eipw_sysstate_tag_a : 1; + bdrkreg_t eipw_mem_unc : 1; + bdrkreg_t eipw_sysad_bad_data_b : 1; + bdrkreg_t eipw_sysad_bad_data_a : 1; + bdrkreg_t eipw_ue_cached_b : 1; + bdrkreg_t eipw_ue_cached_a : 1; + bdrkreg_t eipw_pkt_len_err_b : 1; + bdrkreg_t eipw_pkt_len_err_a : 1; + bdrkreg_t eipw_irb_err_b : 1; + bdrkreg_t eipw_irb_err_a : 1; + bdrkreg_t eipw_irb_timeout_b : 1; + bdrkreg_t eipw_irb_timeout_a : 1; + bdrkreg_t eipw_rsvd : 29; + } pi_err_int_pend_wr_fld_s; +} pi_err_int_pend_wr_u_t; + +#else + +typedef union pi_err_int_pend_wr_u { + bdrkreg_t pi_err_int_pend_wr_regval; + struct { + bdrkreg_t eipw_rsvd : 29; + bdrkreg_t eipw_irb_timeout_a : 1; + bdrkreg_t eipw_irb_timeout_b : 1; + bdrkreg_t eipw_irb_err_a : 1; + bdrkreg_t eipw_irb_err_b : 1; + bdrkreg_t eipw_pkt_len_err_a : 1; + bdrkreg_t eipw_pkt_len_err_b : 1; + bdrkreg_t eipw_ue_cached_a : 1; + bdrkreg_t eipw_ue_cached_b : 1; + bdrkreg_t eipw_sysad_bad_data_a : 1; + bdrkreg_t eipw_sysad_bad_data_b : 1; + bdrkreg_t eipw_mem_unc : 1; + bdrkreg_t eipw_sysstate_tag_a : 1; + bdrkreg_t eipw_sysstate_tag_b : 1; + bdrkreg_t eipw_ue_uncached_a : 1; + bdrkreg_t eipw_ue_uncached_b : 1; + bdrkreg_t eipw_spool_err_a : 1; + bdrkreg_t eipw_spool_err_b : 1; + bdrkreg_t eipw_syscmd_addr_par_a : 1; + bdrkreg_t eipw_syscmd_addr_par_b : 1; + bdrkreg_t eipw_syscmd_data_par_a : 1; + bdrkreg_t eipw_syscmd_data_par_b : 1; + bdrkreg_t eipw_sysad_addr_ecc_a : 1; + bdrkreg_t eipw_sysad_addr_ecc_b : 1; + bdrkreg_t eipw_sysad_data_ecc_a : 1; + bdrkreg_t eipw_sysad_data_ecc_b : 1; + bdrkreg_t eipw_sysstate_par_a : 1; + bdrkreg_t eipw_sysstate_par_b : 1; + bdrkreg_t eipw_wrb_werr_a : 1; + bdrkreg_t eipw_wrb_werr_b : 1; + bdrkreg_t eipw_wrb_terr_a : 1; + bdrkreg_t eipw_wrb_terr_b : 1; + bdrkreg_t eipw_spurious_a : 1; + bdrkreg_t eipw_spurious_b : 1; + bdrkreg_t eipw_spool_comp_a : 1; + bdrkreg_t eipw_spool_comp_b : 1; + } pi_err_int_pend_wr_fld_s; +} pi_err_int_pend_wr_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: A read of this register returns all sources of * + * Bedrock Error Interrupts. Storing to the write-with-clear location * + * clears any bit for which a one appears on the data bus. Storing to * + * the writable location does a direct write to all unreserved bits * + * (except for MEM_UNC). * + * In Synergy mode, the processor that is the source of the command * + * that got an error is independent of the A or B SysAD bus. So in * + * Synergy mode, Synergy provides the source processor number in bit * + * 52 of the SysAD bus in all commands. The PI saves this in the RRB * + * or WRB entry, and uses that value to determine which error bit (A * + * or B) to set, as well as which ERR_STATUS and spool registers to * + * use, for all error types in this register that are specified as an * + * error to CPU_A or CPU_B. * + * This register is not cleared at reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_int_pend_u { + bdrkreg_t pi_err_int_pend_regval; + struct { + bdrkreg_t eip_spool_comp_b : 1; + bdrkreg_t eip_spool_comp_a : 1; + bdrkreg_t eip_spurious_b : 1; + bdrkreg_t eip_spurious_a : 1; + bdrkreg_t eip_wrb_terr_b : 1; + bdrkreg_t eip_wrb_terr_a : 1; + bdrkreg_t eip_wrb_werr_b : 1; + bdrkreg_t eip_wrb_werr_a : 1; + bdrkreg_t eip_sysstate_par_b : 1; + bdrkreg_t eip_sysstate_par_a : 1; + bdrkreg_t eip_sysad_data_ecc_b : 1; + bdrkreg_t eip_sysad_data_ecc_a : 1; + bdrkreg_t eip_sysad_addr_ecc_b : 1; + bdrkreg_t eip_sysad_addr_ecc_a : 1; + bdrkreg_t eip_syscmd_data_par_b : 1; + bdrkreg_t eip_syscmd_data_par_a : 1; + bdrkreg_t eip_syscmd_addr_par_b : 1; + bdrkreg_t eip_syscmd_addr_par_a : 1; + bdrkreg_t eip_spool_err_b : 1; + bdrkreg_t eip_spool_err_a : 1; + bdrkreg_t eip_ue_uncached_b : 1; + bdrkreg_t eip_ue_uncached_a : 1; + bdrkreg_t eip_sysstate_tag_b : 1; + bdrkreg_t eip_sysstate_tag_a : 1; + bdrkreg_t eip_mem_unc : 1; + bdrkreg_t eip_sysad_bad_data_b : 1; + bdrkreg_t eip_sysad_bad_data_a : 1; + bdrkreg_t eip_ue_cached_b : 1; + bdrkreg_t eip_ue_cached_a : 1; + bdrkreg_t eip_pkt_len_err_b : 1; + bdrkreg_t eip_pkt_len_err_a : 1; + bdrkreg_t eip_irb_err_b : 1; + bdrkreg_t eip_irb_err_a : 1; + bdrkreg_t eip_irb_timeout_b : 1; + bdrkreg_t eip_irb_timeout_a : 1; + bdrkreg_t eip_rsvd : 29; + } pi_err_int_pend_fld_s; +} pi_err_int_pend_u_t; + +#else + +typedef union pi_err_int_pend_u { + bdrkreg_t pi_err_int_pend_regval; + struct { + bdrkreg_t eip_rsvd : 29; + bdrkreg_t eip_irb_timeout_a : 1; + bdrkreg_t eip_irb_timeout_b : 1; + bdrkreg_t eip_irb_err_a : 1; + bdrkreg_t eip_irb_err_b : 1; + bdrkreg_t eip_pkt_len_err_a : 1; + bdrkreg_t eip_pkt_len_err_b : 1; + bdrkreg_t eip_ue_cached_a : 1; + bdrkreg_t eip_ue_cached_b : 1; + bdrkreg_t eip_sysad_bad_data_a : 1; + bdrkreg_t eip_sysad_bad_data_b : 1; + bdrkreg_t eip_mem_unc : 1; + bdrkreg_t eip_sysstate_tag_a : 1; + bdrkreg_t eip_sysstate_tag_b : 1; + bdrkreg_t eip_ue_uncached_a : 1; + bdrkreg_t eip_ue_uncached_b : 1; + bdrkreg_t eip_spool_err_a : 1; + bdrkreg_t eip_spool_err_b : 1; + bdrkreg_t eip_syscmd_addr_par_a : 1; + bdrkreg_t eip_syscmd_addr_par_b : 1; + bdrkreg_t eip_syscmd_data_par_a : 1; + bdrkreg_t eip_syscmd_data_par_b : 1; + bdrkreg_t eip_sysad_addr_ecc_a : 1; + bdrkreg_t eip_sysad_addr_ecc_b : 1; + bdrkreg_t eip_sysad_data_ecc_a : 1; + bdrkreg_t eip_sysad_data_ecc_b : 1; + bdrkreg_t eip_sysstate_par_a : 1; + bdrkreg_t eip_sysstate_par_b : 1; + bdrkreg_t eip_wrb_werr_a : 1; + bdrkreg_t eip_wrb_werr_b : 1; + bdrkreg_t eip_wrb_terr_a : 1; + bdrkreg_t eip_wrb_terr_b : 1; + bdrkreg_t eip_spurious_a : 1; + bdrkreg_t eip_spurious_b : 1; + bdrkreg_t eip_spool_comp_a : 1; + bdrkreg_t eip_spool_comp_b : 1; + } pi_err_int_pend_fld_s; +} pi_err_int_pend_u_t; + +#endif + + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. This read/write * + * register masks the contents of ERR_INT_PEND to determine which * + * conditions cause a Level-6 interrupt to CPU_A or CPU_B. A bit set * + * allows the interrupt. Only one processor in a Bedrock should * + * enable the Memory/Directory Uncorrectable Error bit. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_int_mask_a_u { + bdrkreg_t pi_err_int_mask_a_regval; + struct { + bdrkreg_t eima_mask : 35; + bdrkreg_t eima_rsvd : 29; + } pi_err_int_mask_a_fld_s; +} pi_err_int_mask_a_u_t; + +#else + +typedef union pi_err_int_mask_a_u { + bdrkreg_t pi_err_int_mask_a_regval; + struct { + bdrkreg_t eima_rsvd : 29; + bdrkreg_t eima_mask : 35; + } pi_err_int_mask_a_fld_s; +} pi_err_int_mask_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. This read/write * + * register masks the contents of ERR_INT_PEND to determine which * + * conditions cause a Level-6 interrupt to CPU_A or CPU_B. A bit set * + * allows the interrupt. Only one processor in a Bedrock should * + * enable the Memory/Directory Uncorrectable Error bit. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_int_mask_b_u { + bdrkreg_t pi_err_int_mask_b_regval; + struct { + bdrkreg_t eimb_mask : 35; + bdrkreg_t eimb_rsvd : 29; + } pi_err_int_mask_b_fld_s; +} pi_err_int_mask_b_u_t; + +#else + +typedef union pi_err_int_mask_b_u { + bdrkreg_t pi_err_int_mask_b_regval; + struct { + bdrkreg_t eimb_rsvd : 29; + bdrkreg_t eimb_mask : 35; + } pi_err_int_mask_b_fld_s; +} pi_err_int_mask_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There is one of these registers for each CPU. This * + * register is the address of the next write to the error stack. This * + * register is incremented after each such write. Only the low N bits * + * are incremented, where N is defined by the size of the error stack * + * specified in the ERR_STACK_SIZE register. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_stack_addr_a_u { + bdrkreg_t pi_err_stack_addr_a_regval; + struct { + bdrkreg_t esaa_rsvd_1 : 3; + bdrkreg_t esaa_addr : 30; + bdrkreg_t esaa_rsvd : 31; + } pi_err_stack_addr_a_fld_s; +} pi_err_stack_addr_a_u_t; + +#else + +typedef union pi_err_stack_addr_a_u { + bdrkreg_t pi_err_stack_addr_a_regval; + struct { + bdrkreg_t esaa_rsvd : 31; + bdrkreg_t esaa_addr : 30; + bdrkreg_t esaa_rsvd_1 : 3; + } pi_err_stack_addr_a_fld_s; +} pi_err_stack_addr_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: There is one of these registers for each CPU. This * + * register is the address of the next write to the error stack. This * + * register is incremented after each such write. Only the low N bits * + * are incremented, where N is defined by the size of the error stack * + * specified in the ERR_STACK_SIZE register. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_stack_addr_b_u { + bdrkreg_t pi_err_stack_addr_b_regval; + struct { + bdrkreg_t esab_rsvd_1 : 3; + bdrkreg_t esab_addr : 30; + bdrkreg_t esab_rsvd : 31; + } pi_err_stack_addr_b_fld_s; +} pi_err_stack_addr_b_u_t; + +#else + +typedef union pi_err_stack_addr_b_u { + bdrkreg_t pi_err_stack_addr_b_regval; + struct { + bdrkreg_t esab_rsvd : 31; + bdrkreg_t esab_addr : 30; + bdrkreg_t esab_rsvd_1 : 3; + } pi_err_stack_addr_b_fld_s; +} pi_err_stack_addr_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: Sets the size (number of 64-bit entries) in the * + * error stack that is spooled to local memory when an error occurs. * + * Table16 defines the format of each entry in the spooled error * + * stack. * + * This register is not reset by a soft reset. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_stack_size_u { + bdrkreg_t pi_err_stack_size_regval; + struct { + bdrkreg_t ess_size : 4; + bdrkreg_t ess_rsvd : 60; + } pi_err_stack_size_fld_s; +} pi_err_stack_size_u_t; + +#else + +typedef union pi_err_stack_size_u { + bdrkreg_t pi_err_stack_size_regval; + struct { + bdrkreg_t ess_rsvd : 60; + bdrkreg_t ess_size : 4; + } pi_err_stack_size_fld_s; +} pi_err_stack_size_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_A and ERR_STATUS1_A registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status0_a_u { + bdrkreg_t pi_err_status0_a_regval; + struct { + bdrkreg_t esa_error_type : 3; + bdrkreg_t esa_proc_req_num : 3; + bdrkreg_t esa_supplemental : 11; + bdrkreg_t esa_cmd : 8; + bdrkreg_t esa_addr : 37; + bdrkreg_t esa_over_run : 1; + bdrkreg_t esa_valid : 1; + } pi_err_status0_a_fld_s; +} pi_err_status0_a_u_t; + +#else + +typedef union pi_err_status0_a_u { + bdrkreg_t pi_err_status0_a_regval; + struct { + bdrkreg_t esa_valid : 1; + bdrkreg_t esa_over_run : 1; + bdrkreg_t esa_addr : 37; + bdrkreg_t esa_cmd : 8; + bdrkreg_t esa_supplemental : 11; + bdrkreg_t esa_proc_req_num : 3; + bdrkreg_t esa_error_type : 3; + } pi_err_status0_a_fld_s; +} pi_err_status0_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_A and ERR_STATUS1_A registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status0_a_clr_u { + bdrkreg_t pi_err_status0_a_clr_regval; + struct { + bdrkreg_t esac_error_type : 3; + bdrkreg_t esac_proc_req_num : 3; + bdrkreg_t esac_supplemental : 11; + bdrkreg_t esac_cmd : 8; + bdrkreg_t esac_addr : 37; + bdrkreg_t esac_over_run : 1; + bdrkreg_t esac_valid : 1; + } pi_err_status0_a_clr_fld_s; +} pi_err_status0_a_clr_u_t; + +#else + +typedef union pi_err_status0_a_clr_u { + bdrkreg_t pi_err_status0_a_clr_regval; + struct { + bdrkreg_t esac_valid : 1; + bdrkreg_t esac_over_run : 1; + bdrkreg_t esac_addr : 37; + bdrkreg_t esac_cmd : 8; + bdrkreg_t esac_supplemental : 11; + bdrkreg_t esac_proc_req_num : 3; + bdrkreg_t esac_error_type : 3; + } pi_err_status0_a_clr_fld_s; +} pi_err_status0_a_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_A and ERR_STATUS1_A registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status1_a_u { + bdrkreg_t pi_err_status1_a_regval; + struct { + bdrkreg_t esa_spool_count : 21; + bdrkreg_t esa_time_out_count : 8; + bdrkreg_t esa_inval_count : 10; + bdrkreg_t esa_crb_num : 3; + bdrkreg_t esa_wrb : 1; + bdrkreg_t esa_e_bits : 2; + bdrkreg_t esa_t_bit : 1; + bdrkreg_t esa_i_bit : 1; + bdrkreg_t esa_h_bit : 1; + bdrkreg_t esa_w_bit : 1; + bdrkreg_t esa_a_bit : 1; + bdrkreg_t esa_r_bit : 1; + bdrkreg_t esa_v_bit : 1; + bdrkreg_t esa_p_bit : 1; + bdrkreg_t esa_source : 11; + } pi_err_status1_a_fld_s; +} pi_err_status1_a_u_t; + +#else + +typedef union pi_err_status1_a_u { + bdrkreg_t pi_err_status1_a_regval; + struct { + bdrkreg_t esa_source : 11; + bdrkreg_t esa_p_bit : 1; + bdrkreg_t esa_v_bit : 1; + bdrkreg_t esa_r_bit : 1; + bdrkreg_t esa_a_bit : 1; + bdrkreg_t esa_w_bit : 1; + bdrkreg_t esa_h_bit : 1; + bdrkreg_t esa_i_bit : 1; + bdrkreg_t esa_t_bit : 1; + bdrkreg_t esa_e_bits : 2; + bdrkreg_t esa_wrb : 1; + bdrkreg_t esa_crb_num : 3; + bdrkreg_t esa_inval_count : 10; + bdrkreg_t esa_time_out_count : 8; + bdrkreg_t esa_spool_count : 21; + } pi_err_status1_a_fld_s; +} pi_err_status1_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_A and ERR_STATUS1_A registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status1_a_clr_u { + bdrkreg_t pi_err_status1_a_clr_regval; + struct { + bdrkreg_t esac_spool_count : 21; + bdrkreg_t esac_time_out_count : 8; + bdrkreg_t esac_inval_count : 10; + bdrkreg_t esac_crb_num : 3; + bdrkreg_t esac_wrb : 1; + bdrkreg_t esac_e_bits : 2; + bdrkreg_t esac_t_bit : 1; + bdrkreg_t esac_i_bit : 1; + bdrkreg_t esac_h_bit : 1; + bdrkreg_t esac_w_bit : 1; + bdrkreg_t esac_a_bit : 1; + bdrkreg_t esac_r_bit : 1; + bdrkreg_t esac_v_bit : 1; + bdrkreg_t esac_p_bit : 1; + bdrkreg_t esac_source : 11; + } pi_err_status1_a_clr_fld_s; +} pi_err_status1_a_clr_u_t; + +#else + +typedef union pi_err_status1_a_clr_u { + bdrkreg_t pi_err_status1_a_clr_regval; + struct { + bdrkreg_t esac_source : 11; + bdrkreg_t esac_p_bit : 1; + bdrkreg_t esac_v_bit : 1; + bdrkreg_t esac_r_bit : 1; + bdrkreg_t esac_a_bit : 1; + bdrkreg_t esac_w_bit : 1; + bdrkreg_t esac_h_bit : 1; + bdrkreg_t esac_i_bit : 1; + bdrkreg_t esac_t_bit : 1; + bdrkreg_t esac_e_bits : 2; + bdrkreg_t esac_wrb : 1; + bdrkreg_t esac_crb_num : 3; + bdrkreg_t esac_inval_count : 10; + bdrkreg_t esac_time_out_count : 8; + bdrkreg_t esac_spool_count : 21; + } pi_err_status1_a_clr_fld_s; +} pi_err_status1_a_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_B and ERR_STATUS1_B registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status0_b_u { + bdrkreg_t pi_err_status0_b_regval; + struct { + bdrkreg_t esb_error_type : 3; + bdrkreg_t esb_proc_request_number : 3; + bdrkreg_t esb_supplemental : 11; + bdrkreg_t esb_cmd : 8; + bdrkreg_t esb_addr : 37; + bdrkreg_t esb_over_run : 1; + bdrkreg_t esb_valid : 1; + } pi_err_status0_b_fld_s; +} pi_err_status0_b_u_t; + +#else + +typedef union pi_err_status0_b_u { + bdrkreg_t pi_err_status0_b_regval; + struct { + bdrkreg_t esb_valid : 1; + bdrkreg_t esb_over_run : 1; + bdrkreg_t esb_addr : 37; + bdrkreg_t esb_cmd : 8; + bdrkreg_t esb_supplemental : 11; + bdrkreg_t esb_proc_request_number : 3; + bdrkreg_t esb_error_type : 3; + } pi_err_status0_b_fld_s; +} pi_err_status0_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_B and ERR_STATUS1_B registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status0_b_clr_u { + bdrkreg_t pi_err_status0_b_clr_regval; + struct { + bdrkreg_t esbc_error_type : 3; + bdrkreg_t esbc_proc_request_number : 3; + bdrkreg_t esbc_supplemental : 11; + bdrkreg_t esbc_cmd : 8; + bdrkreg_t esbc_addr : 37; + bdrkreg_t esbc_over_run : 1; + bdrkreg_t esbc_valid : 1; + } pi_err_status0_b_clr_fld_s; +} pi_err_status0_b_clr_u_t; + +#else + +typedef union pi_err_status0_b_clr_u { + bdrkreg_t pi_err_status0_b_clr_regval; + struct { + bdrkreg_t esbc_valid : 1; + bdrkreg_t esbc_over_run : 1; + bdrkreg_t esbc_addr : 37; + bdrkreg_t esbc_cmd : 8; + bdrkreg_t esbc_supplemental : 11; + bdrkreg_t esbc_proc_request_number : 3; + bdrkreg_t esbc_error_type : 3; + } pi_err_status0_b_clr_fld_s; +} pi_err_status0_b_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_B and ERR_STATUS1_B registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status1_b_u { + bdrkreg_t pi_err_status1_b_regval; + struct { + bdrkreg_t esb_spool_count : 21; + bdrkreg_t esb_time_out_count : 8; + bdrkreg_t esb_inval_count : 10; + bdrkreg_t esb_crb_num : 3; + bdrkreg_t esb_wrb : 1; + bdrkreg_t esb_e_bits : 2; + bdrkreg_t esb_t_bit : 1; + bdrkreg_t esb_i_bit : 1; + bdrkreg_t esb_h_bit : 1; + bdrkreg_t esb_w_bit : 1; + bdrkreg_t esb_a_bit : 1; + bdrkreg_t esb_r_bit : 1; + bdrkreg_t esb_v_bit : 1; + bdrkreg_t esb_p_bit : 1; + bdrkreg_t esb_source : 11; + } pi_err_status1_b_fld_s; +} pi_err_status1_b_u_t; + +#else + +typedef union pi_err_status1_b_u { + bdrkreg_t pi_err_status1_b_regval; + struct { + bdrkreg_t esb_source : 11; + bdrkreg_t esb_p_bit : 1; + bdrkreg_t esb_v_bit : 1; + bdrkreg_t esb_r_bit : 1; + bdrkreg_t esb_a_bit : 1; + bdrkreg_t esb_w_bit : 1; + bdrkreg_t esb_h_bit : 1; + bdrkreg_t esb_i_bit : 1; + bdrkreg_t esb_t_bit : 1; + bdrkreg_t esb_e_bits : 2; + bdrkreg_t esb_wrb : 1; + bdrkreg_t esb_crb_num : 3; + bdrkreg_t esb_inval_count : 10; + bdrkreg_t esb_time_out_count : 8; + bdrkreg_t esb_spool_count : 21; + } pi_err_status1_b_fld_s; +} pi_err_status1_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. Writing this register with * + * the Write-clear address (with any data) clears both the * + * ERR_STATUS0_B and ERR_STATUS1_B registers. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_status1_b_clr_u { + bdrkreg_t pi_err_status1_b_clr_regval; + struct { + bdrkreg_t esbc_spool_count : 21; + bdrkreg_t esbc_time_out_count : 8; + bdrkreg_t esbc_inval_count : 10; + bdrkreg_t esbc_crb_num : 3; + bdrkreg_t esbc_wrb : 1; + bdrkreg_t esbc_e_bits : 2; + bdrkreg_t esbc_t_bit : 1; + bdrkreg_t esbc_i_bit : 1; + bdrkreg_t esbc_h_bit : 1; + bdrkreg_t esbc_w_bit : 1; + bdrkreg_t esbc_a_bit : 1; + bdrkreg_t esbc_r_bit : 1; + bdrkreg_t esbc_v_bit : 1; + bdrkreg_t esbc_p_bit : 1; + bdrkreg_t esbc_source : 11; + } pi_err_status1_b_clr_fld_s; +} pi_err_status1_b_clr_u_t; + +#else + +typedef union pi_err_status1_b_clr_u { + bdrkreg_t pi_err_status1_b_clr_regval; + struct { + bdrkreg_t esbc_source : 11; + bdrkreg_t esbc_p_bit : 1; + bdrkreg_t esbc_v_bit : 1; + bdrkreg_t esbc_r_bit : 1; + bdrkreg_t esbc_a_bit : 1; + bdrkreg_t esbc_w_bit : 1; + bdrkreg_t esbc_h_bit : 1; + bdrkreg_t esbc_i_bit : 1; + bdrkreg_t esbc_t_bit : 1; + bdrkreg_t esbc_e_bits : 2; + bdrkreg_t esbc_wrb : 1; + bdrkreg_t esbc_crb_num : 3; + bdrkreg_t esbc_inval_count : 10; + bdrkreg_t esbc_time_out_count : 8; + bdrkreg_t esbc_spool_count : 21; + } pi_err_status1_b_clr_fld_s; +} pi_err_status1_b_clr_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_spool_cmp_a_u { + bdrkreg_t pi_spool_cmp_a_regval; + struct { + bdrkreg_t sca_compare : 20; + bdrkreg_t sca_rsvd : 44; + } pi_spool_cmp_a_fld_s; +} pi_spool_cmp_a_u_t; + +#else + +typedef union pi_spool_cmp_a_u { + bdrkreg_t pi_spool_cmp_a_regval; + struct { + bdrkreg_t sca_rsvd : 44; + bdrkreg_t sca_compare : 20; + } pi_spool_cmp_a_fld_s; +} pi_spool_cmp_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_spool_cmp_b_u { + bdrkreg_t pi_spool_cmp_b_regval; + struct { + bdrkreg_t scb_compare : 20; + bdrkreg_t scb_rsvd : 44; + } pi_spool_cmp_b_fld_s; +} pi_spool_cmp_b_u_t; + +#else + +typedef union pi_spool_cmp_b_u { + bdrkreg_t pi_spool_cmp_b_regval; + struct { + bdrkreg_t scb_rsvd : 44; + bdrkreg_t scb_compare : 20; + } pi_spool_cmp_b_fld_s; +} pi_spool_cmp_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. A timeout can be * + * forced by writing one(s). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_crb_timeout_a_u { + bdrkreg_t pi_crb_timeout_a_regval; + struct { + bdrkreg_t cta_rrb : 4; + bdrkreg_t cta_wrb : 8; + bdrkreg_t cta_rsvd : 52; + } pi_crb_timeout_a_fld_s; +} pi_crb_timeout_a_u_t; + +#else + +typedef union pi_crb_timeout_a_u { + bdrkreg_t pi_crb_timeout_a_regval; + struct { + bdrkreg_t cta_rsvd : 52; + bdrkreg_t cta_wrb : 8; + bdrkreg_t cta_rrb : 4; + } pi_crb_timeout_a_fld_s; +} pi_crb_timeout_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. A timeout can be * + * forced by writing one(s). * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_crb_timeout_b_u { + bdrkreg_t pi_crb_timeout_b_regval; + struct { + bdrkreg_t ctb_rrb : 4; + bdrkreg_t ctb_wrb : 8; + bdrkreg_t ctb_rsvd : 52; + } pi_crb_timeout_b_fld_s; +} pi_crb_timeout_b_u_t; + +#else + +typedef union pi_crb_timeout_b_u { + bdrkreg_t pi_crb_timeout_b_regval; + struct { + bdrkreg_t ctb_rsvd : 52; + bdrkreg_t ctb_wrb : 8; + bdrkreg_t ctb_rrb : 4; + } pi_crb_timeout_b_fld_s; +} pi_crb_timeout_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register controls error checking and forwarding of SysAD * + * errors. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_sysad_errchk_en_u { + bdrkreg_t pi_sysad_errchk_en_regval; + struct { + bdrkreg_t see_ecc_gen_en : 1; + bdrkreg_t see_qual_gen_en : 1; + bdrkreg_t see_sadp_chk_en : 1; + bdrkreg_t see_cmdp_chk_en : 1; + bdrkreg_t see_state_chk_en : 1; + bdrkreg_t see_qual_chk_en : 1; + bdrkreg_t see_rsvd : 58; + } pi_sysad_errchk_en_fld_s; +} pi_sysad_errchk_en_u_t; + +#else + +typedef union pi_sysad_errchk_en_u { + bdrkreg_t pi_sysad_errchk_en_regval; + struct { + bdrkreg_t see_rsvd : 58; + bdrkreg_t see_qual_chk_en : 1; + bdrkreg_t see_state_chk_en : 1; + bdrkreg_t see_cmdp_chk_en : 1; + bdrkreg_t see_sadp_chk_en : 1; + bdrkreg_t see_qual_gen_en : 1; + bdrkreg_t see_ecc_gen_en : 1; + } pi_sysad_errchk_en_fld_s; +} pi_sysad_errchk_en_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. If any bit in this * + * register is set, then whenever reply data arrives with the UE * + * (uncorrectable error) indication set, the check-bits that are * + * generated and sent to the SysAD will be inverted corresponding to * + * the bits set in the register. This will also prevent the assertion * + * of the data quality indicator. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_force_bad_check_bit_a_u { + bdrkreg_t pi_force_bad_check_bit_a_regval; + struct { + bdrkreg_t fbcba_bad_check_bit : 8; + bdrkreg_t fbcba_rsvd : 56; + } pi_force_bad_check_bit_a_fld_s; +} pi_force_bad_check_bit_a_u_t; + +#else + +typedef union pi_force_bad_check_bit_a_u { + bdrkreg_t pi_force_bad_check_bit_a_regval; + struct { + bdrkreg_t fbcba_rsvd : 56; + bdrkreg_t fbcba_bad_check_bit : 8; + } pi_force_bad_check_bit_a_fld_s; +} pi_force_bad_check_bit_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. If any bit in this * + * register is set, then whenever reply data arrives with the UE * + * (uncorrectable error) indication set, the check-bits that are * + * generated and sent to the SysAD will be inverted corresponding to * + * the bits set in the register. This will also prevent the assertion * + * of the data quality indicator. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_force_bad_check_bit_b_u { + bdrkreg_t pi_force_bad_check_bit_b_regval; + struct { + bdrkreg_t fbcbb_bad_check_bit : 8; + bdrkreg_t fbcbb_rsvd : 56; + } pi_force_bad_check_bit_b_fld_s; +} pi_force_bad_check_bit_b_u_t; + +#else + +typedef union pi_force_bad_check_bit_b_u { + bdrkreg_t pi_force_bad_check_bit_b_regval; + struct { + bdrkreg_t fbcbb_rsvd : 56; + bdrkreg_t fbcbb_bad_check_bit : 8; + } pi_force_bad_check_bit_b_fld_s; +} pi_force_bad_check_bit_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. When a counter is * + * enabled, it increments each time a DNACK reply is received. The * + * counter is cleared when any other reply is received. The register * + * is cleared when the CNT_EN bit is zero. If a DNACK reply is * + * received when the counter equals the value in the NACK_CMP * + * register, the counter is cleared, an error response is sent to the * + * CPU instead of a nack response, and the NACK_INT_A/B bit is set in * + * INT_PEND1. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_nack_cnt_a_u { + bdrkreg_t pi_nack_cnt_a_regval; + struct { + bdrkreg_t nca_nack_cnt : 20; + bdrkreg_t nca_cnt_en : 1; + bdrkreg_t nca_rsvd : 43; + } pi_nack_cnt_a_fld_s; +} pi_nack_cnt_a_u_t; + +#else + +typedef union pi_nack_cnt_a_u { + bdrkreg_t pi_nack_cnt_a_regval; + struct { + bdrkreg_t nca_rsvd : 43; + bdrkreg_t nca_cnt_en : 1; + bdrkreg_t nca_nack_cnt : 20; + } pi_nack_cnt_a_fld_s; +} pi_nack_cnt_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * There is one of these registers for each CPU. When a counter is * + * enabled, it increments each time a DNACK reply is received. The * + * counter is cleared when any other reply is received. The register * + * is cleared when the CNT_EN bit is zero. If a DNACK reply is * + * received when the counter equals the value in the NACK_CMP * + * register, the counter is cleared, an error response is sent to the * + * CPU instead of a nack response, and the NACK_INT_A/B bit is set in * + * INT_PEND1. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_nack_cnt_b_u { + bdrkreg_t pi_nack_cnt_b_regval; + struct { + bdrkreg_t ncb_nack_cnt : 20; + bdrkreg_t ncb_cnt_en : 1; + bdrkreg_t ncb_rsvd : 43; + } pi_nack_cnt_b_fld_s; +} pi_nack_cnt_b_u_t; + +#else + +typedef union pi_nack_cnt_b_u { + bdrkreg_t pi_nack_cnt_b_regval; + struct { + bdrkreg_t ncb_rsvd : 43; + bdrkreg_t ncb_cnt_en : 1; + bdrkreg_t ncb_nack_cnt : 20; + } pi_nack_cnt_b_fld_s; +} pi_nack_cnt_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * The setting of this register affects both CPUs on this PI. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_nack_cmp_u { + bdrkreg_t pi_nack_cmp_regval; + struct { + bdrkreg_t nc_nack_cmp : 20; + bdrkreg_t nc_rsvd : 44; + } pi_nack_cmp_fld_s; +} pi_nack_cmp_u_t; + +#else + +typedef union pi_nack_cmp_u { + bdrkreg_t pi_nack_cmp_regval; + struct { + bdrkreg_t nc_rsvd : 44; + bdrkreg_t nc_nack_cmp : 20; + } pi_nack_cmp_fld_s; +} pi_nack_cmp_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register controls which errors are spooled. When a bit in * + * this register is set, the corresponding error is spooled. The * + * setting of this register affects both CPUs on this PI. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_spool_mask_u { + bdrkreg_t pi_spool_mask_regval; + struct { + bdrkreg_t sm_access_err : 1; + bdrkreg_t sm_uncached_err : 1; + bdrkreg_t sm_dir_err : 1; + bdrkreg_t sm_timeout_err : 1; + bdrkreg_t sm_poison_err : 1; + bdrkreg_t sm_nack_oflow_err : 1; + bdrkreg_t sm_rsvd : 58; + } pi_spool_mask_fld_s; +} pi_spool_mask_u_t; + +#else + +typedef union pi_spool_mask_u { + bdrkreg_t pi_spool_mask_regval; + struct { + bdrkreg_t sm_rsvd : 58; + bdrkreg_t sm_nack_oflow_err : 1; + bdrkreg_t sm_poison_err : 1; + bdrkreg_t sm_timeout_err : 1; + bdrkreg_t sm_dir_err : 1; + bdrkreg_t sm_uncached_err : 1; + bdrkreg_t sm_access_err : 1; + } pi_spool_mask_fld_s; +} pi_spool_mask_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. When the VALID bit is * + * zero, this register (along with SPURIOUS_HDR_1) will capture the * + * header of an incoming spurious message received from the XBar. A * + * spurious message is a message that does not match up with any of * + * the CRB entries. This is a read/write register, so it is cleared * + * by writing of all zeros. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_spurious_hdr_0_u { + bdrkreg_t pi_spurious_hdr_0_regval; + struct { + bdrkreg_t sh0_prev_valid_b : 1; + bdrkreg_t sh0_prev_valid_a : 1; + bdrkreg_t sh0_rsvd : 4; + bdrkreg_t sh0_supplemental : 11; + bdrkreg_t sh0_cmd : 8; + bdrkreg_t sh0_addr : 37; + bdrkreg_t sh0_tail : 1; + bdrkreg_t sh0_valid : 1; + } pi_spurious_hdr_0_fld_s; +} pi_spurious_hdr_0_u_t; + +#else + +typedef union pi_spurious_hdr_0_u { + bdrkreg_t pi_spurious_hdr_0_regval; + struct { + bdrkreg_t sh0_valid : 1; + bdrkreg_t sh0_tail : 1; + bdrkreg_t sh0_addr : 37; + bdrkreg_t sh0_cmd : 8; + bdrkreg_t sh0_supplemental : 11; + bdrkreg_t sh0_rsvd : 4; + bdrkreg_t sh0_prev_valid_a : 1; + bdrkreg_t sh0_prev_valid_b : 1; + } pi_spurious_hdr_0_fld_s; +} pi_spurious_hdr_0_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is not cleared at reset. When the VALID bit in * + * SPURIOUS_HDR_0 is zero, this register (along with SPURIOUS_HDR_0) * + * will capture the header of an incoming spurious message received * + * from the XBar. A spurious message is a message that does not match * + * up with any of the CRB entries. This is a read/write register, so * + * it is cleared by writing of all zeros. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_spurious_hdr_1_u { + bdrkreg_t pi_spurious_hdr_1_regval; + struct { + bdrkreg_t sh1_rsvd : 53; + bdrkreg_t sh1_source : 11; + } pi_spurious_hdr_1_fld_s; +} pi_spurious_hdr_1_u_t; + +#else + +typedef union pi_spurious_hdr_1_u { + bdrkreg_t pi_spurious_hdr_1_regval; + struct { + bdrkreg_t sh1_source : 11; + bdrkreg_t sh1_rsvd : 53; + } pi_spurious_hdr_1_fld_s; +} pi_spurious_hdr_1_u_t; + +#endif + + + + +/************************************************************************ + * * + * Description: This register controls the injection of errors in * + * outbound SysAD transfers. When a write sets a bit in this * + * register, the PI logic is "armed" to inject that error. At the * + * first transfer of the specified type, the error is injected and * + * the bit in this register is cleared. Writing to this register does * + * not cause a transaction to occur. A bit in this register will * + * remain set until a transaction of the specified type occurs as a * + * result of normal system activity. This register can be polled to * + * determine if an error has been injected or is still "armed". * + * This register does not control injection of data quality bad * + * indicator on a data cycle. This type of error can be created by * + * reading from a memory location that has an uncorrectable ECC * + * error. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_err_inject_u { + bdrkreg_t pi_err_inject_regval; + struct { + bdrkreg_t ei_cmd_syscmd_par_a : 1; + bdrkreg_t ei_data_syscmd_par_a : 1; + bdrkreg_t ei_cmd_sysad_corecc_a : 1; + bdrkreg_t ei_data_sysad_corecc_a : 1; + bdrkreg_t ei_cmd_sysad_uncecc_a : 1; + bdrkreg_t ei_data_sysad_uncecc_a : 1; + bdrkreg_t ei_sysresp_par_a : 1; + bdrkreg_t ei_reserved_1 : 25; + bdrkreg_t ei_cmd_syscmd_par_b : 1; + bdrkreg_t ei_data_syscmd_par_b : 1; + bdrkreg_t ei_cmd_sysad_corecc_b : 1; + bdrkreg_t ei_data_sysad_corecc_b : 1; + bdrkreg_t ei_cmd_sysad_uncecc_b : 1; + bdrkreg_t ei_data_sysad_uncecc_b : 1; + bdrkreg_t ei_sysresp_par_b : 1; + bdrkreg_t ei_reserved : 25; + } pi_err_inject_fld_s; +} pi_err_inject_u_t; + +#else + +typedef union pi_err_inject_u { + bdrkreg_t pi_err_inject_regval; + struct { + bdrkreg_t ei_reserved : 25; + bdrkreg_t ei_sysresp_par_b : 1; + bdrkreg_t ei_data_sysad_uncecc_b : 1; + bdrkreg_t ei_cmd_sysad_uncecc_b : 1; + bdrkreg_t ei_data_sysad_corecc_b : 1; + bdrkreg_t ei_cmd_sysad_corecc_b : 1; + bdrkreg_t ei_data_syscmd_par_b : 1; + bdrkreg_t ei_cmd_syscmd_par_b : 1; + bdrkreg_t ei_reserved_1 : 25; + bdrkreg_t ei_sysresp_par_a : 1; + bdrkreg_t ei_data_sysad_uncecc_a : 1; + bdrkreg_t ei_cmd_sysad_uncecc_a : 1; + bdrkreg_t ei_data_sysad_corecc_a : 1; + bdrkreg_t ei_cmd_sysad_corecc_a : 1; + bdrkreg_t ei_data_syscmd_par_a : 1; + bdrkreg_t ei_cmd_syscmd_par_a : 1; + } pi_err_inject_fld_s; +} pi_err_inject_u_t; + +#endif + + + + +/************************************************************************ + * * + * This Read/Write location determines at what point the TRex+ is * + * stopped from issuing requests, based on the number of entries in * + * the incoming reply FIFO. When the number of entries in the Reply * + * FIFO is greater than the value of this register, the PI will * + * deassert both SysWrRdy and SysRdRdy to both processors. The Reply * + * FIFO has a depth of 0x3F entries, so setting this register to 0x3F * + * effectively disables this feature, allowing requests to be issued * + * always. Setting this register to 0x00 effectively lowers the * + * TRex+'s priority below the reply FIFO, disabling TRex+ requests * + * any time there is an entry waiting in the incoming FIFO.This * + * register is in its own 64KB page so that it can be mapped to user * + * space. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_reply_level_u { + bdrkreg_t pi_reply_level_regval; + struct { + bdrkreg_t rl_reply_level : 6; + bdrkreg_t rl_rsvd : 58; + } pi_reply_level_fld_s; +} pi_reply_level_u_t; + +#else + +typedef union pi_reply_level_u { + bdrkreg_t pi_reply_level_regval; + struct { + bdrkreg_t rl_rsvd : 58; + bdrkreg_t rl_reply_level : 6; + } pi_reply_level_fld_s; +} pi_reply_level_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register is used to change the graphics credit counter * + * operation from "Doubleword" mode to "Transaction" mode. This * + * register is in its own 64KB page so that it can be mapped to user * + * space. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_gfx_credit_mode_u { + bdrkreg_t pi_gfx_credit_mode_regval; + struct { + bdrkreg_t gcm_trans_mode : 1; + bdrkreg_t gcm_rsvd : 63; + } pi_gfx_credit_mode_fld_s; +} pi_gfx_credit_mode_u_t; + +#else + +typedef union pi_gfx_credit_mode_u { + bdrkreg_t pi_gfx_credit_mode_regval; + struct { + bdrkreg_t gcm_rsvd : 63; + bdrkreg_t gcm_trans_mode : 1; + } pi_gfx_credit_mode_fld_s; +} pi_gfx_credit_mode_u_t; + +#endif + + + +/************************************************************************ + * * + * This location contains a 55-bit read/write counter that wraps to * + * zero when the maximum value is reached. This counter is * + * incremented at each rising edge of the global clock (GCLK). This * + * register is in its own 64KB page so that it can be mapped to user * + * space. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_rt_counter_u { + bdrkreg_t pi_rt_counter_regval; + struct { + bdrkreg_t rc_count : 55; + bdrkreg_t rc_rsvd : 9; + } pi_rt_counter_fld_s; +} pi_rt_counter_u_t; + +#else + +typedef union pi_rt_counter_u { + bdrkreg_t pi_rt_counter_regval; + struct { + bdrkreg_t rc_rsvd : 9; + bdrkreg_t rc_count : 55; + } pi_rt_counter_fld_s; +} pi_rt_counter_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register controls the performance counters for one CPU. * + * There are two counters for each CPU. Each counter can be * + * configured to count a variety of events. The performance counter * + * registers for each processor are in their own 64KB page so that * + * they can be mapped to user space. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_perf_cntl_a_u { + bdrkreg_t pi_perf_cntl_a_regval; + struct { + bdrkreg_t pca_cntr_0_select : 28; + bdrkreg_t pca_cntr_0_mode : 3; + bdrkreg_t pca_cntr_0_enable : 1; + bdrkreg_t pca_cntr_1_select : 28; + bdrkreg_t pca_cntr_1_mode : 3; + bdrkreg_t pca_cntr_1_enable : 1; + } pi_perf_cntl_a_fld_s; +} pi_perf_cntl_a_u_t; + +#else + +typedef union pi_perf_cntl_a_u { + bdrkreg_t pi_perf_cntl_a_regval; + struct { + bdrkreg_t pca_cntr_1_enable : 1; + bdrkreg_t pca_cntr_1_mode : 3; + bdrkreg_t pca_cntr_1_select : 28; + bdrkreg_t pca_cntr_0_enable : 1; + bdrkreg_t pca_cntr_0_mode : 3; + bdrkreg_t pca_cntr_0_select : 28; + } pi_perf_cntl_a_fld_s; +} pi_perf_cntl_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register accesses the performance counter 0 for each CPU. * + * Each performance counter is 40-bits wide. On overflow, It wraps to * + * zero, sets the overflow bit in this register, and sets the * + * PERF_CNTR_OFLOW bit in the INT_PEND1 register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_perf_cntr0_a_u { + bdrkreg_t pi_perf_cntr0_a_regval; + struct { + bdrkreg_t pca_count_value : 40; + bdrkreg_t pca_overflow : 1; + bdrkreg_t pca_rsvd : 23; + } pi_perf_cntr0_a_fld_s; +} pi_perf_cntr0_a_u_t; + +#else + +typedef union pi_perf_cntr0_a_u { + bdrkreg_t pi_perf_cntr0_a_regval; + struct { + bdrkreg_t pca_rsvd : 23; + bdrkreg_t pca_overflow : 1; + bdrkreg_t pca_count_value : 40; + } pi_perf_cntr0_a_fld_s; +} pi_perf_cntr0_a_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register accesses the performance counter 1for each CPU. * + * Each performance counter is 40-bits wide. On overflow, It wraps to * + * zero, sets the overflow bit in this register, and sets the * + * PERF_CNTR_OFLOW bit in the INT_PEND1 register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_perf_cntr1_a_u { + bdrkreg_t pi_perf_cntr1_a_regval; + struct { + bdrkreg_t pca_count_value : 40; + bdrkreg_t pca_overflow : 1; + bdrkreg_t pca_rsvd : 23; + } pi_perf_cntr1_a_fld_s; +} pi_perf_cntr1_a_u_t; + +#else + +typedef union pi_perf_cntr1_a_u { + bdrkreg_t pi_perf_cntr1_a_regval; + struct { + bdrkreg_t pca_rsvd : 23; + bdrkreg_t pca_overflow : 1; + bdrkreg_t pca_count_value : 40; + } pi_perf_cntr1_a_fld_s; +} pi_perf_cntr1_a_u_t; + +#endif + + + + + +/************************************************************************ + * * + * This register controls the performance counters for one CPU. * + * There are two counters for each CPU. Each counter can be * + * configured to count a variety of events. The performance counter * + * registers for each processor are in their own 64KB page so that * + * they can be mapped to user space. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_perf_cntl_b_u { + bdrkreg_t pi_perf_cntl_b_regval; + struct { + bdrkreg_t pcb_cntr_0_select : 28; + bdrkreg_t pcb_cntr_0_mode : 3; + bdrkreg_t pcb_cntr_0_enable : 1; + bdrkreg_t pcb_cntr_1_select : 28; + bdrkreg_t pcb_cntr_1_mode : 3; + bdrkreg_t pcb_cntr_1_enable : 1; + } pi_perf_cntl_b_fld_s; +} pi_perf_cntl_b_u_t; + +#else + +typedef union pi_perf_cntl_b_u { + bdrkreg_t pi_perf_cntl_b_regval; + struct { + bdrkreg_t pcb_cntr_1_enable : 1; + bdrkreg_t pcb_cntr_1_mode : 3; + bdrkreg_t pcb_cntr_1_select : 28; + bdrkreg_t pcb_cntr_0_enable : 1; + bdrkreg_t pcb_cntr_0_mode : 3; + bdrkreg_t pcb_cntr_0_select : 28; + } pi_perf_cntl_b_fld_s; +} pi_perf_cntl_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register accesses the performance counter 0 for each CPU. * + * Each performance counter is 40-bits wide. On overflow, It wraps to * + * zero, sets the overflow bit in this register, and sets the * + * PERF_CNTR_OFLOW bit in the INT_PEND1 register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_perf_cntr0_b_u { + bdrkreg_t pi_perf_cntr0_b_regval; + struct { + bdrkreg_t pcb_count_value : 40; + bdrkreg_t pcb_overflow : 1; + bdrkreg_t pcb_rsvd : 23; + } pi_perf_cntr0_b_fld_s; +} pi_perf_cntr0_b_u_t; + +#else + +typedef union pi_perf_cntr0_b_u { + bdrkreg_t pi_perf_cntr0_b_regval; + struct { + bdrkreg_t pcb_rsvd : 23; + bdrkreg_t pcb_overflow : 1; + bdrkreg_t pcb_count_value : 40; + } pi_perf_cntr0_b_fld_s; +} pi_perf_cntr0_b_u_t; + +#endif + + + + +/************************************************************************ + * * + * This register accesses the performance counter 1for each CPU. * + * Each performance counter is 40-bits wide. On overflow, It wraps to * + * zero, sets the overflow bit in this register, and sets the * + * PERF_CNTR_OFLOW bit in the INT_PEND1 register. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union pi_perf_cntr1_b_u { + bdrkreg_t pi_perf_cntr1_b_regval; + struct { + bdrkreg_t pcb_count_value : 40; + bdrkreg_t pcb_overflow : 1; + bdrkreg_t pcb_rsvd : 23; + } pi_perf_cntr1_b_fld_s; +} pi_perf_cntr1_b_u_t; + +#else + +typedef union pi_perf_cntr1_b_u { + bdrkreg_t pi_perf_cntr1_b_regval; + struct { + bdrkreg_t pcb_rsvd : 23; + bdrkreg_t pcb_overflow : 1; + bdrkreg_t pcb_count_value : 40; + } pi_perf_cntr1_b_fld_s; +} pi_perf_cntr1_b_u_t; + +#endif + + + + + + +#endif /* _LANGUAGE_C */ + +/************************************************************************ + * * + * MAKE ALL ADDITIONS AFTER THIS LINE * + * * + ************************************************************************/ + + +#define PI_GFX_OFFSET (PI_GFX_PAGE_B - PI_GFX_PAGE_A) +#define PI_GFX_PAGE_ENABLE 0x0000010000000000LL + + +#endif /* _ASM_SN_SN1_HUBPI_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubpi_next.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubpi_next.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubpi_next.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubpi_next.h Wed Dec 6 21:56:15 2000 @@ -0,0 +1,332 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBPI_NEXT_H +#define _ASM_SN_SN1_HUBPI_NEXT_H + + +/* define for remote PI_1 space. It is always half of a node_addressspace + * from PI_0. The normal REMOTE_HUB space for PI registers access + * the PI_0 space, unless they are qualified by PI_1. + */ +#define PI_0(x) (x) +#define PI_1(x) ((x) + 0x200000) +#define PIREG(x,sn) ((sn) ? PI_1(x) : PI_0(x)) + +#define PI_MIN_STACK_SIZE 4096 /* For figuring out the size to set */ +#define PI_STACK_SIZE_SHFT 12 /* 4k */ + +#define PI_STACKADDR_OFFSET (PI_ERR_STACK_ADDR_B - PI_ERR_STACK_ADDR_A) +#define PI_ERRSTAT_OFFSET (PI_ERR_STATUS0_B - PI_ERR_STATUS0_A) +#define PI_RDCLR_OFFSET (PI_ERR_STATUS0_A_RCLR - PI_ERR_STATUS0_A) +/* these macros are correct, but fix their users to understand two PIs + and 4 CPUs (slices) per bedrock */ +#define PI_INT_MASK_OFFSET (PI_INT_MASK0_B - PI_INT_MASK0_A) +#define PI_INT_SET_OFFSET (PI_CC_PEND_CLR_B - PI_CC_PEND_CLR_A) +#define PI_NMI_OFFSET (PI_NMI_B - PI_NMI_A) + +#define ERR_STACK_SIZE_BYTES(_sz) \ + ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0) + +#define PI_CRB_STS_P (1 << 9) /* "P" (partial word read/write) bit */ +#define PI_CRB_STS_V (1 << 8) /* "V" (valid) bit */ +#define PI_CRB_STS_R (1 << 7) /* "R" (response data sent to CPU) */ +#define PI_CRB_STS_A (1 << 6) /* "A" (data ack. received) bit */ +#define PI_CRB_STS_W (1 << 5) /* "W" (waiting for write compl.) */ +#define PI_CRB_STS_H (1 << 4) /* "H" (gathering invalidates) bit */ +#define PI_CRB_STS_I (1 << 3) /* "I" (targ. inbound invalidate) */ +#define PI_CRB_STS_T (1 << 2) /* "T" (targ. inbound intervention) */ +#define PI_CRB_STS_E (0x3) /* "E" (coherent read type) */ + +/* When the "P" bit is set in the sk_crb_sts field of an error stack + * entry, the "R," "A," "H," and "I" bits are actually bits 6..3 of + * the address. This macro extracts those address bits and shifts + * them to their proper positions, ready to be ORed in to the rest of + * the address (which is calculated as sk_addr << 7). + */ +#define PI_CRB_STS_ADDR_BITS(sts) \ + ((sts) & (PI_CRB_STS_I | PI_CRB_STS_H) | \ + ((sts) & (PI_CRB_STS_A | PI_CRB_STS_R)) >> 1) + +#ifdef _LANGUAGE_C +/* + * format of error stack and error status registers. + */ + +#ifdef LITTLE_ENDIAN + +struct err_stack_format { + uint64_t sk_err_type: 3, /* error type */ + sk_suppl : 3, /* lowest 3 bit of supplemental */ + sk_t5_req : 3, /* RRB T5 request number */ + sk_crb_num : 3, /* WRB (0 to 7) or RRB (0 to 4) */ + sk_rw_rb : 1, /* RRB == 0, WRB == 1 */ + sk_crb_sts : 10, /* status from RRB or WRB */ + sk_cmd : 8, /* message command */ + sk_addr : 33; /* address */ +}; + +#else + +struct err_stack_format { + uint64_t sk_addr : 33, /* address */ + sk_cmd : 8, /* message command */ + sk_crb_sts : 10, /* status from RRB or WRB */ + sk_rw_rb : 1, /* RRB == 0, WRB == 1 */ + sk_crb_num : 3, /* WRB (0 to 7) or RRB (0 to 4) */ + sk_t5_req : 3, /* RRB T5 request number */ + sk_suppl : 3, /* lowest 3 bit of supplemental */ + sk_err_type: 3; /* error type */ +}; + +#endif + +typedef union pi_err_stack { + uint64_t pi_stk_word; + struct err_stack_format pi_stk_fmt; +} pi_err_stack_t; + +/* Simplified version of pi_err_status0_a_u_t (PI_ERR_STATUS0_A) */ +#ifdef LITTLE_ENDIAN + +struct err_status0_format { + uint64_t s0_err_type : 3, /* Encoded error cause */ + s0_proc_req_num : 3, /* Request number for RRB only */ + s0_supplemental : 11, /* ncoming message sup field */ + s0_cmd : 8, /* Incoming message command */ + s0_addr : 37, /* Address */ + s0_over_run : 1, /* Subsequent errors spooled */ + s0_valid : 1; /* error is valid */ +}; + +#else + +struct err_status0_format { + uint64_t s0_valid : 1, /* error is valid */ + s0_over_run : 1, /* Subsequent errors spooled */ + s0_addr : 37, /* Address */ + s0_cmd : 8, /* Incoming message command */ + s0_supplemental : 11, /* ncoming message sup field */ + s0_proc_req_num : 3, /* Request number for RRB only */ + s0_err_type : 3; /* Encoded error cause */ +}; + +#endif + + +typedef union pi_err_stat0 { + uint64_t pi_stat0_word; + struct err_status0_format pi_stat0_fmt; +} pi_err_stat0_t; + +/* Simplified version of pi_err_status1_a_u_t (PI_ERR_STATUS1_A) */ + +#ifdef LITTLE_ENDIAN + +struct err_status1_format { + uint64_t s1_spl_cnt : 21, /* number spooled to memory */ + s1_to_cnt : 8, /* crb timeout counter */ + s1_inval_cnt:10, /* signed invalidate counter RRB */ + s1_crb_num : 3, /* WRB (0 to 7) or RRB (0 to 4) */ + s1_rw_rb : 1, /* RRB == 0, WRB == 1 */ + s1_crb_sts : 10, /* status from RRB or WRB */ + s1_src : 11; /* message source */ +}; + +#else + +struct err_status1_format { + uint64_t s1_src : 11, /* message source */ + s1_crb_sts : 10, /* status from RRB or WRB */ + s1_rw_rb : 1, /* RRB == 0, WRB == 1 */ + s1_crb_num : 3, /* WRB (0 to 7) or RRB (0 to 4) */ + s1_inval_cnt:10, /* signed invalidate counter RRB */ + s1_to_cnt : 8, /* crb timeout counter */ + s1_spl_cnt : 21; /* number spooled to memory */ +}; + +#endif + +typedef union pi_err_stat1 { + uint64_t pi_stat1_word; + struct err_status1_format pi_stat1_fmt; +} pi_err_stat1_t; +#endif + +/* Error stack types (sk_err_type) for reads: */ +#define PI_ERR_RD_AERR 0 /* Read Access Error */ +#define PI_ERR_RD_PRERR 1 /* Uncached Partitial Read */ +#define PI_ERR_RD_DERR 2 /* Directory Error */ +#define PI_ERR_RD_TERR 3 /* read timeout */ +#define PI_ERR_RD_PERR 4 /* Poison Access Violation */ +#define PI_ERR_RD_NACK 5 /* Excessive NACKs */ +#define PI_ERR_RD_RDE 6 /* Response Data Error */ +#define PI_ERR_RD_PLERR 7 /* Packet Length Error */ +/* Error stack types (sk_err_type) for writes: */ +#define PI_ERR_WR_WERR 0 /* Write Access Error */ +#define PI_ERR_WR_PWERR 1 /* Uncached Write Error */ +#define PI_ERR_WR_TERR 3 /* write timeout */ +#define PI_ERR_WR_RDE 6 /* Response Data Error */ +#define PI_ERR_WR_PLERR 7 /* Packet Length Error */ + + +/* For backwards compatibility */ +#define PI_RT_COUNT PI_RT_COUNTER /* Real Time Counter */ +#define PI_RT_EN_A PI_RT_INT_EN_A /* RT int for CPU A enable */ +#define PI_RT_EN_B PI_RT_INT_EN_B /* RT int for CPU B enable */ +#define PI_PROF_EN_A PI_PROF_INT_EN_A /* PROF int for CPU A enable */ +#define PI_PROF_EN_B PI_PROF_INT_EN_B /* PROF int for CPU B enable */ +#define PI_RT_PEND_A PI_RT_INT_PEND_A /* RT interrupt pending */ +#define PI_RT_PEND_B PI_RT_INT_PEND_B /* RT interrupt pending */ +#define PI_PROF_PEND_A PI_PROF_INT_PEND_A /* Profiling interrupt pending */ +#define PI_PROF_PEND_B PI_PROF_INT_PEND_B /* Profiling interrupt pending */ + + +/* Bits in PI_SYSAD_ERRCHK_EN */ +#define PI_SYSAD_ERRCHK_ECCGEN 0x01 /* Enable ECC generation */ +#define PI_SYSAD_ERRCHK_QUALGEN 0x02 /* Enable data quality signal gen. */ +#define PI_SYSAD_ERRCHK_SADP 0x04 /* Enable SysAD parity checking */ +#define PI_SYSAD_ERRCHK_CMDP 0x08 /* Enable SysCmd parity checking */ +#define PI_SYSAD_ERRCHK_STATE 0x10 /* Enable SysState parity checking */ +#define PI_SYSAD_ERRCHK_QUAL 0x20 /* Enable data quality checking */ +#define PI_SYSAD_CHECK_ALL 0x3f /* Generate and check all signals. */ + +/* CALIAS values */ +#define PI_CALIAS_SIZE_0 0 +#define PI_CALIAS_SIZE_4K 1 +#define PI_CALIAS_SIZE_8K 2 +#define PI_CALIAS_SIZE_16K 3 +#define PI_CALIAS_SIZE_32K 4 +#define PI_CALIAS_SIZE_64K 5 +#define PI_CALIAS_SIZE_128K 6 +#define PI_CALIAS_SIZE_256K 7 +#define PI_CALIAS_SIZE_512K 8 +#define PI_CALIAS_SIZE_1M 9 +#define PI_CALIAS_SIZE_2M 10 +#define PI_CALIAS_SIZE_4M 11 +#define PI_CALIAS_SIZE_8M 12 +#define PI_CALIAS_SIZE_16M 13 +#define PI_CALIAS_SIZE_32M 14 +#define PI_CALIAS_SIZE_64M 15 + +/* Fields in PI_ERR_STATUS0_[AB] */ +#define PI_ERR_ST0_VALID_MASK 0x8000000000000000 +#define PI_ERR_ST0_VALID_SHFT 63 + +/* Fields in PI_SPURIOUS_HDR_0 */ +#define PI_SPURIOUS_HDR_VALID_MASK 0x8000000000000000 +#define PI_SPURIOUS_HDR_VALID_SHFT 63 + +/* Fields in PI_NACK_CNT_A/B */ +#define PI_NACK_CNT_EN_SHFT 20 +#define PI_NACK_CNT_EN_MASK 0x100000 +#define PI_NACK_CNT_MASK 0x0fffff +#define PI_NACK_CNT_MAX 0x0fffff + +/* Bits in PI_ERR_INT_PEND */ +#define PI_ERR_SPOOL_CMP_B 0x000000001 /* Spool end hit high water */ +#define PI_ERR_SPOOL_CMP_A 0x000000002 +#define PI_ERR_SPUR_MSG_B 0x000000004 /* Spurious message intr. */ +#define PI_ERR_SPUR_MSG_A 0x000000008 +#define PI_ERR_WRB_TERR_B 0x000000010 /* WRB TERR */ +#define PI_ERR_WRB_TERR_A 0x000000020 +#define PI_ERR_WRB_WERR_B 0x000000040 /* WRB WERR */ +#define PI_ERR_WRB_WERR_A 0x000000080 +#define PI_ERR_SYSSTATE_B 0x000000100 /* SysState parity error */ +#define PI_ERR_SYSSTATE_A 0x000000200 +#define PI_ERR_SYSAD_DATA_B 0x000000400 /* SysAD data parity error */ +#define PI_ERR_SYSAD_DATA_A 0x000000800 +#define PI_ERR_SYSAD_ADDR_B 0x000001000 /* SysAD addr parity error */ +#define PI_ERR_SYSAD_ADDR_A 0x000002000 +#define PI_ERR_SYSCMD_DATA_B 0x000004000 /* SysCmd data parity error */ +#define PI_ERR_SYSCMD_DATA_A 0x000008000 +#define PI_ERR_SYSCMD_ADDR_B 0x000010000 /* SysCmd addr parity error */ +#define PI_ERR_SYSCMD_ADDR_A 0x000020000 +#define PI_ERR_BAD_SPOOL_B 0x000040000 /* Error spooling to memory */ +#define PI_ERR_BAD_SPOOL_A 0x000080000 +#define PI_ERR_UNCAC_UNCORR_B 0x000100000 /* Uncached uncorrectable */ +#define PI_ERR_UNCAC_UNCORR_A 0x000200000 +#define PI_ERR_SYSSTATE_TAG_B 0x000400000 /* SysState tag parity error */ +#define PI_ERR_SYSSTATE_TAG_A 0x000800000 +#define PI_ERR_MD_UNCORR 0x001000000 /* Must be cleared in MD */ +#define PI_ERR_SYSAD_BAD_DATA_B 0x002000000 /* SysAD Data quality bad */ +#define PI_ERR_SYSAD_BAD_DATA_A 0x004000000 +#define PI_ERR_UE_CACHED_B 0x008000000 /* UE during cached load */ +#define PI_ERR_UE_CACHED_A 0x010000000 +#define PI_ERR_PKT_LEN_ERR_B 0x020000000 /* Xbar data too long/short */ +#define PI_ERR_PKT_LEN_ERR_A 0x040000000 +#define PI_ERR_IRB_ERR_B 0x080000000 /* Protocol error */ +#define PI_ERR_IRB_ERR_A 0x100000000 +#define PI_ERR_IRB_TIMEOUT_B 0x200000000 /* IRB_B got a timeout */ +#define PI_ERR_IRB_TIMEOUT_A 0x400000000 + +#define PI_ERR_CLEAR_ALL_A 0x554aaaaaa +#define PI_ERR_CLEAR_ALL_B 0x2aa555555 + + +/* + * The following three macros define all possible error int pends. + */ + +#define PI_FATAL_ERR_CPU_A (PI_ERR_SYSAD_BAD_DATA_A | \ + PI_ERR_SYSSTATE_TAG_A | \ + PI_ERR_BAD_SPOOL_A | \ + PI_ERR_SYSCMD_ADDR_A | \ + PI_ERR_SYSCMD_DATA_A | \ + PI_ERR_SYSAD_ADDR_A | \ + PI_ERR_SYSAD_DATA_A | \ + PI_ERR_SYSSTATE_A) + +#define PI_MISC_ERR_CPU_A (PI_ERR_IRB_TIMEOUT_A | \ + PI_ERR_IRB_ERR_A | \ + PI_ERR_PKT_LEN_ERR_A | \ + PI_ERR_UE_CACHED_A | \ + PI_ERR_UNCAC_UNCORR_A | \ + PI_ERR_WRB_WERR_A | \ + PI_ERR_WRB_TERR_A | \ + PI_ERR_SPUR_MSG_A | \ + PI_ERR_SPOOL_CMP_A) + +#define PI_FATAL_ERR_CPU_B (PI_ERR_SYSAD_BAD_DATA_B | \ + PI_ERR_SYSSTATE_TAG_B | \ + PI_ERR_BAD_SPOOL_B | \ + PI_ERR_SYSCMD_ADDR_B | \ + PI_ERR_SYSCMD_DATA_B | \ + PI_ERR_SYSAD_ADDR_B | \ + PI_ERR_SYSAD_DATA_B | \ + PI_ERR_SYSSTATE_B) + +#define PI_MISC_ERR_CPU_B (PI_ERR_IRB_TIMEOUT_B | \ + PI_ERR_IRB_ERR_B | \ + PI_ERR_PKT_LEN_ERR_B | \ + PI_ERR_UE_CACHED_B | \ + PI_ERR_UNCAC_UNCORR_B | \ + PI_ERR_WRB_WERR_B | \ + PI_ERR_WRB_TERR_B | \ + PI_ERR_SPUR_MSG_B | \ + PI_ERR_SPOOL_CMP_B) + +#define PI_ERR_GENERIC (PI_ERR_MD_UNCORR) + +/* Values for PI_MAX_CRB_TIMEOUT and PI_CRB_SFACTOR */ +#define PMCT_MAX 0xff +#define PCS_MAX 0xffffff + +/* pi_err_status0_a_u_t address shift */ +#define ERR_STAT0_ADDR_SHFT 3 + +/* PI error read/write bit (RRB == 0, WRB == 1) */ +/* pi_err_status1_a_u_t.pi_err_status1_a_fld_s.esa_wrb */ +#define PI_ERR_RRB 0 +#define PI_ERR_WRB 1 + +/* Error stack address shift, for use with pi_stk_fmt.sk_addr */ +#define ERR_STK_ADDR_SHFT 3 + +#endif /* _ASM_SN_SN1_HUBPI_NEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubxb.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubxb.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubxb.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubxb.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,1289 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBXB_H +#define _ASM_SN_SN1_HUBXB_H + +/************************************************************************ + * * + * WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! * + * * + * This file is created by an automated script. Any (minimal) changes * + * made manually to this file should be made with care. * + * * + * MAKE ALL ADDITIONS TO THE END OF THIS FILE * + * * + ************************************************************************/ + + +#define XB_PARMS 0x00700000 /* + * Controls + * crossbar-wide + * parameters. + */ + + + +#define XB_SLOW_GNT 0x00700008 /* + * Controls wavefront + * arbiter grant + * frequency, used to + * slow XB grants + */ + + + +#define XB_SPEW_CONTROL 0x00700010 /* + * Controls spew + * settings (debug + * only). + */ + + + +#define XB_IOQ_ARB_TRIGGER 0x00700018 /* + * Controls IOQ + * trigger level + */ + + + +#define XB_FIRST_ERROR 0x00700090 /* + * Records the first + * crossbar error + * seen. + */ + + + +#define XB_POQ0_ERROR 0x00700020 /* + * POQ0 error + * register. + */ + + + +#define XB_PIQ0_ERROR 0x00700028 /* + * PIQ0 error + * register. + */ + + + +#define XB_POQ1_ERROR 0x00700030 /* + * POQ1 error + * register. + */ + + + +#define XB_PIQ1_ERROR 0x00700038 /* + * PIQ1 error + * register. + */ + + + +#define XB_MP0_ERROR 0x00700040 /* + * MOQ for PI0 error + * register. + */ + + + +#define XB_MP1_ERROR 0x00700048 /* + * MOQ for PI1 error + * register. + */ + + + +#define XB_MMQ_ERROR 0x00700050 /* + * MOQ for misc. (LB, + * NI, II) error + * register. + */ + + + +#define XB_MIQ_ERROR 0x00700058 /* + * MIQ error register, + * addtional MIQ + * errors are logged + * in MD "Input + * Error + * Registers". + */ + + + +#define XB_NOQ_ERROR 0x00700060 /* NOQ error register. */ + + + +#define XB_NIQ_ERROR 0x00700068 /* NIQ error register. */ + + + +#define XB_IOQ_ERROR 0x00700070 /* IOQ error register. */ + + + +#define XB_IIQ_ERROR 0x00700078 /* IIQ error register. */ + + + +#define XB_LOQ_ERROR 0x00700080 /* LOQ error register. */ + + + +#define XB_LIQ_ERROR 0x00700088 /* LIQ error register. */ + + + +#define XB_DEBUG_DATA_CTL 0x00700098 /* + * Debug Datapath + * Select + */ + + + +#define XB_DEBUG_ARB_CTL 0x007000A0 /* + * XB master debug + * control + */ + + + +#define XB_POQ0_ERROR_CLEAR 0x00700120 /* + * Clears + * XB_POQ0_ERROR + * register. + */ + + + +#define XB_PIQ0_ERROR_CLEAR 0x00700128 /* + * Clears + * XB_PIQ0_ERROR + * register. + */ + + + +#define XB_POQ1_ERROR_CLEAR 0x00700130 /* + * Clears + * XB_POQ1_ERROR + * register. + */ + + + +#define XB_PIQ1_ERROR_CLEAR 0x00700138 /* + * Clears + * XB_PIQ1_ERROR + * register. + */ + + + +#define XB_MP0_ERROR_CLEAR 0x00700140 /* + * Clears XB_MP0_ERROR + * register. + */ + + + +#define XB_MP1_ERROR_CLEAR 0x00700148 /* + * Clears XB_MP1_ERROR + * register. + */ + + + +#define XB_MMQ_ERROR_CLEAR 0x00700150 /* + * Clears XB_MMQ_ERROR + * register. + */ + + + +#define XB_XM_MIQ_ERROR_CLEAR 0x00700158 /* + * Clears XB_MIQ_ERROR + * register + */ + + + +#define XB_NOQ_ERROR_CLEAR 0x00700160 /* + * Clears XB_NOQ_ERROR + * register. + */ + + + +#define XB_NIQ_ERROR_CLEAR 0x00700168 /* + * Clears XB_NIQ_ERROR + * register. + */ + + + +#define XB_IOQ_ERROR_CLEAR 0x00700170 /* + * Clears XB_IOQ + * _ERROR register. + */ + + + +#define XB_IIQ_ERROR_CLEAR 0x00700178 /* + * Clears XB_IIQ + * _ERROR register. + */ + + + +#define XB_LOQ_ERROR_CLEAR 0x00700180 /* + * Clears XB_LOQ_ERROR + * register. + */ + + + +#define XB_LIQ_ERROR_CLEAR 0x00700188 /* + * Clears XB_LIQ_ERROR + * register. + */ + + + +#define XB_FIRST_ERROR_CLEAR 0x00700190 /* + * Clears + * XB_FIRST_ERROR + * register + */ + + + + + +#ifdef _LANGUAGE_C + +/************************************************************************ + * * + * Access to parameters which control various aspects of the * + * crossbar's operation. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_parms_u { + bdrkreg_t xb_parms_regval; + struct { + bdrkreg_t p_byp_en : 1; + bdrkreg_t p_rsrvd_1 : 3; + bdrkreg_t p_age_wrap : 8; + bdrkreg_t p_deadlock_to_wrap : 20; + bdrkreg_t p_tail_to_wrap : 20; + bdrkreg_t p_rsrvd : 12; + } xb_parms_fld_s; +} xb_parms_u_t; + +#else + +typedef union xb_parms_u { + bdrkreg_t xb_parms_regval; + struct { + bdrkreg_t p_rsrvd : 12; + bdrkreg_t p_tail_to_wrap : 20; + bdrkreg_t p_deadlock_to_wrap : 20; + bdrkreg_t p_age_wrap : 8; + bdrkreg_t p_rsrvd_1 : 3; + bdrkreg_t p_byp_en : 1; + } xb_parms_fld_s; +} xb_parms_u_t; + +#endif + + + + +/************************************************************************ + * * + * Sets the period of wavefront grants given to each unit. The * + * register's value corresponds to the number of cycles between each * + * wavefront grant opportunity given to the requesting unit. If set * + * to 0xF, no grants are given to this unit. If set to 0xE, the unit * + * is granted at the slowest rate (sometimes called "molasses mode"). * + * This feature can be used to apply backpressure to a unit's output * + * queue(s). The setting does not affect bypass grants. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_slow_gnt_u { + bdrkreg_t xb_slow_gnt_regval; + struct { + bdrkreg_t sg_lb_slow_gnt : 4; + bdrkreg_t sg_ii_slow_gnt : 4; + bdrkreg_t sg_ni_slow_gnt : 4; + bdrkreg_t sg_mmq_slow_gnt : 4; + bdrkreg_t sg_mp1_slow_gnt : 4; + bdrkreg_t sg_mp0_slow_gnt : 4; + bdrkreg_t sg_pi1_slow_gnt : 4; + bdrkreg_t sg_pi0_slow_gnt : 4; + bdrkreg_t sg_rsrvd : 32; + } xb_slow_gnt_fld_s; +} xb_slow_gnt_u_t; + +#else + +typedef union xb_slow_gnt_u { + bdrkreg_t xb_slow_gnt_regval; + struct { + bdrkreg_t sg_rsrvd : 32; + bdrkreg_t sg_pi0_slow_gnt : 4; + bdrkreg_t sg_pi1_slow_gnt : 4; + bdrkreg_t sg_mp0_slow_gnt : 4; + bdrkreg_t sg_mp1_slow_gnt : 4; + bdrkreg_t sg_mmq_slow_gnt : 4; + bdrkreg_t sg_ni_slow_gnt : 4; + bdrkreg_t sg_ii_slow_gnt : 4; + bdrkreg_t sg_lb_slow_gnt : 4; + } xb_slow_gnt_fld_s; +} xb_slow_gnt_u_t; + +#endif + + + + +/************************************************************************ + * * + * Enables snooping of internal crossbar traffic by spewing all * + * traffic across a selected crossbar point to the PI1 port. Only one * + * bit should be set at any one time, and any bit set will preclude * + * using the P1 for anything but a debug connection. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_spew_control_u { + bdrkreg_t xb_spew_control_regval; + struct { + bdrkreg_t sc_snoop_liq : 1; + bdrkreg_t sc_snoop_iiq : 1; + bdrkreg_t sc_snoop_niq : 1; + bdrkreg_t sc_snoop_miq : 1; + bdrkreg_t sc_snoop_piq0 : 1; + bdrkreg_t sc_snoop_loq : 1; + bdrkreg_t sc_snoop_ioq : 1; + bdrkreg_t sc_snoop_noq : 1; + bdrkreg_t sc_snoop_mmq : 1; + bdrkreg_t sc_snoop_mp0 : 1; + bdrkreg_t sc_snoop_poq0 : 1; + bdrkreg_t sc_rsrvd : 53; + } xb_spew_control_fld_s; +} xb_spew_control_u_t; + +#else + +typedef union xb_spew_control_u { + bdrkreg_t xb_spew_control_regval; + struct { + bdrkreg_t sc_rsrvd : 53; + bdrkreg_t sc_snoop_poq0 : 1; + bdrkreg_t sc_snoop_mp0 : 1; + bdrkreg_t sc_snoop_mmq : 1; + bdrkreg_t sc_snoop_noq : 1; + bdrkreg_t sc_snoop_ioq : 1; + bdrkreg_t sc_snoop_loq : 1; + bdrkreg_t sc_snoop_piq0 : 1; + bdrkreg_t sc_snoop_miq : 1; + bdrkreg_t sc_snoop_niq : 1; + bdrkreg_t sc_snoop_iiq : 1; + bdrkreg_t sc_snoop_liq : 1; + } xb_spew_control_fld_s; +} xb_spew_control_u_t; + +#endif + + + + +/************************************************************************ + * * + * Number of clocks the IOQ will wait before beginning XB * + * arbitration. This is set so that the slower IOQ data rate can * + * catch up up with the XB data rate in the IOQ buffer. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_ioq_arb_trigger_u { + bdrkreg_t xb_ioq_arb_trigger_regval; + struct { + bdrkreg_t iat_ioq_arb_trigger : 4; + bdrkreg_t iat_rsrvd : 60; + } xb_ioq_arb_trigger_fld_s; +} xb_ioq_arb_trigger_u_t; + +#else + +typedef union xb_ioq_arb_trigger_u { + bdrkreg_t xb_ioq_arb_trigger_regval; + struct { + bdrkreg_t iat_rsrvd : 60; + bdrkreg_t iat_ioq_arb_trigger : 4; + } xb_ioq_arb_trigger_fld_s; +} xb_ioq_arb_trigger_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by POQ0.Can be written to test software, will * + * cause an interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_poq0_error_u { + bdrkreg_t xb_poq0_error_regval; + struct { + bdrkreg_t pe_invalid_xsel : 2; + bdrkreg_t pe_rsrvd_3 : 2; + bdrkreg_t pe_overflow : 2; + bdrkreg_t pe_rsrvd_2 : 2; + bdrkreg_t pe_underflow : 2; + bdrkreg_t pe_rsrvd_1 : 2; + bdrkreg_t pe_tail_timeout : 2; + bdrkreg_t pe_unused : 6; + bdrkreg_t pe_rsrvd : 44; + } xb_poq0_error_fld_s; +} xb_poq0_error_u_t; + +#else + +typedef union xb_poq0_error_u { + bdrkreg_t xb_poq0_error_regval; + struct { + bdrkreg_t pe_rsrvd : 44; + bdrkreg_t pe_unused : 6; + bdrkreg_t pe_tail_timeout : 2; + bdrkreg_t pe_rsrvd_1 : 2; + bdrkreg_t pe_underflow : 2; + bdrkreg_t pe_rsrvd_2 : 2; + bdrkreg_t pe_overflow : 2; + bdrkreg_t pe_rsrvd_3 : 2; + bdrkreg_t pe_invalid_xsel : 2; + } xb_poq0_error_fld_s; +} xb_poq0_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by PIQ0. Note that the PIQ/PI interface * + * precludes PIQ underflow. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_piq0_error_u { + bdrkreg_t xb_piq0_error_regval; + struct { + bdrkreg_t pe_overflow : 2; + bdrkreg_t pe_rsrvd_1 : 2; + bdrkreg_t pe_deadlock_timeout : 2; + bdrkreg_t pe_rsrvd : 58; + } xb_piq0_error_fld_s; +} xb_piq0_error_u_t; + +#else + +typedef union xb_piq0_error_u { + bdrkreg_t xb_piq0_error_regval; + struct { + bdrkreg_t pe_rsrvd : 58; + bdrkreg_t pe_deadlock_timeout : 2; + bdrkreg_t pe_rsrvd_1 : 2; + bdrkreg_t pe_overflow : 2; + } xb_piq0_error_fld_s; +} xb_piq0_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by MP0 queue (the MOQ for processor 0). Since * + * the xselect is decoded on the MD/MOQ interface, no invalid xselect * + * errors are possible. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_mp0_error_u { + bdrkreg_t xb_mp0_error_regval; + struct { + bdrkreg_t me_rsrvd_3 : 4; + bdrkreg_t me_overflow : 2; + bdrkreg_t me_rsrvd_2 : 2; + bdrkreg_t me_underflow : 2; + bdrkreg_t me_rsrvd_1 : 2; + bdrkreg_t me_tail_timeout : 2; + bdrkreg_t me_rsrvd : 50; + } xb_mp0_error_fld_s; +} xb_mp0_error_u_t; + +#else + +typedef union xb_mp0_error_u { + bdrkreg_t xb_mp0_error_regval; + struct { + bdrkreg_t me_rsrvd : 50; + bdrkreg_t me_tail_timeout : 2; + bdrkreg_t me_rsrvd_1 : 2; + bdrkreg_t me_underflow : 2; + bdrkreg_t me_rsrvd_2 : 2; + bdrkreg_t me_overflow : 2; + bdrkreg_t me_rsrvd_3 : 4; + } xb_mp0_error_fld_s; +} xb_mp0_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by MIQ. * + * * + ************************************************************************/ + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_miq_error_u { + bdrkreg_t xb_miq_error_regval; + struct { + bdrkreg_t me_rsrvd_1 : 4; + bdrkreg_t me_deadlock_timeout : 4; + bdrkreg_t me_rsrvd : 56; + } xb_miq_error_fld_s; +} xb_miq_error_u_t; + +#else + +typedef union xb_miq_error_u { + bdrkreg_t xb_miq_error_regval; + struct { + bdrkreg_t me_rsrvd : 56; + bdrkreg_t me_deadlock_timeout : 4; + bdrkreg_t me_rsrvd_1 : 4; + } xb_miq_error_fld_s; +} xb_miq_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by NOQ. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_noq_error_u { + bdrkreg_t xb_noq_error_regval; + struct { + bdrkreg_t ne_rsvd : 4; + bdrkreg_t ne_overflow : 4; + bdrkreg_t ne_underflow : 4; + bdrkreg_t ne_tail_timeout : 4; + bdrkreg_t ne_rsrvd : 48; + } xb_noq_error_fld_s; +} xb_noq_error_u_t; + +#else + +typedef union xb_noq_error_u { + bdrkreg_t xb_noq_error_regval; + struct { + bdrkreg_t ne_rsrvd : 48; + bdrkreg_t ne_tail_timeout : 4; + bdrkreg_t ne_underflow : 4; + bdrkreg_t ne_overflow : 4; + bdrkreg_t ne_rsvd : 4; + } xb_noq_error_fld_s; +} xb_noq_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by LOQ. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_loq_error_u { + bdrkreg_t xb_loq_error_regval; + struct { + bdrkreg_t le_invalid_xsel : 2; + bdrkreg_t le_rsrvd_1 : 6; + bdrkreg_t le_underflow : 2; + bdrkreg_t le_rsvd : 2; + bdrkreg_t le_tail_timeout : 2; + bdrkreg_t le_rsrvd : 50; + } xb_loq_error_fld_s; +} xb_loq_error_u_t; + +#else + +typedef union xb_loq_error_u { + bdrkreg_t xb_loq_error_regval; + struct { + bdrkreg_t le_rsrvd : 50; + bdrkreg_t le_tail_timeout : 2; + bdrkreg_t le_rsvd : 2; + bdrkreg_t le_underflow : 2; + bdrkreg_t le_rsrvd_1 : 6; + bdrkreg_t le_invalid_xsel : 2; + } xb_loq_error_fld_s; +} xb_loq_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by LIQ. Note that the LIQ only records errors * + * for the request channel. The reply channel can never deadlock or * + * overflow because it does not have hardware flow control. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_liq_error_u { + bdrkreg_t xb_liq_error_regval; + struct { + bdrkreg_t le_overflow : 1; + bdrkreg_t le_rsrvd_1 : 3; + bdrkreg_t le_deadlock_timeout : 1; + bdrkreg_t le_rsrvd : 59; + } xb_liq_error_fld_s; +} xb_liq_error_u_t; + +#else + +typedef union xb_liq_error_u { + bdrkreg_t xb_liq_error_regval; + struct { + bdrkreg_t le_rsrvd : 59; + bdrkreg_t le_deadlock_timeout : 1; + bdrkreg_t le_rsrvd_1 : 3; + bdrkreg_t le_overflow : 1; + } xb_liq_error_fld_s; +} xb_liq_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * First error is latched whenever the Valid bit is clear and an * + * error occurs. Any valid bit on in this register causes an * + * interrupt to PI0 and PI1. This interrupt bit will persist until * + * the specific error register to capture the error is cleared, then * + * the FIRST_ERROR register is cleared (in that oder.) The * + * FIRST_ERROR register is not writable, but will be set when any of * + * the corresponding error registers are written by software. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_first_error_u { + bdrkreg_t xb_first_error_regval; + struct { + bdrkreg_t fe_type : 4; + bdrkreg_t fe_channel : 4; + bdrkreg_t fe_source : 4; + bdrkreg_t fe_valid : 1; + bdrkreg_t fe_rsrvd : 51; + } xb_first_error_fld_s; +} xb_first_error_u_t; + +#else + +typedef union xb_first_error_u { + bdrkreg_t xb_first_error_regval; + struct { + bdrkreg_t fe_rsrvd : 51; + bdrkreg_t fe_valid : 1; + bdrkreg_t fe_source : 4; + bdrkreg_t fe_channel : 4; + bdrkreg_t fe_type : 4; + } xb_first_error_fld_s; +} xb_first_error_u_t; + +#endif + + + + +/************************************************************************ + * * + * Controls DEBUG_DATA mux setting. Allows user to watch the output * + * of any OQ or input of any IQ on the DEBUG port. Note that bits * + * 13:0 are one-hot. If more than one bit is set in [13:0], the debug * + * output is undefined. Details on the debug output lines can be * + * found in the XB chapter of the Bedrock Interface Specification. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_debug_data_ctl_u { + bdrkreg_t xb_debug_data_ctl_regval; + struct { + bdrkreg_t ddc_observe_liq_traffic : 1; + bdrkreg_t ddc_observe_iiq_traffic : 1; + bdrkreg_t ddc_observe_niq_traffic : 1; + bdrkreg_t ddc_observe_miq_traffic : 1; + bdrkreg_t ddc_observe_piq1_traffic : 1; + bdrkreg_t ddc_observe_piq0_traffic : 1; + bdrkreg_t ddc_observe_loq_traffic : 1; + bdrkreg_t ddc_observe_ioq_traffic : 1; + bdrkreg_t ddc_observe_noq_traffic : 1; + bdrkreg_t ddc_observe_mp1_traffic : 1; + bdrkreg_t ddc_observe_mp0_traffic : 1; + bdrkreg_t ddc_observe_mmq_traffic : 1; + bdrkreg_t ddc_observe_poq1_traffic : 1; + bdrkreg_t ddc_observe_poq0_traffic : 1; + bdrkreg_t ddc_observe_source_field : 1; + bdrkreg_t ddc_observe_lodata : 1; + bdrkreg_t ddc_rsrvd : 48; + } xb_debug_data_ctl_fld_s; +} xb_debug_data_ctl_u_t; + +#else + +typedef union xb_debug_data_ctl_u { + bdrkreg_t xb_debug_data_ctl_regval; + struct { + bdrkreg_t ddc_rsrvd : 48; + bdrkreg_t ddc_observe_lodata : 1; + bdrkreg_t ddc_observe_source_field : 1; + bdrkreg_t ddc_observe_poq0_traffic : 1; + bdrkreg_t ddc_observe_poq1_traffic : 1; + bdrkreg_t ddc_observe_mmq_traffic : 1; + bdrkreg_t ddc_observe_mp0_traffic : 1; + bdrkreg_t ddc_observe_mp1_traffic : 1; + bdrkreg_t ddc_observe_noq_traffic : 1; + bdrkreg_t ddc_observe_ioq_traffic : 1; + bdrkreg_t ddc_observe_loq_traffic : 1; + bdrkreg_t ddc_observe_piq0_traffic : 1; + bdrkreg_t ddc_observe_piq1_traffic : 1; + bdrkreg_t ddc_observe_miq_traffic : 1; + bdrkreg_t ddc_observe_niq_traffic : 1; + bdrkreg_t ddc_observe_iiq_traffic : 1; + bdrkreg_t ddc_observe_liq_traffic : 1; + } xb_debug_data_ctl_fld_s; +} xb_debug_data_ctl_u_t; + +#endif + + + + +/************************************************************************ + * * + * Controls debug mux setting for XB Input/Output Queues and * + * Arbiter. Can select one of the following values. Details on the * + * debug output lines can be found in the XB chapter of the Bedrock * + * Interface Specification. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_debug_arb_ctl_u { + bdrkreg_t xb_debug_arb_ctl_regval; + struct { + bdrkreg_t dac_xb_debug_select : 3; + bdrkreg_t dac_rsrvd : 61; + } xb_debug_arb_ctl_fld_s; +} xb_debug_arb_ctl_u_t; + +#else + +typedef union xb_debug_arb_ctl_u { + bdrkreg_t xb_debug_arb_ctl_regval; + struct { + bdrkreg_t dac_rsrvd : 61; + bdrkreg_t dac_xb_debug_select : 3; + } xb_debug_arb_ctl_fld_s; +} xb_debug_arb_ctl_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by POQ0.Can be written to test software, will * + * cause an interrupt. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_poq0_error_clear_u { + bdrkreg_t xb_poq0_error_clear_regval; + struct { + bdrkreg_t pec_invalid_xsel : 2; + bdrkreg_t pec_rsrvd_3 : 2; + bdrkreg_t pec_overflow : 2; + bdrkreg_t pec_rsrvd_2 : 2; + bdrkreg_t pec_underflow : 2; + bdrkreg_t pec_rsrvd_1 : 2; + bdrkreg_t pec_tail_timeout : 2; + bdrkreg_t pec_unused : 6; + bdrkreg_t pec_rsrvd : 44; + } xb_poq0_error_clear_fld_s; +} xb_poq0_error_clear_u_t; + +#else + +typedef union xb_poq0_error_clear_u { + bdrkreg_t xb_poq0_error_clear_regval; + struct { + bdrkreg_t pec_rsrvd : 44; + bdrkreg_t pec_unused : 6; + bdrkreg_t pec_tail_timeout : 2; + bdrkreg_t pec_rsrvd_1 : 2; + bdrkreg_t pec_underflow : 2; + bdrkreg_t pec_rsrvd_2 : 2; + bdrkreg_t pec_overflow : 2; + bdrkreg_t pec_rsrvd_3 : 2; + bdrkreg_t pec_invalid_xsel : 2; + } xb_poq0_error_clear_fld_s; +} xb_poq0_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by PIQ0. Note that the PIQ/PI interface * + * precludes PIQ underflow. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_piq0_error_clear_u { + bdrkreg_t xb_piq0_error_clear_regval; + struct { + bdrkreg_t pec_overflow : 2; + bdrkreg_t pec_rsrvd_1 : 2; + bdrkreg_t pec_deadlock_timeout : 2; + bdrkreg_t pec_rsrvd : 58; + } xb_piq0_error_clear_fld_s; +} xb_piq0_error_clear_u_t; + +#else + +typedef union xb_piq0_error_clear_u { + bdrkreg_t xb_piq0_error_clear_regval; + struct { + bdrkreg_t pec_rsrvd : 58; + bdrkreg_t pec_deadlock_timeout : 2; + bdrkreg_t pec_rsrvd_1 : 2; + bdrkreg_t pec_overflow : 2; + } xb_piq0_error_clear_fld_s; +} xb_piq0_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by MP0 queue (the MOQ for processor 0). Since * + * the xselect is decoded on the MD/MOQ interface, no invalid xselect * + * errors are possible. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_mp0_error_clear_u { + bdrkreg_t xb_mp0_error_clear_regval; + struct { + bdrkreg_t mec_rsrvd_3 : 4; + bdrkreg_t mec_overflow : 2; + bdrkreg_t mec_rsrvd_2 : 2; + bdrkreg_t mec_underflow : 2; + bdrkreg_t mec_rsrvd_1 : 2; + bdrkreg_t mec_tail_timeout : 2; + bdrkreg_t mec_rsrvd : 50; + } xb_mp0_error_clear_fld_s; +} xb_mp0_error_clear_u_t; + +#else + +typedef union xb_mp0_error_clear_u { + bdrkreg_t xb_mp0_error_clear_regval; + struct { + bdrkreg_t mec_rsrvd : 50; + bdrkreg_t mec_tail_timeout : 2; + bdrkreg_t mec_rsrvd_1 : 2; + bdrkreg_t mec_underflow : 2; + bdrkreg_t mec_rsrvd_2 : 2; + bdrkreg_t mec_overflow : 2; + bdrkreg_t mec_rsrvd_3 : 4; + } xb_mp0_error_clear_fld_s; +} xb_mp0_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by MIQ. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_xm_miq_error_clear_u { + bdrkreg_t xb_xm_miq_error_clear_regval; + struct { + bdrkreg_t xmec_rsrvd_1 : 4; + bdrkreg_t xmec_deadlock_timeout : 4; + bdrkreg_t xmec_rsrvd : 56; + } xb_xm_miq_error_clear_fld_s; +} xb_xm_miq_error_clear_u_t; + +#else + +typedef union xb_xm_miq_error_clear_u { + bdrkreg_t xb_xm_miq_error_clear_regval; + struct { + bdrkreg_t xmec_rsrvd : 56; + bdrkreg_t xmec_deadlock_timeout : 4; + bdrkreg_t xmec_rsrvd_1 : 4; + } xb_xm_miq_error_clear_fld_s; +} xb_xm_miq_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by NOQ. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_noq_error_clear_u { + bdrkreg_t xb_noq_error_clear_regval; + struct { + bdrkreg_t nec_rsvd : 4; + bdrkreg_t nec_overflow : 4; + bdrkreg_t nec_underflow : 4; + bdrkreg_t nec_tail_timeout : 4; + bdrkreg_t nec_rsrvd : 48; + } xb_noq_error_clear_fld_s; +} xb_noq_error_clear_u_t; + +#else + +typedef union xb_noq_error_clear_u { + bdrkreg_t xb_noq_error_clear_regval; + struct { + bdrkreg_t nec_rsrvd : 48; + bdrkreg_t nec_tail_timeout : 4; + bdrkreg_t nec_underflow : 4; + bdrkreg_t nec_overflow : 4; + bdrkreg_t nec_rsvd : 4; + } xb_noq_error_clear_fld_s; +} xb_noq_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by LOQ. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_loq_error_clear_u { + bdrkreg_t xb_loq_error_clear_regval; + struct { + bdrkreg_t lec_invalid_xsel : 2; + bdrkreg_t lec_rsrvd_1 : 6; + bdrkreg_t lec_underflow : 2; + bdrkreg_t lec_rsvd : 2; + bdrkreg_t lec_tail_timeout : 2; + bdrkreg_t lec_rsrvd : 50; + } xb_loq_error_clear_fld_s; +} xb_loq_error_clear_u_t; + +#else + +typedef union xb_loq_error_clear_u { + bdrkreg_t xb_loq_error_clear_regval; + struct { + bdrkreg_t lec_rsrvd : 50; + bdrkreg_t lec_tail_timeout : 2; + bdrkreg_t lec_rsvd : 2; + bdrkreg_t lec_underflow : 2; + bdrkreg_t lec_rsrvd_1 : 6; + bdrkreg_t lec_invalid_xsel : 2; + } xb_loq_error_clear_fld_s; +} xb_loq_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * Records errors seen by LIQ. Note that the LIQ only records errors * + * for the request channel. The reply channel can never deadlock or * + * overflow because it does not have hardware flow control. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_liq_error_clear_u { + bdrkreg_t xb_liq_error_clear_regval; + struct { + bdrkreg_t lec_overflow : 1; + bdrkreg_t lec_rsrvd_1 : 3; + bdrkreg_t lec_deadlock_timeout : 1; + bdrkreg_t lec_rsrvd : 59; + } xb_liq_error_clear_fld_s; +} xb_liq_error_clear_u_t; + +#else + +typedef union xb_liq_error_clear_u { + bdrkreg_t xb_liq_error_clear_regval; + struct { + bdrkreg_t lec_rsrvd : 59; + bdrkreg_t lec_deadlock_timeout : 1; + bdrkreg_t lec_rsrvd_1 : 3; + bdrkreg_t lec_overflow : 1; + } xb_liq_error_clear_fld_s; +} xb_liq_error_clear_u_t; + +#endif + + + + +/************************************************************************ + * * + * First error is latched whenever the Valid bit is clear and an * + * error occurs. Any valid bit on in this register causes an * + * interrupt to PI0 and PI1. This interrupt bit will persist until * + * the specific error register to capture the error is cleared, then * + * the FIRST_ERROR register is cleared (in that oder.) The * + * FIRST_ERROR register is not writable, but will be set when any of * + * the corresponding error registers are written by software. * + * * + ************************************************************************/ + + + + +#ifdef LITTLE_ENDIAN + +typedef union xb_first_error_clear_u { + bdrkreg_t xb_first_error_clear_regval; + struct { + bdrkreg_t fec_type : 4; + bdrkreg_t fec_channel : 4; + bdrkreg_t fec_source : 4; + bdrkreg_t fec_valid : 1; + bdrkreg_t fec_rsrvd : 51; + } xb_first_error_clear_fld_s; +} xb_first_error_clear_u_t; + +#else + +typedef union xb_first_error_clear_u { + bdrkreg_t xb_first_error_clear_regval; + struct { + bdrkreg_t fec_rsrvd : 51; + bdrkreg_t fec_valid : 1; + bdrkreg_t fec_source : 4; + bdrkreg_t fec_channel : 4; + bdrkreg_t fec_type : 4; + } xb_first_error_clear_fld_s; +} xb_first_error_clear_u_t; + +#endif + + + + + + +#endif /* _LANGUAGE_C */ + +/************************************************************************ + * * + * The following defines were not formed into structures * + * * + * This could be because the document did not contain details of the * + * register, or because the automated script did not recognize the * + * register details in the documentation. If these register need * + * structure definition, please create them manually * + * * + * XB_POQ1_ERROR 0x700030 * + * XB_PIQ1_ERROR 0x700038 * + * XB_MP1_ERROR 0x700048 * + * XB_MMQ_ERROR 0x700050 * + * XB_NIQ_ERROR 0x700068 * + * XB_IOQ_ERROR 0x700070 * + * XB_IIQ_ERROR 0x700078 * + * XB_POQ1_ERROR_CLEAR 0x700130 * + * XB_PIQ1_ERROR_CLEAR 0x700138 * + * XB_MP1_ERROR_CLEAR 0x700148 * + * XB_MMQ_ERROR_CLEAR 0x700150 * + * XB_NIQ_ERROR_CLEAR 0x700168 * + * XB_IOQ_ERROR_CLEAR 0x700170 * + * XB_IIQ_ERROR_CLEAR 0x700178 * + * * + ************************************************************************/ + + +/************************************************************************ + * * + * MAKE ALL ADDITIONS AFTER THIS LINE * + * * + ************************************************************************/ + + + + + +#endif /* _ASM_SN_SN1_HUBXB_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubxb_next.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubxb_next.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/hubxb_next.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/hubxb_next.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,32 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_HUBXB_NEXT_H +#define _ASM_SN_SN1_HUBXB_NEXT_H + +/* XB_FIRST_ERROR fe_source field encoding */ +#define XVE_SOURCE_POQ0 0xf /* 1111 */ +#define XVE_SOURCE_PIQ0 0xe /* 1110 */ +#define XVE_SOURCE_POQ1 0xd /* 1101 */ +#define XVE_SOURCE_PIQ1 0xc /* 1100 */ +#define XVE_SOURCE_MP0 0xb /* 1011 */ +#define XVE_SOURCE_MP1 0xa /* 1010 */ +#define XVE_SOURCE_MMQ 0x9 /* 1001 */ +#define XVE_SOURCE_MIQ 0x8 /* 1000 */ +#define XVE_SOURCE_NOQ 0x7 /* 0111 */ +#define XVE_SOURCE_NIQ 0x6 /* 0110 */ +#define XVE_SOURCE_IOQ 0x5 /* 0101 */ +#define XVE_SOURCE_IIQ 0x4 /* 0100 */ +#define XVE_SOURCE_LOQ 0x3 /* 0011 */ +#define XVE_SOURCE_LIQ 0x2 /* 0010 */ + +/* XB_PARMS fields */ +#define XBP_RESET_DEFAULTS 0x0008000080000021LL + +#endif /* _ASM_SN_SN1_HUBXB_NEXT_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/ip27config.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/ip27config.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/ip27config.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/ip27config.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,657 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_IP27CONFIG_H +#define _ASM_SN_SN1_IP27CONFIG_H + + +/* + * Structure: ip27config_s + * Typedef: ip27config_t + * Purpose: Maps out the region of the boot prom used to define + * configuration information. + * Notes: Corresponds to ip27config structure found in start.s. + * Fields are ulong where possible to facilitate IP27 PROM fetches. + */ + +#define CONFIG_INFO_OFFSET 0x60 + +#define IP27CONFIG_ADDR (LBOOT_BASE + \ + CONFIG_INFO_OFFSET) +#define IP27CONFIG_ADDR_NODE(n) (NODE_RBOOT_BASE(n) + \ + CONFIG_INFO_OFFSET) + +/* Offset to the config_type field within local ip27config structure */ +#define CONFIG_FLAGS_ADDR (IP27CONFIG_ADDR + 72) +/* Offset to the config_type field in the ip27config structure on + * node with nasid n + */ +#define CONFIG_FLAGS_ADDR_NODE(n) (IP27CONFIG_ADDR_NODE(n) + 72) + +/* Meaning of each valid bit in the config flags + * None are currently defined + */ + +/* Meaning of each mach_type value + */ +#define SN1_MACH_TYPE 0 + +/* + * Since 800 ns works well with various HUB frequencies, (such as 360, + * 380, 390, and 400 MHZ), we now use 800ns rtc cycle time instead of + * 1 microsec. + */ +#define IP27_RTC_FREQ 1250 /* 800ns cycle time */ + +#if _LANGUAGE_C + +typedef struct ip27config_s { /* KEEP IN SYNC w/ start.s & below */ + uint time_const; /* Time constant */ + uint r10k_mode; /* R10k boot mode bits */ + + uint64_t magic; /* CONFIG_MAGIC */ + + uint64_t freq_cpu; /* Hz */ + uint64_t freq_hub; /* Hz */ + uint64_t freq_rtc; /* Hz */ + + uint ecc_enable; /* ECC enable flag */ + uint fprom_cyc; /* FPROM_CYC speed control */ + + uint mach_type; /* Inidicate IP27 (0) or Sn00 (1) */ + + uint check_sum_adj; /* Used after config hdr overlay */ + /* to make the checksum 0 again */ + uint flash_count; /* Value incr'd on each PROM flash */ + uint fprom_wr; /* FPROM_WR speed control */ + + uint pvers_vers; /* Prom version number */ + uint pvers_rev; /* Prom revision number */ + uint config_type; /* To support special configurations + * (none currently defined) + */ +} ip27config_t; + +typedef struct { + uint r10k_mode; /* R10k boot mode bits */ + uint freq_cpu; /* Hz */ + uint freq_hub; /* Hz */ + char fprom_cyc; /* FPROM_CYC speed control */ + char mach_type; /* IP35(0) is only type defined */ + char fprom_wr; /* FPROM_WR speed control */ +} config_modifiable_t; + +#define IP27CONFIG (*(ip27config_t *) IP27CONFIG_ADDR) +#define IP27CONFIG_NODE(n) (*(ip27config_t *) IP27CONFIG_ADDR_NODE(n)) +#define SN00 0 /* IP35 has no Speedo equivalent */ + +/* Get the config flags from local ip27config */ +#define CONFIG_FLAGS (*(uint *) (CONFIG_FLAGS_ADDR)) + +/* Get the config flags from ip27config on the node + * with nasid n + */ +#define CONFIG_FLAGS_NODE(n) (*(uint *) (CONFIG_FLAGS_ADDR_NODE(n))) + +/* Macro to check if the local ip27config indicates a config + * of 12 p 4io + */ +#define CONFIG_12P4I (0) /* IP35 has no 12p4i equivalent */ + +/* Macro to check if the ip27config on node with nasid n + * indicates a config of 12 p 4io + */ +#define CONFIG_12P4I_NODE(n) (0) + +#endif /* _LANGUAGE_C */ + +#if _LANGUAGE_ASSEMBLY + .struct 0 /* KEEP IN SYNC WITH C structure */ + +ip27c_time_const: .word 0 +ip27c_r10k_mode: .word 0 + +ip27c_magic: .dword 0 + +ip27c_freq_cpu: .dword 0 +ip27c_freq_hub: .dword 0 +ip27c_freq_rtc: .dword 0 + +ip27c_ecc_enable: .word 1 +ip27c_fprom_cyc: .word 0 + +ip27c_mach_type: .word 0 +ip27c_check_sum_adj: .word 0 + +ip27c_flash_count: .word 0 +ip27c_fprom_wr: .word 0 + +ip27c_pvers_vers: .word 0 +ip27c_pvers_rev: .word 0 + +ip27c_config_type: .word 0 /* To recognize special configs */ +#endif /* _LANGUAGE_ASSEMBLY */ + +/* + * R10000 Configuration Cycle - These define the SYSAD values used + * during the reset cycle. + */ + +#define IP27C_R10000_KSEG0CA_SHFT 0 +#define IP27C_R10000_KSEG0CA_MASK (7 << IP27C_R10000_KSEG0CA_SHFT) +#define IP27C_R10000_KSEG0CA(_B) ((_B) << IP27C_R10000_KSEG0CA_SHFT) + +#define IP27C_R10000_DEVNUM_SHFT 3 +#define IP27C_R10000_DEVNUM_MASK (3 << IP27C_R10000_DEVNUM_SHFT) +#define IP27C_R10000_DEVNUM(_B) ((_B) << IP27C_R10000_DEVNUM_SHFT) + +#define IP27C_R10000_CRPT_SHFT 5 +#define IP27C_R10000_CRPT_MASK (1 << IP27C_R10000_CRPT_SHFT) +#define IP27C_R10000_CPRT(_B) ((_B)<33M) +-----------------------------------------+ + * | IP35 Topology (PCFG) + misc data | + * 0x2000000 (32M) +-----------------------------------------+ + * | IO7 BUFFERS FOR FLASH ENET IOC3 | + * 0x1F80000 (31.5M) +-----------------------------------------+ + * | Free | + * 0x1C00000 (28M) +-----------------------------------------+ + * | IP35 PROM TEXT/DATA/BSS/stack | + * 0x1A00000 (26M) +-----------------------------------------+ + * | Routing temp. space | + * 0x1800000 (24M) +-----------------------------------------+ + * | Diagnostics temp. space | + * 0x1500000 (21M) +-----------------------------------------+ + * | Free | + * 0x1400000 (20M) +-----------------------------------------+ + * | IO7 PROM temporary copy | + * 0x1300000 (19M) +-----------------------------------------+ + * | | + * | Free | + * | (UNIX DATA starts above 0x1000000) | + * | | + * +-----------------------------------------+ + * | UNIX DEBUG Version | + * 0x0310000 (3.1M) +-----------------------------------------+ + * | SYMMON, loaded just below UNIX | + * | (For UNIX Debug only) | + * | | + * | | + * 0x006C000 (432K) +-----------------------------------------+ + * | SYMMON STACK [NUM_CPU_PER_NODE] | + * | (For UNIX Debug only) | + * 0x004C000 (304K) +-----------------------------------------+ + * | | + * | | + * | UNIX NON-DEBUG Version | + * 0x0040000 (256K) +-----------------------------------------+ + * + * + * The lower portion of the memory map contains information that is + * permanent and is used by the IP35PROM, IO7PROM and IRIX. + * + * 0x40000 (256K) +-----------------------------------------+ + * | | + * | KLCONFIG (64K) | + * | | + * 0x30000 (192K) +-----------------------------------------+ + * | | + * | PI Error Spools (64K) | + * | | + * 0x20000 (128K) +-----------------------------------------+ + * | | + * | Unused | + * | | + * 0x19000 (100K) +-----------------------------------------+ + * | Early cache Exception stack (CPU 3)| + * 0x18800 (98K) +-----------------------------------------+ + * | cache error eframe (CPU 3) | + * 0x18400 (97K) +-----------------------------------------+ + * | Exception Handlers (CPU 3) | + * 0x18000 (96K) +-----------------------------------------+ + * | | + * | Unused | + * | | + * 0x13c00 (79K) +-----------------------------------------+ + * | GPDA (8k) | + * 0x11c00 (71K) +-----------------------------------------+ + * | Early cache Exception stack (CPU 2)| + * 0x10800 (66k) +-----------------------------------------+ + * | cache error eframe (CPU 2) | + * 0x10400 (65K) +-----------------------------------------+ + * | Exception Handlers (CPU 2) | + * 0x10000 (64K) +-----------------------------------------+ + * | | + * | Unused | + * | | + * 0x0b400 (45K) +-----------------------------------------+ + * | GDA (1k) | + * 0x0b000 (44K) +-----------------------------------------+ + * | NMI Eframe areas (4) | + * 0x0a000 (40K) +-----------------------------------------+ + * | NMI Register save areas (4) | + * 0x09000 (36K) +-----------------------------------------+ + * | Early cache Exception stack (CPU 1)| + * 0x08800 (34K) +-----------------------------------------+ + * | cache error eframe (CPU 1) | + * 0x08400 (33K) +-----------------------------------------+ + * | Exception Handlers (CPU 1) | + * 0x08000 (32K) +-----------------------------------------+ + * | | + * | | + * | Unused | + * | | + * | | + * 0x04000 (16K) +-----------------------------------------+ + * | NMI Handler (Protected Page) | + * 0x03000 (12K) +-----------------------------------------+ + * | ARCS PVECTORS (master node only) | + * 0x02c00 (11K) +-----------------------------------------+ + * | ARCS TVECTORS (master node only) | + * 0x02800 (10K) +-----------------------------------------+ + * | LAUNCH [NUM_CPU] | + * 0x02400 (9K) +-----------------------------------------+ + * | Low memory directory (KLDIR) | + * 0x02000 (8K) +-----------------------------------------+ + * | ARCS SPB (1K) | + * 0x01000 (4K) +-----------------------------------------+ + * | Early cache Exception stack (CPU 0)| + * 0x00800 (2k) +-----------------------------------------+ + * | cache error eframe (CPU 0) | + * 0x00400 (1K) +-----------------------------------------+ + * | Exception Handlers (CPU 0) | + * 0x00000 (0K) +-----------------------------------------+ + */ + +/* + * NOTE: To change the kernel load address, you must update: + * - the appropriate elspec files in irix/kern/master.d + * - NODEBUGUNIX_ADDR in SN/SN1/addrs.h + * - IP27_FREEMEM_OFFSET below + * - KERNEL_START_OFFSET below (if supporting cells) + */ + + +/* + * This is defined here because IP27_SYMMON_STK_SIZE must be at least what + * we define here. Since it's set up in the prom. We can't redefine it later + * and expect more space to be allocated. The way to find out the true size + * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE + * for a particular node. + */ +#define SYMMON_STACK_SIZE 0x8000 + +#if defined (PROM) || defined (SABLE) + +/* + * These defines are prom version dependent. No code other than the IP35 + * prom should attempt to use these values. + */ +#define IP27_LAUNCH_OFFSET 0x2400 +#define IP27_LAUNCH_SIZE 0x400 +#define IP27_LAUNCH_COUNT 4 +#define IP27_LAUNCH_STRIDE 0x100 /* could be as small as 0x80 */ + +#define IP27_KLCONFIG_OFFSET 0x30000 +#define IP27_KLCONFIG_SIZE 0x10000 +#define IP27_KLCONFIG_COUNT 1 +#define IP27_KLCONFIG_STRIDE 0 + +#define IP27_NMI_OFFSET 0x3000 +#define IP27_NMI_SIZE 0x100 +#define IP27_NMI_COUNT 4 +#define IP27_NMI_STRIDE 0x40 + +#define IP27_PI_ERROR_OFFSET 0x20000 +#define IP27_PI_ERROR_SIZE 0x10000 +#define IP27_PI_ERROR_COUNT 1 +#define IP27_PI_ERROR_STRIDE 0 + +#define IP27_SYMMON_STK_OFFSET 0x4c000 +#define IP27_SYMMON_STK_SIZE 0x20000 +#define IP27_SYMMON_STK_COUNT 4 +/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */ +#define IP27_SYMMON_STK_STRIDE 0x8000 + +#define IP27_FREEMEM_OFFSET 0x40000 +#define IP27_FREEMEM_SIZE -1 +#define IP27_FREEMEM_COUNT 1 +#define IP27_FREEMEM_STRIDE 0 + +#endif /* PROM || SABLE*/ +/* + * There will be only one of these in a partition so the IO7 must set it up. + */ +#define IO6_GDA_OFFSET 0xb000 +#define IO6_GDA_SIZE 0x400 +#define IO6_GDA_COUNT 1 +#define IO6_GDA_STRIDE 0 + +/* + * save area of kernel nmi regs in the prom format + */ +#define IP27_NMI_KREGS_OFFSET 0x9000 +#define IP27_NMI_KREGS_CPU_SIZE 0x400 +/* + * save area of kernel nmi regs in eframe format + */ +#define IP27_NMI_EFRAME_OFFSET 0xa000 +#define IP27_NMI_EFRAME_SIZE 0x400 + +#define GPDA_OFFSET 0x11c00 + +#endif /* _ASM_SN_SN1_KLDIR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/leds.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/leds.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/leds.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/leds.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,35 @@ +#ifndef _ASM_SN_SN1_LED_H +#define _ASM_SN_SN1_LED_H + +/* + * Copyright (C) 2000 Silicon Graphics, Inc + * Copyright (C) 2000 Jack Steiner (steiner@sgi.com) + */ + +#include + +#define LED0 0xc0000b00100000c0LL /* ZZZ fixme */ + + + +#define LED_AP_START 0x01 /* AP processor started */ +#define LED_AP_IDLE 0x01 + +/* + * Basic macros for flashing the LEDS on an SGI, SN1. + */ + +extern __inline__ void +HUB_SET_LED(int val) +{ + long *ledp; + int eid; + + eid = hard_processor_sapicid() & 3; + ledp = (long*) (LED0 + (eid<<3)); + *ledp = val; +} + + +#endif /* _ASM_SN_SN1_LED_H */ + diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/promlog.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/promlog.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/promlog.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/promlog.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,85 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_PROMLOG_H +#define _ASM_SN_SN1_PROMLOG_H + +#include + +#define PROMLOG_MAGIC 0x504c4f49 +#define PROMLOG_VERSION 1 + +#define PROMLOG_OFFSET_MAGIC 0x10 +#define PROMLOG_OFFSET_VERSION 0x14 +#define PROMLOG_OFFSET_SEQUENCE 0x18 +#define PROMLOG_OFFSET_ENTRY0 0x100 + +#define PROMLOG_ERROR_NONE 0 +#define PROMLOG_ERROR_PROM -1 +#define PROMLOG_ERROR_MAGIC -2 +#define PROMLOG_ERROR_CORRUPT -3 +#define PROMLOG_ERROR_BOL -4 +#define PROMLOG_ERROR_EOL -5 +#define PROMLOG_ERROR_POS -6 +#define PROMLOG_ERROR_REPLACE -7 +#define PROMLOG_ERROR_COMPACT -8 +#define PROMLOG_ERROR_FULL -9 +#define PROMLOG_ERROR_ARG -10 +#define PROMLOG_ERROR_UNUSED -11 + +#define PROMLOG_TYPE_UNUSED 0xf +#define PROMLOG_TYPE_LOG 3 +#define PROMLOG_TYPE_LIST 2 +#define PROMLOG_TYPE_VAR 1 +#define PROMLOG_TYPE_DELETED 0 + +#define PROMLOG_TYPE_ANY 98 +#define PROMLOG_TYPE_INVALID 99 + +#define PROMLOG_KEY_MAX 14 +#define PROMLOG_VALUE_MAX 47 +#define PROMLOG_CPU_MAX 4 + +typedef struct promlog_header_s { + unsigned int unused[4]; + unsigned int magic; + unsigned int version; + unsigned int sequence; +} promlog_header_t; + +typedef unsigned int promlog_pos_t; + +typedef struct promlog_ent_s { /* PROM individual entry */ + uint type : 4; + uint cpu_num : 4; + char key[PROMLOG_KEY_MAX + 1]; + + char value[PROMLOG_VALUE_MAX + 1]; + +} promlog_ent_t; + +typedef struct promlog_s { /* Activation handle */ + fprom_t f; + int sector_base; + int cpu_num; + + int active; /* Active sector, 0 or 1 */ + + promlog_pos_t log_start; + promlog_pos_t log_end; + + promlog_pos_t alt_start; + promlog_pos_t alt_end; + + promlog_pos_t pos; + promlog_ent_t ent; +} promlog_t; + +#endif /* _ASM_SN_SN1_PROMLOG_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/router.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/router.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/router.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/router.h Wed Dec 13 19:35:33 2000 @@ -0,0 +1,669 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_ROUTER_H +#define _ASM_SN_SN1_ROUTER_H + +/* + * Router Register definitions + * + * Macro argument _L always stands for a link number (1 to 8, inclusive). + */ + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +#include +#include +#include + +typedef uint64_t router_reg_t; + +#define MAX_ROUTERS 64 + +#define MAX_ROUTER_PATH 80 + +#define ROUTER_REG_CAST (volatile router_reg_t *) +#define PS_UINT_CAST (__psunsigned_t) +#define UINT64_CAST (uint64_t) +typedef signed char port_no_t; /* Type for router port number */ + +#elif _LANGUAGE_ASSEMBLY + +#define ROUTERREG_CAST +#define PS_UINT_CAST +#define UINT64_CAST + +#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ + +#define MAX_ROUTER_PORTS (8) /* Max. number of ports on a router */ + +#define ALL_PORTS ((1 << MAX_ROUTER_PORTS) - 1) /* for 0 based references */ + +#define PORT_INVALID (-1) /* Invalid port number */ + +#define IS_META(_rp) ((_rp)->flags & PCFG_ROUTER_META) + +#define IS_REPEATER(_rp)((_rp)->flags & PCFG_ROUTER_REPEATER) + +/* + * RR_TURN makes a given number of clockwise turns (0 to 7) from an inport + * port to generate an output port. + * + * RR_DISTANCE returns the number of turns necessary (0 to 7) to go from + * an input port (_L1 = 1 to 8) to an output port ( _L2 = 1 to 8). + * + * These are written to work on unsigned data. + */ + +#define RR_TURN(_L, count) ((_L) + (count) > MAX_ROUTER_PORTS ? \ + (_L) + (count) - MAX_ROUTER_PORTS : \ + (_L) + (count)) + +#define RR_DISTANCE(_LS, _LD) ((_LD) >= (_LS) ? \ + (_LD) - (_LS) : \ + (_LD) + MAX_ROUTER_PORTS - (_LS)) + +/* Router register addresses */ + +#define RR_STATUS_REV_ID 0x00000 /* Status register and Revision ID */ +#define RR_PORT_RESET 0x00008 /* Multiple port reset */ +#define RR_PROT_CONF 0x00010 /* Inter-partition protection conf. */ +#define RR_GLOBAL_PORT_DEF 0x00018 /* Global Port definitions */ +#define RR_GLOBAL_PARMS0 0x00020 /* Parameters shared by all 8 ports */ +#define RR_GLOBAL_PARMS1 0x00028 /* Parameters shared by all 8 ports */ +#define RR_DIAG_PARMS 0x00030 /* Parameters for diag. testing */ +#define RR_DEBUG_ADDR 0x00038 /* Debug address select - debug port*/ +#define RR_LB_TO_L2 0x00040 /* Local Block to L2 cntrl intf reg */ +#define RR_L2_TO_LB 0x00048 /* L2 cntrl intf to Local Block reg */ +#define RR_JBUS_CONTROL 0x00050 /* read/write timing for JBUS intf */ + +#define RR_SCRATCH_REG0 0x00100 /* Scratch 0 is 64 bits */ +#define RR_SCRATCH_REG1 0x00108 /* Scratch 1 is 64 bits */ +#define RR_SCRATCH_REG2 0x00110 /* Scratch 2 is 64 bits */ +#define RR_SCRATCH_REG3 0x00118 /* Scratch 3 is 1 bit */ +#define RR_SCRATCH_REG4 0x00120 /* Scratch 4 is 1 bit */ + +#define RR_JBUS0(_D) (((_D) & 0x7) << 3 | 0x00200) /* JBUS0 addresses */ +#define RR_JBUS1(_D) (((_D) & 0x7) << 3 | 0x00240) /* JBUS1 addresses */ + +#define RR_SCRATCH_REG0_WZ 0x00500 /* Scratch 0 is 64 bits */ +#define RR_SCRATCH_REG1_WZ 0x00508 /* Scratch 1 is 64 bits */ +#define RR_SCRATCH_REG2_WZ 0x00510 /* Scratch 2 is 64 bits */ +#define RR_SCRATCH_REG3_SZ 0x00518 /* Scratch 3 is 1 bit */ +#define RR_SCRATCH_REG4_SZ 0x00520 /* Scratch 4 is 1 bit */ + +#define RR_VECTOR_HW_BAR(context) (0x08000 | (context)<<3) /* barrier config registers */ +/* Port-specific registers (_L is the link number from 1 to 8) */ + +#define RR_PORT_PARMS(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0000) /* LLP parameters */ +#define RR_STATUS_ERROR(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0008) /* Port-related errs */ +#define RR_CHANNEL_TEST(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0010) /* Port LLP chan test */ +#define RR_RESET_MASK(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0018) /* Remote reset mask */ +#define RR_HISTOGRAM0(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0020) /* Port usage histgrm */ +#define RR_HISTOGRAM1(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0028) /* Port usage histgrm */ +#define RR_HISTOGRAM0_WC(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0030) /* Port usage histgrm */ +#define RR_HISTOGRAM1_WC(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0038) /* Port usage histgrm */ +#define RR_ERROR_CLEAR(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0088) /* Read/clear errors */ +#define RR_GLOBAL_TABLE0(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0100) /* starting address of global table for this port */ +#define RR_GLOBAL_TABLE(_L, _x) (RR_GLOBAL_TABLE0(_L) + ((_x) << 3)) +#define RR_LOCAL_TABLE0(_L) (((_L+1) & 0xe) << 15 | ((_L+1) & 0x1) << 11 | 0x0200) /* starting address of local table for this port */ +#define RR_LOCAL_TABLE(_L, _x) (RR_LOCAL_TABLE0(_L) + ((_x) << 3)) + +#define RR_META_ENTRIES 16 + +#define RR_LOCAL_ENTRIES 128 + +/* + * RR_STATUS_REV_ID mask and shift definitions + */ + +#define RSRI_INPORT_SHFT 52 +#define RSRI_INPORT_MASK (UINT64_CAST 0xf << 52) +#define RSRI_LINKWORKING_BIT(_L) (35 + 2 * (_L)) +#define RSRI_LINKWORKING(_L) (UINT64_CAST 1 << (35 + 2 * (_L))) +#define RSRI_LINKRESETFAIL(_L) (UINT64_CAST 1 << (34 + 2 * (_L))) +#define RSRI_LSTAT_SHFT(_L) (34 + 2 * (_L)) +#define RSRI_LSTAT_MASK(_L) (UINT64_CAST 0x3 << 34 + 2 * (_L)) +#define RSRI_LOCALSBERROR (UINT64_CAST 1 << 35) +#define RSRI_LOCALSTUCK (UINT64_CAST 1 << 34) +#define RSRI_LOCALBADVEC (UINT64_CAST 1 << 33) +#define RSRI_LOCALTAILERR (UINT64_CAST 1 << 32) +#define RSRI_LOCAL_SHFT 32 +#define RSRI_LOCAL_MASK (UINT64_CAST 0xf << 32) +#define RSRI_CHIPREV_SHFT 28 +#define RSRI_CHIPREV_MASK (UINT64_CAST 0xf << 28) +#define RSRI_CHIPID_SHFT 12 +#define RSRI_CHIPID_MASK (UINT64_CAST 0xffff << 12) +#define RSRI_MFGID_SHFT 1 +#define RSRI_MFGID_MASK (UINT64_CAST 0x7ff << 1) + +#define RSRI_LSTAT_WENTDOWN 0 +#define RSRI_LSTAT_RESETFAIL 1 +#define RSRI_LSTAT_LINKUP 2 +#define RSRI_LSTAT_NOTUSED 3 + +/* + * RR_PORT_RESET mask definitions + */ + +#define RPRESET_WARM (UINT64_CAST 1 << 9) +#define RPRESET_LINK(_L) (UINT64_CAST 1 << (_L)) +#define RPRESET_LOCAL (UINT64_CAST 1) + +/* + * RR_PROT_CONF mask and shift definitions + */ + +#define RPCONF_DIRCMPDIS_SHFT 13 +#define RPCONF_DIRCMPDIS_MASK (UINT64_CAST 1 << 13) +#define RPCONF_FORCELOCAL (UINT64_CAST 1 << 12) +#define RPCONF_FLOCAL_SHFT 12 +#define RPCONF_METAID_SHFT 8 +#define RPCONF_METAID_MASK (UINT64_CAST 0xf << 8) +#define RPCONF_RESETOK(_L) (UINT64_CAST 1 << ((_L) - 1)) + +/* + * RR_GLOBAL_PORT_DEF mask and shift definitions + */ + +#define RGPD_MGLBLNHBR_ID_SHFT 12 /* -global neighbor ID */ +#define RGPD_MGLBLNHBR_ID_MASK (UINT64_CAST 0xf << 12) +#define RGPD_MGLBLNHBR_VLD_SHFT 11 /* -global neighbor Valid */ +#define RGPD_MGLBLNHBR_VLD_MASK (UINT64_CAST 0x1 << 11) +#define RGPD_MGLBLPORT_SHFT 8 /* -global neighbor Port */ +#define RGPD_MGLBLPORT_MASK (UINT64_CAST 0x7 << 8) +#define RGPD_PGLBLNHBR_ID_SHFT 4 /* +global neighbor ID */ +#define RGPD_PGLBLNHBR_ID_MASK (UINT64_CAST 0xf << 4) +#define RGPD_PGLBLNHBR_VLD_SHFT 3 /* +global neighbor Valid */ +#define RGPD_PGLBLNHBR_VLD_MASK (UINT64_CAST 0x1 << 3) +#define RGPD_PGLBLPORT_SHFT 0 /* +global neighbor Port */ +#define RGPD_PGLBLPORT_MASK (UINT64_CAST 0x7 << 0) + +#define GLBL_PARMS_REGS 2 /* Two Global Parms registers */ + +/* + * RR_GLOBAL_PARMS0 mask and shift definitions + */ + +#define RGPARM0_ARB_VALUE_SHFT 54 /* Local Block Arbitration State */ +#define RGPARM0_ARB_VALUE_MASK (UINT64_CAST 0x7 << 54) +#define RGPARM0_ROTATEARB_SHFT 53 /* Rotate Local Block Arbitration */ +#define RGPARM0_ROTATEARB_MASK (UINT64_CAST 0x1 << 53) +#define RGPARM0_FAIREN_SHFT 52 /* Fairness logic Enable */ +#define RGPARM0_FAIREN_MASK (UINT64_CAST 0x1 << 52) +#define RGPARM0_LOCGNTTO_SHFT 40 /* Local grant timeout */ +#define RGPARM0_LOCGNTTO_MASK (UINT64_CAST 0xfff << 40) +#define RGPARM0_DATELINE_SHFT 38 /* Dateline crossing router */ +#define RGPARM0_DATELINE_MASK (UINT64_CAST 0x1 << 38) +#define RGPARM0_MAXRETRY_SHFT 28 /* Max retry count */ +#define RGPARM0_MAXRETRY_MASK (UINT64_CAST 0x3ff << 28) +#define RGPARM0_URGWRAP_SHFT 20 /* Urgent wrap */ +#define RGPARM0_URGWRAP_MASK (UINT64_CAST 0xff << 20) +#define RGPARM0_DEADLKTO_SHFT 16 /* Deadlock timeout */ +#define RGPARM0_DEADLKTO_MASK (UINT64_CAST 0xf << 16) +#define RGPARM0_URGVAL_SHFT 12 /* Urgent value */ +#define RGPARM0_URGVAL_MASK (UINT64_CAST 0xf << 12) +#define RGPARM0_VCHSELEN_SHFT 11 /* VCH_SEL_EN */ +#define RGPARM0_VCHSELEN_MASK (UINT64_CAST 0x1 << 11) +#define RGPARM0_LOCURGTO_SHFT 9 /* Local urgent timeout */ +#define RGPARM0_LOCURGTO_MASK (UINT64_CAST 0x3 << 9) +#define RGPARM0_TAILVAL_SHFT 5 /* Tail value */ +#define RGPARM0_TAILVAL_MASK (UINT64_CAST 0xf << 5) +#define RGPARM0_CLOCK_SHFT 1 /* Global clock select */ +#define RGPARM0_CLOCK_MASK (UINT64_CAST 0xf << 1) +#define RGPARM0_BYPEN_SHFT 0 +#define RGPARM0_BYPEN_MASK (UINT64_CAST 1) /* Bypass enable */ + +/* + * RR_GLOBAL_PARMS1 shift and mask definitions + */ + +#define RGPARM1_TTOWRAP_SHFT 12 /* Tail timeout wrap */ +#define RGPARM1_TTOWRAP_MASK (UINT64_CAST 0xfffff << 12) +#define RGPARM1_AGERATE_SHFT 8 /* Age rate */ +#define RGPARM1_AGERATE_MASK (UINT64_CAST 0xf << 8) +#define RGPARM1_JSWSTAT_SHFT 0 /* JTAG Sw Register bits */ +#define RGPARM1_JSWSTAT_MASK (UINT64_CAST 0xff << 0) + +/* + * RR_DIAG_PARMS mask and shift definitions + */ + +#define RDPARM_ABSHISTOGRAM (UINT64_CAST 1 << 17) /* Absolute histgrm */ +#define RDPARM_DEADLOCKRESET (UINT64_CAST 1 << 16) /* Reset on deadlck */ +#define RDPARM_DISABLE(_L) (UINT64_CAST 1 << ((_L) + 7)) +#define RDPARM_SENDERROR(_L) (UINT64_CAST 1 << ((_L) - 1)) + +/* + * RR_DEBUG_ADDR mask and shift definitions + */ + +#define RDA_DATA_SHFT 10 /* Observed debug data */ +#define RDA_DATA_MASK (UINT64_CAST 0xffff << 10) +#define RDA_ADDR_SHFT 0 /* debug address for data */ +#define RDA_ADDR_MASK (UINT64_CAST 0x3ff << 0) + +/* + * RR_LB_TO_L2 mask and shift definitions + */ + +#define RLBTOL2_DATA_VLD_SHFT 32 /* data is valid for JTAG controller */ +#define RLBTOL2_DATA_VLD_MASK (UINT64_CAST 0x1 << 32) +#define RLBTOL2_DATA_SHFT 0 /* data bits for JTAG controller */ +#define RLBTOL2_DATA_MASK (UINT64_CAST 0xffffffff) + +/* + * RR_L2_TO_LB mask and shift definitions + */ + +#define RL2TOLB_DATA_VLD_SHFT 33 /* data is valid from JTAG controller */ +#define RL2TOLB_DATA_VLD_MASK (UINT64_CAST 0x1 << 33) +#define RL2TOLB_PARITY_SHFT 32 /* sw implemented parity for data */ +#define RL2TOLB_PARITY_MASK (UINT64_CAST 0x1 << 32) +#define RL2TOLB_DATA_SHFT 0 /* data bits from JTAG controller */ +#define RL2TOLB_DATA_MASK (UINT64_CAST 0xffffffff) + +/* + * RR_JBUS_CONTROL mask and shift definitions + */ + +#define RJC_POS_BITS_SHFT 20 /* Router position bits */ +#define RJC_POS_BITS_MASK (UINT64_CAST 0xf << 20) +#define RJC_RD_DATA_STROBE_SHFT 16 /* count when read data is strobed in */ +#define RJC_RD_DATA_STROBE_MASK (UINT64_CAST 0xf << 16) +#define RJC_WE_OE_HOLD_SHFT 8 /* time OE or WE is held */ +#define RJC_WE_OE_HOLD_MASK (UINT64_CAST 0xff << 8) +#define RJC_ADDR_SET_HLD_SHFT 0 /* time address driven around OE/WE */ +#define RJC_ADDR_SET_HLD_MASK (UINT64_CAST 0xff) + +/* + * RR_SCRATCH_REGx mask and shift definitions + * note: these fields represent a software convention, and are not + * understood/interpreted by the hardware. + */ + +#define RSCR0_BOOTED_SHFT 63 +#define RSCR0_BOOTED_MASK (UINT64_CAST 0x1 << RSCR0_BOOTED_SHFT) +#define RSCR0_LOCALID_SHFT 56 +#define RSCR0_LOCALID_MASK (UINT64_CAST 0x7f << RSCR0_LOCALID_SHFT) +#define RSCR0_UNUSED_SHFT 48 +#define RSCR0_UNUSED_MASK (UINT64_CAST 0xff << RSCR0_UNUSED_SHFT) +#define RSCR0_NIC_SHFT 0 +#define RSCR0_NIC_MASK (UINT64_CAST 0xffffffffffff) + +#define RSCR1_MODID_SHFT 0 +#define RSCR1_MODID_MASK (UINT64_CAST 0xffff) + +/* + * RR_VECTOR_HW_BAR mask and shift definitions + */ + +#define BAR_TX_SHFT 27 /* Barrier in trans(m)it when read */ +#define BAR_TX_MASK (UINT64_CAST 1 << BAR_TX_SHFT) +#define BAR_VLD_SHFT 26 /* Valid Configuration */ +#define BAR_VLD_MASK (UINT64_CAST 1 << BAR_VLD_SHFT) +#define BAR_SEQ_SHFT 24 /* Sequence number */ +#define BAR_SEQ_MASK (UINT64_CAST 3 << BAR_SEQ_SHFT) +#define BAR_LEAFSTATE_SHFT 18 /* Leaf State */ +#define BAR_LEAFSTATE_MASK (UINT64_CAST 0x3f << BAR_LEAFSTATE_SHFT) +#define BAR_PARENT_SHFT 14 /* Parent Port */ +#define BAR_PARENT_MASK (UINT64_CAST 0xf << BAR_PARENT_SHFT) +#define BAR_CHILDREN_SHFT 6 /* Child Select port bits */ +#define BAR_CHILDREN_MASK (UINT64_CAST 0xff << BAR_CHILDREN_SHFT) +#define BAR_LEAFCOUNT_SHFT 0 /* Leaf Count to trigger parent */ +#define BAR_LEAFCOUNT_MASK (UINT64_CAST 0x3f) + +/* + * RR_PORT_PARMS(_L) mask and shift definitions + */ + +#define RPPARM_MIPRESETEN_SHFT 29 /* Message In Progress reset enable */ +#define RPPARM_MIPRESETEN_MASK (UINT64_CAST 0x1 << 29) +#define RPPARM_UBAREN_SHFT 28 /* Enable user barrier requests */ +#define RPPARM_UBAREN_MASK (UINT64_CAST 0x1 << 28) +#define RPPARM_OUTPDTO_SHFT 24 /* Output Port Deadlock TO value */ +#define RPPARM_OUTPDTO_MASK (UINT64_CAST 0xf << 24) +#define RPPARM_PORTMATE_SHFT 21 /* Port Mate for the port */ +#define RPPARM_PORTMATE_MASK (UINT64_CAST 0x7 << 21) +#define RPPARM_HISTEN_SHFT 20 /* Histogram counter enable */ +#define RPPARM_HISTEN_MASK (UINT64_CAST 0x1 << 20) +#define RPPARM_HISTSEL_SHFT 18 +#define RPPARM_HISTSEL_MASK (UINT64_CAST 0x3 << 18) +#define RPPARM_DAMQHS_SHFT 16 +#define RPPARM_DAMQHS_MASK (UINT64_CAST 0x3 << 16) +#define RPPARM_NULLTO_SHFT 10 +#define RPPARM_NULLTO_MASK (UINT64_CAST 0x3f << 10) +#define RPPARM_MAXBURST_SHFT 0 +#define RPPARM_MAXBURST_MASK (UINT64_CAST 0x3ff) + +/* + * NOTE: Normally the kernel tracks only UTILIZATION statistics. + * The other 2 should not be used, except during any experimentation + * with the router. + */ +#define RPPARM_HISTSEL_AGE 0 /* Histogram age characterization. */ +#define RPPARM_HISTSEL_UTIL 1 /* Histogram link utilization */ +#define RPPARM_HISTSEL_DAMQ 2 /* Histogram DAMQ characterization. */ + +/* + * RR_STATUS_ERROR(_L) and RR_ERROR_CLEAR(_L) mask and shift definitions + */ +#define RSERR_POWERNOK (UINT64_CAST 1 << 38) +#define RSERR_PORT_DEADLOCK (UINT64_CAST 1 << 37) +#define RSERR_WARMRESET (UINT64_CAST 1 << 36) +#define RSERR_LINKRESET (UINT64_CAST 1 << 35) +#define RSERR_RETRYTIMEOUT (UINT64_CAST 1 << 34) +#define RSERR_FIFOOVERFLOW (UINT64_CAST 1 << 33) +#define RSERR_ILLEGALPORT (UINT64_CAST 1 << 32) +#define RSERR_DEADLOCKTO_SHFT 28 +#define RSERR_DEADLOCKTO_MASK (UINT64_CAST 0xf << 28) +#define RSERR_RECVTAILTO_SHFT 24 +#define RSERR_RECVTAILTO_MASK (UINT64_CAST 0xf << 24) +#define RSERR_RETRYCNT_SHFT 16 +#define RSERR_RETRYCNT_MASK (UINT64_CAST 0xff << 16) +#define RSERR_CBERRCNT_SHFT 8 +#define RSERR_CBERRCNT_MASK (UINT64_CAST 0xff << 8) +#define RSERR_SNERRCNT_SHFT 0 +#define RSERR_SNERRCNT_MASK (UINT64_CAST 0xff << 0) + + +#define PORT_STATUS_UP (1 << 0) /* Router link up */ +#define PORT_STATUS_FENCE (1 << 1) /* Router link fenced */ +#define PORT_STATUS_RESETFAIL (1 << 2) /* Router link didnot + * come out of reset */ +#define PORT_STATUS_DISCFAIL (1 << 3) /* Router link failed after + * out of reset but before + * router tables were + * programmed + */ +#define PORT_STATUS_KERNFAIL (1 << 4) /* Router link failed + * after reset and the + * router tables were + * programmed + */ +#define PORT_STATUS_UNDEF (1 << 5) /* Unable to pinpoint + * why the router link + * went down + */ +#define PROBE_RESULT_BAD (-1) /* Set if any of the router + * links failed after reset + */ +#define PROBE_RESULT_GOOD (0) /* Set if all the router links + * which came out of reset + * are up + */ + +/* Should be enough for 256 CPUs */ +#define MAX_RTR_BREADTH 64 /* Max # of routers possible */ + +/* Get the require set of bits in a var. corr to a sequence of bits */ +#define GET_FIELD(var, fname) \ + ((var) >> fname##_SHFT & fname##_MASK >> fname##_SHFT) +/* Set the require set of bits in a var. corr to a sequence of bits */ +#define SET_FIELD(var, fname, fval) \ + ((var) = (var) & ~fname##_MASK | (uint64_t) (fval) << fname##_SHFT) + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +typedef struct router_map_ent_s { + uint64_t nic; + moduleid_t module; + slotid_t slot; +} router_map_ent_t; + +struct rr_status_error_fmt { + uint64_t rserr_unused : 30, + rserr_fifooverflow : 1, + rserr_illegalport : 1, + rserr_deadlockto : 4, + rserr_recvtailto : 4, + rserr_retrycnt : 8, + rserr_cberrcnt : 8, + rserr_snerrcnt : 8; +}; + +/* + * This type is used to store "absolute" counts of router events + */ +typedef int router_count_t; + +/* All utilizations are on a scale from 0 - 1023. */ +#define RP_BYPASS_UTIL 0 +#define RP_RCV_UTIL 1 +#define RP_SEND_UTIL 2 +#define RP_TOTAL_PKTS 3 /* Free running clock/packet counter */ + +#define RP_NUM_UTILS 3 + +#define RP_HIST_REGS 2 +#define RP_NUM_BUCKETS 4 +#define RP_HIST_TYPES 3 + +#define RP_AGE0 0 +#define RP_AGE1 1 +#define RP_AGE2 2 +#define RP_AGE3 3 + + +#define RR_UTIL_SCALE 1024 + +/* + * Router port-oriented information + */ +typedef struct router_port_info_s { + router_reg_t rp_histograms[RP_HIST_REGS];/* Port usage info */ + router_reg_t rp_port_error; /* Port error info */ + router_count_t rp_retry_errors; /* Total retry errors */ + router_count_t rp_sn_errors; /* Total sn errors */ + router_count_t rp_cb_errors; /* Total cb errors */ + int rp_overflows; /* Total count overflows */ + int rp_excess_err; /* Port has excessive errors */ + ushort rp_util[RP_NUM_BUCKETS];/* Port utilization */ +} router_port_info_t; + +#define ROUTER_INFO_VERSION 7 + +struct lboard_s; + +/* + * Router information + */ +typedef struct router_info_s { + char ri_version; /* structure version */ + cnodeid_t ri_cnode; /* cnode of its legal guardian hub */ + nasid_t ri_nasid; /* Nasid of same */ + char ri_ledcache; /* Last LED bitmap */ + char ri_leds; /* Current LED bitmap */ + char ri_portmask; /* Active port bitmap */ + router_reg_t ri_stat_rev_id; /* Status rev ID value */ + net_vec_t ri_vector; /* vector from guardian to router */ + int ri_writeid; /* router's vector write ID */ + int64_t ri_timebase; /* Time of first sample */ + int64_t ri_timestamp; /* Time of last sample */ + router_port_info_t ri_port[MAX_ROUTER_PORTS]; /* per port info */ + moduleid_t ri_module; /* Which module are we in? */ + slotid_t ri_slotnum; /* Which slot are we in? */ + router_reg_t ri_glbl_parms[GLBL_PARMS_REGS]; + /* Global parms0&1 register contents*/ + devfs_handle_t ri_vertex; /* hardware graph vertex */ + router_reg_t ri_prot_conf; /* protection config. register */ + int64_t ri_per_minute; /* Ticks per minute */ + + /* + * Everything below here is for kernel use only and may change at + * at any time with or without a change in teh revision number + * + * Any pointers or things that come and go with DEBUG must go at + * the bottom of the structure, below the user stuff. + */ + char ri_hist_type; /* histogram type */ + devfs_handle_t ri_guardian; /* guardian node for the router */ + int64_t ri_last_print; /* When did we last print */ + char ri_print; /* Should we print */ + char ri_just_blink; /* Should we blink the LEDs */ + +#ifdef DEBUG + int64_t ri_deltatime; /* Time it took to sample */ +#endif + lock_t ri_lock; /* Lock for access to router info */ + net_vec_t *ri_vecarray; /* Pointer to array of vectors */ + struct lboard_s *ri_brd; /* Pointer to board structure */ + char * ri_name; /* This board's hwg path */ + unsigned char ri_port_maint[MAX_ROUTER_PORTS]; /* should we send a + message to availmon */ +} router_info_t; + + +/* Router info location specifiers */ + +#define RIP_PROMLOG 2 /* Router info in promlog */ +#define RIP_CONSOLE 4 /* Router info on console */ + +#define ROUTER_INFO_PRINT(_rip,_where) (_rip->ri_print |= _where) + /* Set the field used to check if a + * router info can be printed + */ +#define IS_ROUTER_INFO_PRINTED(_rip,_where) \ + (_rip->ri_print & _where) + /* Was the router info printed to + * the given location (_where) ? + * Mainly used to prevent duplicate + * router error states. + */ +#define ROUTER_INFO_LOCK(_rip,_s) _s = mutex_spinlock(&(_rip->ri_lock)) + /* Take the lock on router info + * to gain exclusive access + */ +#define ROUTER_INFO_UNLOCK(_rip,_s) mutex_spinunlock(&(_rip->ri_lock),_s) + /* Release the lock on router info */ +/* + * Router info hanging in the nodepda + */ +typedef struct nodepda_router_info_s { + devfs_handle_t router_vhdl; /* vertex handle of the router */ + short router_port; /* port thru which we entered */ + short router_portmask; + moduleid_t router_module; /* module in which router is there */ + slotid_t router_slot; /* router slot */ + unsigned char router_type; /* kind of router */ + net_vec_t router_vector; /* vector from the guardian node */ + + router_info_t *router_infop; /* info hanging off the hwg vertex */ + struct nodepda_router_info_s *router_next; + /* pointer to next element */ +} nodepda_router_info_t; + +#define ROUTER_NAME_SIZE 20 /* Max size of a router name */ + +#define NORMAL_ROUTER_NAME "normal_router" +#define NULL_ROUTER_NAME "null_router" +#define META_ROUTER_NAME "meta_router" +#define UNKNOWN_ROUTER_NAME "unknown_router" + +/* The following definitions are needed by the router traversing + * code either using the hardware graph or using vector operations. + */ +/* Structure of the router queue element */ +typedef struct router_elt_s { + union { + /* queue element structure during router probing */ + struct { + /* number-in-a-can (unique) for the router */ + nic_t nic; + /* vector route from the master hub to + * this router. + */ + net_vec_t vec; + /* port status */ + uint64_t status; + char port_status[MAX_ROUTER_PORTS + 1]; + } r_elt; + /* queue element structure during router guardian + * assignment + */ + struct { + /* vertex handle for the router */ + devfs_handle_t vhdl; + /* guardian for this router */ + devfs_handle_t guard; + /* vector router from the guardian to the router */ + net_vec_t vec; + } k_elt; + } u; + /* easy to use port status interpretation */ +} router_elt_t; + +/* structure of the router queue */ + +typedef struct router_queue_s { + char head; /* Point where a queue element is inserted */ + char tail; /* Point where a queue element is removed */ + int type; + router_elt_t array[MAX_RTR_BREADTH]; + /* Entries for queue elements */ +} router_queue_t; + + +#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ + +/* + * RR_HISTOGRAM(_L) mask and shift definitions + * There are two 64 bit histogram registers, so the following macros take + * into account dealing with an array of 4 32 bit values indexed by _x + */ + +#define RHIST_BUCKET_SHFT(_x) (32 * ((_x) & 0x1)) +#define RHIST_BUCKET_MASK(_x) (UINT64_CAST 0xffffffff << RHIST_BUCKET_SHFT((_x) & 0x1)) +#define RHIST_GET_BUCKET(_x, _reg) \ + ((RHIST_BUCKET_MASK(_x) & ((_reg)[(_x) >> 1])) >> RHIST_BUCKET_SHFT(_x)) + +/* + * RR_RESET_MASK(_L) mask and shift definitions + */ + +#define RRM_RESETOK(_L) (UINT64_CAST 1 << ((_L) - 1)) +#define RRM_RESETOK_ALL (UINT64_CAST 0x3f) + +/* + * RR_META_TABLE(_x) and RR_LOCAL_TABLE(_x) mask and shift definitions + */ + +#define RTABLE_SHFT(_L) (4 * ((_L) - 1)) +#define RTABLE_MASK(_L) (UINT64_CAST 0x7 << RTABLE_SHFT(_L)) + + +#define ROUTERINFO_STKSZ 4096 + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +#if defined(_LANGUAGE_C_PLUS_PLUS) +extern "C" { +#endif + +int router_reg_read(router_info_t *rip, int regno, router_reg_t *val); +int router_reg_write(router_info_t *rip, int regno, router_reg_t val); +int router_get_info(devfs_handle_t routerv, router_info_t *, int); +int router_init(cnodeid_t cnode,int writeid, nodepda_router_info_t *npda_rip); +int router_set_leds(router_info_t *rip); +void router_print_state(router_info_t *rip, int level, + void (*pf)(int, char *, ...),int print_where); +void capture_router_stats(router_info_t *rip); + + +int probe_routers(void); +void get_routername(unsigned char brd_type,char *rtrname); +void router_guardians_set(devfs_handle_t hwgraph_root); +int router_hist_reselect(router_info_t *, int64_t); +#if defined(_LANGUAGE_C_PLUS_PLUS) +} +#endif +#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ + +#endif /* _ASM_SN_SN1_ROUTER_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/slotnum.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/slotnum.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/slotnum.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/slotnum.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,86 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +#ifndef _ASM_SN_SN1_SLOTNUM_H +#define _ASM_SN_SN1_SLOTNUM_H + +#define SLOTNUM_MAXLENGTH 16 + +/* + * This file attempts to define a slot number space across all slots + * a IP27 module. Here, we deal with the top level slots. + * + * Node slots + * Router slots + * Crosstalk slots + * + * Other slots are children of their parent crosstalk slot: + * PCI slots + * VME slots + */ +// #include + +// #ifdef NOTDEF /* moved to sys/slotnum.h */ +#define SLOTNUM_NODE_CLASS 0x00 /* Node */ +#define SLOTNUM_ROUTER_CLASS 0x10 /* Router */ +#define SLOTNUM_XTALK_CLASS 0x20 /* Xtalk */ +#define SLOTNUM_MIDPLANE_CLASS 0x30 /* Midplane */ +#define SLOTNUM_XBOW_CLASS 0x40 /* Xbow */ +#define SLOTNUM_KNODE_CLASS 0x50 /* Kego node */ +#define SLOTNUM_INVALID_CLASS 0xf0 /* Invalid */ + +#define SLOTNUM_CLASS_MASK 0xf0 +#define SLOTNUM_SLOT_MASK 0x0f + +#define SLOTNUM_GETCLASS(_sn) ((_sn) & SLOTNUM_CLASS_MASK) +#define SLOTNUM_GETSLOT(_sn) ((_sn) & SLOTNUM_SLOT_MASK) +// #endif /* NOTDEF */ + +/* This determines module to pnode mapping. */ +/* NODESLOTS_PER_MODULE has changed from 4 to 6 + * to support the 12P 4IO configuration. This change + * helps in minimum number of changes to code which + * depend on the number of node boards within a module. + */ +#define NODESLOTS_PER_MODULE 6 +#define NODESLOTS_PER_MODULE_SHFT 2 + +#define HIGHEST_I2C_VISIBLE_NODESLOT 4 +#define RTRSLOTS_PER_MODULE 2 + +#if __KERNEL__ +#include + +extern slotid_t xbwidget_to_xtslot(int crossbow, int widget); +extern slotid_t hub_slotbits_to_slot(slotid_t slotbits); +extern slotid_t hub_slot_to_crossbow(slotid_t hub_slot); +extern slotid_t router_slotbits_to_slot(slotid_t slotbits); +extern slotid_t get_node_slotid(nasid_t nasid); +extern slotid_t get_my_slotid(void); +extern slotid_t get_node_crossbow(nasid_t); +extern xwidgetnum_t hub_slot_to_widget(slotid_t); +extern void get_slotname(slotid_t, char *); +extern void get_my_slotname(char *); +extern slotid_t get_widget_slotnum(int xbow, int widget); +extern void get_widget_slotname(int, int, char *); +extern void router_slotbits_to_slotname(int, char *); +extern slotid_t meta_router_slotbits_to_slot(slotid_t) ; +extern slotid_t hub_slot_get(void); + +extern int node_can_talk_to_elsc(void); + +extern int slot_to_widget(int) ; +#define MAX_IO_SLOT_NUM 12 +#define MAX_NODE_SLOT_NUM 4 +#define MAX_ROUTER_SLOTNUM 2 + +#endif /* __KERNEL__ */ + +#endif /* _ASM_SN_SN1_SLOTNUM_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/sn1.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/sn1.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/sn1.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/sn1.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,34 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ + +/* + * sn1.h -- hardware specific defines for sn1 boards + * The defines used here are used to limit the size of + * various datastructures in the PROM. eg. KLCFGINFO, MPCONF etc. + */ + +#ifndef _ASM_SN_SN1_SN1_H +#define _ASM_SN_SN1_SN1_H + +extern xwidgetnum_t hub_widget_id(nasid_t); +extern nasid_t get_nasid(void); +extern int get_slice(void); +extern int is_fine_dirmode(void); +extern hubreg_t get_hub_chiprev(nasid_t nasid); +extern hubreg_t get_region(cnodeid_t); +extern hubreg_t nasid_to_region(nasid_t); +extern int verify_snchip_rev(void); +extern void ni_reset_port(void); + +#ifdef SN1_USE_POISON_BITS +extern int hub_bte_poison_ok(void); +#endif /* SN1_USE_POISON_BITS */ + +#endif /* _ASM_SN_SN1_SN1_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/uart16550.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/uart16550.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/uart16550.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/uart16550.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,214 @@ + +/* + * Definitions for 16550 chip + */ + + /* defined as offsets from the data register */ +#define REG_DAT 0 /* receive/transmit data */ +#define REG_ICR 1 /* interrupt control register */ +#define REG_ISR 2 /* interrupt status register */ +#define REG_FCR 2 /* fifo control register */ +#define REG_LCR 3 /* line control register */ +#define REG_MCR 4 /* modem control register */ +#define REG_LSR 5 /* line status register */ +#define REG_MSR 6 /* modem status register */ +#define REG_SCR 7 /* Scratch register */ +#define REG_DLL 0 /* divisor latch (lsb) */ +#define REG_DLH 1 /* divisor latch (msb) */ +#define REG_EFR 2 /* 16650 enhanced feature register */ + +/* + * 16450/16550 Registers Structure. + */ + +/* Line Control Register */ +#define LCR_WLS0 0x01 /*word length select bit 0 */ +#define LCR_WLS1 0x02 /*word length select bit 2 */ +#define LCR_STB 0x04 /* number of stop bits */ +#define LCR_PEN 0x08 /* parity enable */ +#define LCR_EPS 0x10 /* even parity select */ +#define LCR_SETBREAK 0x40 /* break key */ +#define LCR_DLAB 0x80 /* divisor latch access bit */ +#define LCR_RXLEN 0x03 /* # of data bits per received/xmitted char */ +#define LCR_STOP1 0x00 +#define LCR_STOP2 0x04 +#define LCR_PAREN 0x08 +#define LCR_PAREVN 0x10 +#define LCR_PARMARK 0x20 +#define LCR_SNDBRK 0x40 +#define LCR_DLAB 0x80 + + +#define LCR_BITS5 0x00 /* 5 bits per char */ +#define LCR_BITS6 0x01 /* 6 bits per char */ +#define LCR_BITS7 0x02 /* 7 bits per char */ +#define LCR_BITS8 0x03 /* 8 bits per char */ + +#define LCR_MASK_BITS_CHAR 0x03 +#define LCR_MASK_STOP_BITS 0x04 +#define LCR_MASK_PARITY_BITS 0x18 + + +/* Line Status Register */ +#define LSR_RCA 0x01 /* data ready */ +#define LSR_OVRRUN 0x02 /* overrun error */ +#define LSR_PARERR 0x04 /* parity error */ +#define LSR_FRMERR 0x08 /* framing error */ +#define LSR_BRKDET 0x10 /* a break has arrived */ +#define LSR_XHRE 0x20 /* tx hold reg is now empty */ +#define LSR_XSRE 0x40 /* tx shift reg is now empty */ +#define LSR_RFBE 0x80 /* rx FIFO Buffer error */ + +/* Interrupt Status Regisger */ +#define ISR_MSTATUS 0x00 +#define ISR_TxRDY 0x02 +#define ISR_RxRDY 0x04 +#define ISR_ERROR_INTR 0x08 +#define ISR_FFTMOUT 0x0c /* FIFO Timeout */ +#define ISR_RSTATUS 0x06 /* Receiver Line status */ + +/* Interrupt Enable Register */ +#define ICR_RIEN 0x01 /* Received Data Ready */ +#define ICR_TIEN 0x02 /* Tx Hold Register Empty */ +#define ICR_SIEN 0x04 /* Receiver Line Status */ +#define ICR_MIEN 0x08 /* Modem Status */ + +/* Modem Control Register */ +#define MCR_DTR 0x01 /* Data Terminal Ready */ +#define MCR_RTS 0x02 /* Request To Send */ +#define MCR_OUT1 0x04 /* Aux output - not used */ +#define MCR_OUT2 0x08 /* turns intr to 386 on/off */ +#define MCR_LOOP 0x10 /* loopback for diagnostics */ +#define MCR_AFE 0x20 /* Auto flow control enable */ + +/* Modem Status Register */ +#define MSR_DCTS 0x01 /* Delta Clear To Send */ +#define MSR_DDSR 0x02 /* Delta Data Set Ready */ +#define MSR_DRI 0x04 /* Trail Edge Ring Indicator */ +#define MSR_DDCD 0x08 /* Delta Data Carrier Detect */ +#define MSR_CTS 0x10 /* Clear To Send */ +#define MSR_DSR 0x20 /* Data Set Ready */ +#define MSR_RI 0x40 /* Ring Indicator */ +#define MSR_DCD 0x80 /* Data Carrier Detect */ + +#define DELTAS(x) ((x)&(MSR_DCTS|MSR_DDSR|MSR_DRI|MSR_DDCD)) +#define STATES(x) ((x)(MSR_CTS|MSR_DSR|MSR_RI|MSR_DCD)) + + +#define FCR_FIFOEN 0x01 /* enable receive/transmit fifo */ +#define FCR_RxFIFO 0x02 /* enable receive fifo */ +#define FCR_TxFIFO 0x04 /* enable transmit fifo */ +#define FCR_MODE1 0x08 /* change to mode 1 */ +#define RxLVL0 0x00 /* Rx fifo level at 1 */ +#define RxLVL1 0x40 /* Rx fifo level at 4 */ +#define RxLVL2 0x80 /* Rx fifo level at 8 */ +#define RxLVL3 0xc0 /* Rx fifo level at 14 */ + +#define FIFOEN (FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL3 | FCR_MODE1) + +#define FCT_TxMASK 0x30 /* mask for Tx trigger */ +#define FCT_RxMASK 0xc0 /* mask for Rx trigger */ + +/* enhanced festures register */ +#define EFR_SFLOW 0x0f /* various S/w Flow Controls */ +#define EFR_EIC 0x10 /* Enhanced Interrupt Control bit */ +#define EFR_SCD 0x20 /* Special Character Detect */ +#define EFR_RTS 0x40 /* RTS flow control */ +#define EFR_CTS 0x80 /* CTS flow control */ + +/* Rx Tx software flow controls in 16650 enhanced mode */ +#define SFLOW_Tx0 0x00 /* no Xmit flow control */ +#define SFLOW_Tx1 0x08 /* Transmit Xon1, Xoff1 */ +#define SFLOW_Tx2 0x04 /* Transmit Xon2, Xoff2 */ +#define SFLOW_Tx3 0x0c /* Transmit Xon1,Xon2, Xoff1,Xoff2 */ +#define SFLOW_Rx0 0x00 /* no Rcv flow control */ +#define SFLOW_Rx1 0x02 /* Receiver compares Xon1, Xoff1 */ +#define SFLOW_Rx2 0x01 /* Receiver compares Xon2, Xoff2 */ + +#define ASSERT_DTR(x) (x |= MCR_DTR) +#define ASSERT_RTS(x) (x |= MCR_RTS) +#define DU_RTS_ASSERTED(x) (((x) & MCR_RTS) != 0) +#define DU_RTS_ASSERT(x) ((x) |= MCR_RTS) +#define DU_RTS_DEASSERT(x) ((x) &= ~MCR_RTS) + + +/* + * ioctl(fd, I_STR, arg) + * use the SIOC_RS422 and SIOC_EXTCLK combination to support MIDI + */ +#define SIOC ('z' << 8) /* z for z85130 */ +#define SIOC_EXTCLK (SIOC | 1) /* select/de-select external clock */ +#define SIOC_RS422 (SIOC | 2) /* select/de-select RS422 protocol */ +#define SIOC_ITIMER (SIOC | 3) /* upstream timer adjustment */ +#define SIOC_LOOPBACK (SIOC | 4) /* diagnostic loopback test mode */ + + +/* channel control register */ +#define DMA_INT_MASK 0xe0 /* ring intr mask */ +#define DMA_INT_TH25 0x20 /* 25% threshold */ +#define DMA_INT_TH50 0x40 /* 50% threshold */ +#define DMA_INT_TH75 0x60 /* 75% threshold */ +#define DMA_INT_EMPTY 0x80 /* ring buffer empty */ +#define DMA_INT_NEMPTY 0xa0 /* ring buffer not empty */ +#define DMA_INT_FULL 0xc0 /* ring buffer full */ +#define DMA_INT_NFULL 0xe0 /* ring buffer not full */ + +#define DMA_CHANNEL_RESET 0x400 /* reset dma channel */ +#define DMA_ENABLE 0x200 /* enable DMA */ + +/* peripheral controller intr status bits applicable to serial ports */ +#define ISA_SERIAL0_MASK 0x03f00000 /* mask for port #1 intrs */ +#define ISA_SERIAL0_DIR 0x00100000 /* device intr request */ +#define ISA_SERIAL0_Tx_THIR 0x00200000 /* Transmit DMA threshold */ +#define ISA_SERIAL0_Tx_PREQ 0x00400000 /* Transmit DMA pair req */ +#define ISA_SERIAL0_Tx_MEMERR 0x00800000 /* Transmit DMA memory err */ +#define ISA_SERIAL0_Rx_THIR 0x01000000 /* Receive DMA threshold */ +#define ISA_SERIAL0_Rx_OVERRUN 0x02000000 /* Receive DMA over-run */ + +#define ISA_SERIAL1_MASK 0xfc000000 /* mask for port #1 intrs */ +#define ISA_SERIAL1_DIR 0x04000000 /* device intr request */ +#define ISA_SERIAL1_Tx_THIR 0x08000000 /* Transmit DMA threshold */ +#define ISA_SERIAL1_Tx_PREQ 0x10000000 /* Transmit DMA pair req */ +#define ISA_SERIAL1_Tx_MEMERR 0x20000000 /* Transmit DMA memory err */ +#define ISA_SERIAL1_Rx_THIR 0x40000000 /* Receive DMA threshold */ +#define ISA_SERIAL1_Rx_OVERRUN 0x80000000 /* Receive DMA over-run */ + +#define MAX_RING_BLOCKS 128 /* 4096/32 */ +#define MAX_RING_SIZE 4096 + +/* DMA Input Control Byte */ +#define DMA_IC_OVRRUN 0x01 /* overrun error */ +#define DMA_IC_PARERR 0x02 /* parity error */ +#define DMA_IC_FRMERR 0x04 /* framing error */ +#define DMA_IC_BRKDET 0x08 /* a break has arrived */ +#define DMA_IC_VALID 0x80 /* pair is valid */ + +/* DMA Output Control Byte */ +#define DMA_OC_TxINTR 0x20 /* set Tx intr after processing byte */ +#define DMA_OC_INVALID 0x00 /* invalid pair */ +#define DMA_OC_WTHR 0x40 /* Write byte to THR */ +#define DMA_OC_WMCR 0x80 /* Write byte to MCR */ +#define DMA_OC_DELAY 0xc0 /* time delay before next xmit */ + +/* ring id's */ +#define RID_SERIAL0_TX 0x4 /* serial port 0, transmit ring buffer */ +#define RID_SERIAL0_RX 0x5 /* serial port 0, receive ring buffer */ +#define RID_SERIAL1_TX 0x6 /* serial port 1, transmit ring buffer */ +#define RID_SERIAL1_RX 0x7 /* serial port 1, receive ring buffer */ + +#define CLOCK_XIN 22 +#define PRESCALER_DIVISOR 3 +#define CLOCK_ACE 7333333 + +/* + * increment the ring offset. One way to do this would be to add b'100000. + * this would let the offset value roll over automatically when it reaches + * its maximum value (127). However when we use the offset, we must use + * the appropriate bits only by masking with 0xfe0. + * The other option is to shift the offset right by 5 bits and look at its + * value. Then increment if required and shift back + * note: 127 * 2^5 = 4064 + */ +#define INC_RING_POINTER(x) \ + ( ((x & 0xffe0) < 4064) ? (x += 32) : 0 ) + diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn1/war.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/war.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn1/war.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn1/war.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,25 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN1_WAR_H +#define _ASM_SN_SN1_WAR_H + +/**************************************************************************** + * Support macros and defitions for hardware workarounds in * + * early chip versions. * + ****************************************************************************/ + +/* + * This is the bitmap of runtime-switched workarounds. + */ +typedef short warbits_t; + +extern int warbits_override; + +#endif /* _ASM_SN_SN1_WAR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn_cpuid.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn_cpuid.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn_cpuid.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn_cpuid.h Wed Dec 13 19:35:00 2000 @@ -0,0 +1,198 @@ +/* + * + * 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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) + */ + + +#ifndef _ASM_IA64_SN_SN_CPUID_H +#define _ASM_IA64_SN_SN_CPUID_H + +#include + +/* + * Functions for converting between cpuids, nodeids and NASIDs. + * + * These are for SGI platforms only. + * + */ + + + + +/* + * The following assumes the following mappings for LID register values: + * + * LID + * 31:24 - id Contains the NASID + * 23:16 - eid Contains 0-3 to identify the cpu on the node + * bit 17 - synergy number + * bit 16 - FSB number + * + * SAPICID + * This is the same as 31:24 of LID + * + * The macros convert between cpuid & slice/fsb/synergy/nasid/cnodeid. + * These terms are described below: + * + * + * ----- ----- ----- ----- CPU + * | 0 | | 1 | | 2 | | 3 | SLICE + * ----- ----- ----- ----- + * | | | | + * | | | | + * 0 | | 1 0 | | 1 FSB + * ------- ------- + * | | + * | | + * ------- ------- + * | | | | + * | 0 | | 1 | SYNERGY + * | | | | + * ------- ------- + * | | + * | | + * ------------------------------- + * | | + * | BEDROCK | NASID (0..127) + * | | CNODEID (0..numnodes-1) + * | | + * | | + * ------------------------------- + * | + * + */ + + + +#define sapicid_to_nasid(sid) ((sid) >> 8) +#define sapicid_to_synergy(sid) (((sid) >> 1) & 1) +#define sapicid_to_fsb(sid) ((sid) & 1) +#define sapicid_to_slice(sid) ((sid) & 3) + +/* + * NOTE: id & eid refer to Intels definitions of the LID register + * (id = NASID, eid = slice) + * NOTE: on non-MP systems, only cpuid 0 exists + */ +#define id_eid_to_sapicid(id,eid) (((id)<<8) | (eid)) +#define id_eid_to_cpuid(id,eid) ((NASID_TO_CNODEID(id)<<2) | (eid)) + + +/* + * The following table/struct is for translating between sapicid and cpuids. + * It is also used for managing PTC coherency domains. + */ +typedef struct { + u8 domain; + u8 reserved; + u16 sapicid; +} sn_sapicid_info_t; + +extern sn_sapicid_info_t sn_sapicid_info[]; /* indexed by cpuid */ + + + +/* + * cpuid_to_spaicid - Convert a cpuid to a SAPIC id of the cpu. + * The SAPIC id is the same as bits 31:16 of the LID register. + */ +static __inline__ int +cpuid_to_spaicid(int cpuid) +{ +#ifdef CONFIG_SMP + return cpu_physical_id(cpuid); +#else + return ((ia64_get_lid() >> 16) & 0xffff); +#endif +} + + +/* + * cpuid_to_fsb_slot - convert a cpuid to the fsb slot number that it is in. + * (there are 2 cpus per FSB. This function returns 0 or 1) + */ +static __inline__ int +cpuid_to_fsb_slot(int cpuid) +{ + return sapicid_to_fsb(cpuid_to_spaicid(cpuid)); +} + + +/* + * cpuid_to_synergy - convert a cpuid to the synergy that it resides on + * (there are 2 synergies per node. Function returns 0 or 1 to + * specify which synergy the cpu is on) + */ +static __inline__ int +cpuid_to_synergy(int cpuid) +{ + return sapicid_to_synergy(cpuid_to_spaicid(cpuid)); +} + + +/* + * cpuid_to_slice - convert a cpuid to the slice that it resides on + * There are 4 cpus per node. This function returns 0 .. 3) + */ +static __inline__ int +cpuid_to_slice(int cpuid) +{ + return sapicid_to_slice(cpuid_to_spaicid(cpuid)); +} + + +/* + * cpuid_to_nasid - convert a cpuid to the NASID that it resides on + */ +static __inline__ int +cpuid_to_nasid(int cpuid) +{ + return sapicid_to_nasid(cpuid_to_spaicid(cpuid)); +} + + +/* + * cpuid_to_cnodeid - convert a cpuid to the cnode that it resides on + */ +static __inline__ int +cpuid_to_cnodeid(int cpuid) +{ + return nasid_map[cpuid_to_nasid(cpuid)]; +} + +static __inline__ int +cnodeid_to_nasid(int cnodeid) +{ + int i; + for (i = 0; i < MAXNASIDS; i++) { + if (nasid_map[i] == cnodeid) { + return(i); + } + } + return(-1); +} + +static __inline__ int +cnode_slice_to_cpuid(int cnodeid, int slice) { + return(id_eid_to_cpuid(cnodeid_to_nasid(cnodeid),slice)); +} + +static __inline__ int +cpuid_to_subnode(int cpuid) { + int ret = cpuid_to_slice(cpuid); + if (ret < 2) return 0; + else return 1; +} + +static __inline__ int +cpuid_to_localslice(int cpuid) { + return(cpuid_to_slice(cpuid) & 1); +} + + +#endif /* _ASM_IA64_SN_SN_CPUID_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn_fru.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn_fru.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn_fru.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn_fru.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,49 @@ +/************************************************************************** + * * + * Copyright (C) 1992-1997, Silicon Graphics, Inc. * + * * + * These coded instructions, statements, and computer programs contain * + * unpublished proprietary information of Silicon Graphics, Inc., and * + * are protected by Federal copyright law. They may not be disclosed * + * to third parties or copied or duplicated in any form, in whole or * + * in part, without the prior written consent of Silicon Graphics, Inc. * + * * + **************************************************************************/ +#ifndef __SYS_SN_SN0_FRU_H__ +#define __SYS_SN_SN0_FRU_H__ + +#define MAX_DIMMS 8 /* max # of dimm banks */ +#define MAX_PCIDEV 8 /* max # of pci devices on a pci bus */ + +typedef unsigned char confidence_t; + +typedef struct kf_mem_s { + confidence_t km_confidence; /* confidence level that the memory is bad + * is this necessary ? + */ + confidence_t km_dimm[MAX_DIMMS]; + /* confidence level that dimm[i] is bad + *I think this is the right number + */ + +} kf_mem_t; + +typedef struct kf_cpu_s { + confidence_t kc_confidence; /* confidence level that cpu is bad */ + confidence_t kc_icache; /* confidence level that instr. cache is bad */ + confidence_t kc_dcache; /* confidence level that data cache is bad */ + confidence_t kc_scache; /* confidence level that sec. cache is bad */ + confidence_t kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */ +} kf_cpu_t; + + +typedef struct kf_pci_bus_s { + confidence_t kpb_belief; /* confidence level that the pci bus is bad */ + confidence_t kpb_pcidev_belief[MAX_PCIDEV]; + /* confidence level that the pci dev is bad */ +} kf_pci_bus_t; + + + +#endif /* #ifdef __SYS_SN_SN0_FRU_H__ */ + diff -urN linux-2.4.0-test12/include/asm-ia64/sn/sn_private.h linux-2.4.0-test12-lia/include/asm-ia64/sn/sn_private.h --- linux-2.4.0-test12/include/asm-ia64/sn/sn_private.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/sn_private.h Wed Dec 13 23:53:00 2000 @@ -0,0 +1,302 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_PRIVATE_H +#define _ASM_SN_PRIVATE_H + +#include +#include +#include + +extern nasid_t master_nasid; + +extern hubreg_t get_region(cnodeid_t); +extern hubreg_t nasid_to_region(nasid_t); +/* promif.c */ +#ifndef CONFIG_IA64_SGI_IO +extern cpuid_t cpu_node_probe(cpumask_t *cpumask, int *numnodes); +#endif +extern void he_arcs_set_vectors(void); +extern void mem_init(void); +#ifndef CONFIG_IA64_SGI_IO +extern int cpu_enabled(cpuid_t); +#endif +extern void cpu_unenable(cpuid_t); +extern nasid_t get_lowest_nasid(void); +extern __psunsigned_t get_master_bridge_base(void); +extern void set_master_bridge_base(void); +extern int check_nasid_equiv(nasid_t, nasid_t); +extern nasid_t get_console_nasid(void); +extern char get_console_pcislot(void); +#ifndef CONFIG_IA64_SGI_IO +extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int); +#endif + +extern int is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid); + +/* memsupport.c */ +extern void poison_state_alter_range(__psunsigned_t start, int len, int poison); +extern int memory_present(paddr_t); +extern int memory_read_accessible(paddr_t); +extern int memory_write_accessible(paddr_t); +extern void memory_set_access(paddr_t, int, int); +extern void show_dir_state(paddr_t, void (*)(char *, ...)); +extern void check_dir_state(nasid_t, int, void (*)(char *, ...)); +extern void set_dir_owner(paddr_t, int); +extern void set_dir_state(paddr_t, int); +extern void set_dir_state_POISONED(paddr_t); +extern void set_dir_state_UNOWNED(paddr_t); +extern int is_POISONED_dir_state(paddr_t); +extern int is_UNOWNED_dir_state(paddr_t); +extern void get_dir_ent(paddr_t paddr, int *state, + uint64_t *vec_ptr, hubreg_t *elo); + +/* intr.c */ +#if defined(NEW_INTERRUPTS) +extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name); +extern void intr_unreserve_level(cpuid_t cpu, int level); +extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, + intr_func_t intr_func, void *intr_arg, + intr_func_t intr_prefunc); +extern int intr_disconnect_level(cpuid_t cpu, int bit); +extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc, + int req_bit,int intr_resflags,devfs_handle_t owner_dev, + char *intr_name,int *resp_bit); +#endif /* NEW_INTERRUPTS */ +extern void intr_block_bit(cpuid_t cpu, int bit); +extern void intr_unblock_bit(cpuid_t cpu, int bit); +extern void setrtvector(intr_func_t); +extern void install_cpuintr(cpuid_t cpu); +extern void install_dbgintr(cpuid_t cpu); +extern void install_tlbintr(cpuid_t cpu); +extern void hub_migrintr_init(cnodeid_t /*cnode*/); +extern int cause_intr_connect(int level, intr_func_t handler, uint intr_spl_mask); +extern int cause_intr_disconnect(int level); +extern void intr_reserve_hardwired(cnodeid_t); +extern void intr_clear_all(nasid_t); +extern void intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...)); +extern int protected_broadcast(hubreg_t intrbit); + +/* error_dump.c */ +extern char *hub_rrb_err_type[]; +extern char *hub_wrb_err_type[]; + +void nmi_dump(void); +void install_cpu_nmi_handler(int slice); + +/* klclock.c */ +extern void hub_rtc_init(cnodeid_t); + +/* bte.c */ +void bte_lateinit(void); +void bte_wait_for_xfer_completion(void *); + +/* klgraph.c */ +void klhwg_add_all_nodes(devfs_handle_t); +void klhwg_add_all_modules(devfs_handle_t); + +/* klidbg.c */ +void install_klidbg_functions(void); + +/* klnuma.c */ +extern void replicate_kernel_text(int numnodes); +extern __psunsigned_t get_freemem_start(cnodeid_t cnode); +extern void setup_replication_mask(int maxnodes); + +/* init.c */ +extern cnodeid_t get_compact_nodeid(void); /* get compact node id */ +#ifndef CONFIG_IA64_SGI_IO +extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node); +extern void init_platform_pda(pda_t *ppda, cpuid_t cpu); +#endif +extern void per_cpu_init(void); +extern void per_hub_init(cnodeid_t); +#ifndef CONFIG_IA64_SGI_IO +extern cpumask_t boot_cpumask; +#endif +extern int is_fine_dirmode(void); +extern void update_node_information(cnodeid_t); + +#ifndef CONFIG_IA64_SGI_IO +/* clksupport.c */ +extern void early_counter_intr(eframe_t *); +#endif + +/* hubio.c */ +extern void hubio_init(void); +extern void hub_merge_clean(nasid_t nasid); +extern void hub_set_piomode(nasid_t nasid, int conveyor); + +/* huberror.c */ +extern void hub_error_init(cnodeid_t); +extern void dump_error_spool(cpuid_t cpu, void (*pf)(char *, ...)); +extern void hubni_error_handler(char *, int); +extern int check_ni_errors(void); + +/* Used for debugger to signal upper software a breakpoint has taken place */ + +extern void *debugger_update; +extern __psunsigned_t debugger_stopped; + +/* + * IP27 piomap, created by hub_pio_alloc. + * xtalk_info MUST BE FIRST, since this structure is cast to a + * xtalk_piomap_s by generic xtalk routines. + */ +struct hub_piomap_s { + struct xtalk_piomap_s hpio_xtalk_info;/* standard crosstalk pio info */ + devfs_handle_t hpio_hub; /* which hub's mapping registers are set up */ + short hpio_holdcnt; /* count of current users of bigwin mapping */ + char hpio_bigwin_num;/* if big window map, which one */ + int hpio_flags; /* defined below */ +}; +/* hub_piomap flags */ +#define HUB_PIOMAP_IS_VALID 0x1 +#define HUB_PIOMAP_IS_BIGWINDOW 0x2 +#define HUB_PIOMAP_IS_FIXED 0x4 + +#define hub_piomap_xt_piomap(hp) (&hp->hpio_xtalk_info) +#define hub_piomap_hub_v(hp) (hp->hpio_hub) +#define hub_piomap_winnum(hp) (hp->hpio_bigwin_num) + +#if TBD + /* Ensure that hpio_xtalk_info is first */ + #assert (&(((struct hub_piomap_s *)0)->hpio_xtalk_info) == 0) +#endif + + +/* + * IP27 dmamap, created by hub_pio_alloc. + * xtalk_info MUST BE FIRST, since this structure is cast to a + * xtalk_dmamap_s by generic xtalk routines. + */ +struct hub_dmamap_s { + struct xtalk_dmamap_s hdma_xtalk_info;/* standard crosstalk dma info */ + devfs_handle_t hdma_hub; /* which hub we go through */ + int hdma_flags; /* defined below */ +}; +/* hub_dmamap flags */ +#define HUB_DMAMAP_IS_VALID 0x1 +#define HUB_DMAMAP_USED 0x2 +#define HUB_DMAMAP_IS_FIXED 0x4 + +#if TBD + /* Ensure that hdma_xtalk_info is first */ + #assert (&(((struct hub_dmamap_s *)0)->hdma_xtalk_info) == 0) +#endif + +/* + * IP27 interrupt handle, created by hub_intr_alloc. + * xtalk_info MUST BE FIRST, since this structure is cast to a + * xtalk_intr_s by generic xtalk routines. + */ +struct hub_intr_s { + struct xtalk_intr_s i_xtalk_info; /* standard crosstalk intr info */ + ilvl_t i_swlevel; /* software level for blocking intr */ + cpuid_t i_cpuid; /* which cpu */ + int i_bit; /* which bit */ + int i_flags; +}; +/* flag values */ +#define HUB_INTR_IS_ALLOCED 0x1 /* for debug: allocated */ +#define HUB_INTR_IS_CONNECTED 0x4 /* for debug: connected to a software driver */ + +#if TBD + /* Ensure that i_xtalk_info is first */ + #assert (&(((struct hub_intr_s *)0)->i_xtalk_info) == 0) +#endif + + +/* IP27 hub-specific information stored under INFO_LBL_HUB_INFO */ +/* TBD: IP27-dependent stuff currently in nodepda.h should be here */ +typedef struct hubinfo_s { + nodepda_t *h_nodepda; /* pointer to node's private data area */ + cnodeid_t h_cnodeid; /* compact nodeid */ + nasid_t h_nasid; /* nasid */ + + /* structures for PIO management */ + xwidgetnum_t h_widgetid; /* my widget # (as viewed from xbow) */ + struct hub_piomap_s h_small_window_piomap[HUB_WIDGET_ID_MAX+1]; + sv_t h_bwwait; /* wait for big window to free */ + spinlock_t h_bwlock; /* guard big window piomap's */ + spinlock_t h_crblock; /* gaurd CRB error handling */ + int h_num_big_window_fixed; /* count number of FIXED maps */ + struct hub_piomap_s h_big_window_piomap[HUB_NUM_BIG_WINDOW]; + hub_intr_t hub_ii_errintr; +} *hubinfo_t; + +#define hubinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \ + (vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t *)infoptr)) + +#define hubinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \ + (vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t)infoptr) + +#define hubinfo_to_hubv(hinfo, hub_v) (hinfo->h_nodepda->node_vertex) + +/* + * Hub info PIO map access functions. + */ +#define hubinfo_bwin_piomap_get(hinfo, win) \ + (&hinfo->h_big_window_piomap[win]) +#define hubinfo_swin_piomap_get(hinfo, win) \ + (&hinfo->h_small_window_piomap[win]) + +/* IP27 cpu-specific information stored under INFO_LBL_CPU_INFO */ +/* TBD: IP27-dependent stuff currently in pda.h should be here */ +typedef struct cpuinfo_s { +#ifndef CONFIG_IA64_SGI_IO + pda_t *ci_cpupda; /* pointer to CPU's private data area */ +#endif + cpuid_t ci_cpuid; /* CPU ID */ +} *cpuinfo_t; + +#define cpuinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \ + (vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t *)infoptr)) + +#define cpuinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \ + (vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr) + +/* Special initialization function for xswitch vertices created during startup. */ +extern void xswitch_vertex_init(devfs_handle_t xswitch); + +extern xtalk_provider_t hub_provider; + +/* du.c */ +int ducons_write(char *buf, int len); + +/* memerror.c */ + +extern void install_eccintr(cpuid_t cpu); +extern void memerror_get_stats(cnodeid_t cnode, + int *bank_stats, int *bank_stats_max); +extern void probe_md_errors(nasid_t); +/* sysctlr.c */ +extern void sysctlr_init(void); +extern void sysctlr_power_off(int sdonly); +extern void sysctlr_keepalive(void); + +#define valid_cpuid(_x) (((_x) >= 0) && ((_x) < maxcpus)) + +/* Useful definitions to get the memory dimm given a physical + * address. + */ +#define paddr_dimm(_pa) ((_pa & MD_BANK_MASK) >> MD_BANK_SHFT) +#define paddr_cnode(_pa) (NASID_TO_COMPACT_NODEID(NASID_GET(_pa))) +extern void membank_pathname_get(paddr_t,char *); + +/* To redirect the output into the error buffer */ +#define errbuf_print(_s) printf("#%s",_s) + +extern void crbx(nasid_t nasid, void (*pf)(char *, ...)); +void bootstrap(void); + +/* sndrv.c */ +extern int sndrv_attach(devfs_handle_t vertex); + +#endif /* _ASM_SN_PRIVATE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/synergy.h linux-2.4.0-test12-lia/include/asm-ia64/sn/synergy.h --- linux-2.4.0-test12/include/asm-ia64/sn/synergy.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/synergy.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,127 @@ +#ifndef ASM_IA64_SN_SYNERGY_H +#define ASM_IA64_SN_SYNERGY_H + +#include "asm/io.h" +#include "asm/sn/intr_public.h" + + +/* + * Definitions for the synergy asic driver + * + * These are for SGI platforms only. + * + * Copyright (C) 2000 Silicon Graphics, Inc + * Copyright (C) 2000 Alan Mayer (ajm@sgi.com) + */ + + +#define SSPEC_BASE (0xe0000000000) +#define LB_REG_BASE (SSPEC_BASE + 0x0) + +#define VEC_MASK3A_ADDR (0x2a0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK3B_ADDR (0x2a8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK3A (0x2a0) +#define VEC_MASK3B (0x2a8) + +#define VEC_MASK2A_ADDR (0x2b0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK2B_ADDR (0x2b8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK2A (0x2b0) +#define VEC_MASK2B (0x2b8) + +#define VEC_MASK1A_ADDR (0x2c0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK1B_ADDR (0x2c8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK1A (0x2c0) +#define VEC_MASK1B (0x2c8) + +#define VEC_MASK0A_ADDR (0x2d0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK0B_ADDR (0x2d8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET) +#define VEC_MASK0A (0x2d0) +#define VEC_MASK0B (0x2d8) + +#define WRITE_LOCAL_SYNERGY_REG(addr, value) __synergy_out(addr, value) + +#define HUBREG_CAST (volatile hubreg_t *) +#define NODE_OFFSET(_n) (UINT64_CAST (_n) << NODE_SIZE_BITS) +#define SYN_UNCACHED_SPACE 0xc000000000000000 +#define NODE_HSPEC_BASE(_n) (HSPEC_BASE + NODE_OFFSET(_n)) +#define NODE_LREG_BASE(_n) (NODE_HSPEC_BASE(_n) + 0x30000000) +#define RREG_BASE(_n) (NODE_LREG_BASE(_n)) +#define REMOTE_HSPEC(_n, _x) (HUBREG_CAST (RREG_BASE(_n) + (_x))) +#define HSPEC_SYNERGY0_0 0x04000000 /* Synergy0 Registers */ +#define HSPEC_SYNERGY1_0 0x05000000 /* Synergy1 Registers */ +#define HS_SYNERGY_STRIDE (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0) + + +#define HUB_L(_a) *(_a) +#define HUB_S(_a, _d) *(_a) = (_d) + + +#define REMOTE_SYNERGY_LOAD(nasid, fsb, reg) __remote_synergy_in(nasid, fsb, reg) +#define REMOTE_SYNERGY_STORE(nasid, fsb, reg, val) __remote_synergy_out(nasid, fsb, reg, val) + +extern inline void +__remote_synergy_out(int nasid, int fsb, unsigned long reg, unsigned long val) { + unsigned long addr = ((RREG_BASE(nasid)) + + ((HSPEC_SYNERGY0_0 | (fsb)*HS_SYNERGY_STRIDE) | ((reg) << 2))); + + HUB_S((unsigned long *)(addr), (val) >> 48); + HUB_S((unsigned long *)(addr+0x08), (val) >> 32); + HUB_S((unsigned long *)(addr+0x10), (val) >> 16); + HUB_S((unsigned long *)(addr+0x18), (val) ); + __ia64_mf_a(); +} + +extern inline unsigned long +__remote_synergy_in(int nasid, int fsb, unsigned long reg) { + volatile unsigned long *addr = (unsigned long *) ((RREG_BASE(nasid)) + + ((HSPEC_SYNERGY0_0 | (fsb)*HS_SYNERGY_STRIDE) | (reg))); + unsigned long ret; + + ret = *addr; + __ia64_mf_a(); + return ret; +} + +extern inline void +__synergy_out(unsigned long addr, unsigned long value) +{ + volatile unsigned long *adr = (unsigned long *) + (addr | __IA64_UNCACHED_OFFSET); + + *adr = value; + __ia64_mf_a(); +} + +#define READ_LOCAL_SYNERGY_REG(addr) __synergy_in(addr) + +extern inline unsigned long +__synergy_in(unsigned long addr) +{ + unsigned long ret, *adr = (unsigned long *) + (addr | __IA64_UNCACHED_OFFSET); + + ret = *adr; + __ia64_mf_a(); + return ret; +} + +struct sn1_intr_action { + void (*handler)(int, void *, struct pt_regs *); + void *intr_arg; + unsigned long flags; + struct sn1_intr_action * next; +}; + +typedef struct synergy_da_s { + hub_intmasks_t s_intmasks; +}synergy_da_t; + +struct sn1_cnode_action_list { + spinlock_t action_list_lock; + struct sn1_intr_action *action_list; +}; + + +/* Temporary defintions for testing: */ + +#endif ASM_IA64_SN_SYNERGY_H diff -urN linux-2.4.0-test12/include/asm-ia64/sn/systeminfo.h linux-2.4.0-test12-lia/include/asm-ia64/sn/systeminfo.h --- linux-2.4.0-test12/include/asm-ia64/sn/systeminfo.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/systeminfo.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,72 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SYSTEMINFO_H +#define _ASM_SN_SYSTEMINFO_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_SN_SYSTEMINFO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/types.h linux-2.4.0-test12-lia/include/asm-ia64/sn/types.h --- linux-2.4.0-test12/include/asm-ia64/sn/types.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/types.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,36 @@ +/* + * 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) 1999 Silicon Graphics, Inc. + * Copyright (C) 1999 by Ralf Baechle + */ +#ifndef _ASM_SN_TYPES_H +#define _ASM_SN_TYPES_H + +#include +#include + +typedef unsigned long cpuid_t; +typedef unsigned long cpumask_t; +/* typedef unsigned long cnodemask_t; */ +typedef signed short nasid_t; /* node id in numa-as-id space */ +typedef signed short cnodeid_t; /* node id in compact-id space */ +typedef signed char partid_t; /* partition ID type */ +typedef signed short moduleid_t; /* user-visible module number type */ +typedef signed short cmoduleid_t; /* kernel compact module id type */ +typedef unsigned char clusterid_t; /* Clusterid of the cell */ + +#if defined(CONFIG_IA64_SGI_IO) +#define __psunsigned_t uint64_t +#define lock_t uint64_t +#define sv_t uint64_t + +typedef unsigned long iopaddr_t; +typedef unsigned char uchar_t; +typedef unsigned long paddr_t; +typedef unsigned long pfn_t; +#endif /* CONFIG_IA64_SGI_IO */ + +#endif /* _ASM_SN_TYPES_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/vector.h linux-2.4.0-test12-lia/include/asm-ia64/sn/vector.h --- linux-2.4.0-test12/include/asm-ia64/sn/vector.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/vector.h Wed Dec 13 19:35:19 2000 @@ -0,0 +1,117 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_VECTOR_H +#define _ASM_SN_VECTOR_H + +#define NET_VEC_NULL ((net_vec_t) 0) +#define NET_VEC_BAD ((net_vec_t) -1) + +#ifdef RTL + +#define VEC_POLLS_W 16 /* Polls before write times out */ +#define VEC_POLLS_R 16 /* Polls before read times out */ +#define VEC_POLLS_X 16 /* Polls before exch times out */ + +#define VEC_RETRIES_W 1 /* Retries before write fails */ +#define VEC_RETRIES_R 1 /* Retries before read fails */ +#define VEC_RETRIES_X 1 /* Retries before exch fails */ + +#else /* RTL */ + +#define VEC_POLLS_W 128 /* Polls before write times out */ +#define VEC_POLLS_R 128 /* Polls before read times out */ +#define VEC_POLLS_X 128 /* Polls before exch times out */ + +#define VEC_RETRIES_W 8 /* Retries before write fails */ +#define VEC_RETRIES_R 8 /* Retries before read fails */ +#define VEC_RETRIES_X 4 /* Retries before exch fails */ + +#endif /* RTL */ + +#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#define VECTOR_PARMS LB_VECTOR_PARMS +#define VECTOR_ROUTE LB_VECTOR_ROUTE +#define VECTOR_DATA LB_VECTOR_DATA +#define VECTOR_STATUS LB_VECTOR_STATUS +#define VECTOR_RETURN LB_VECTOR_RETURN +#define VECTOR_READ_DATA LB_VECTOR_READ_DATA +#define VECTOR_STATUS_CLEAR LB_VECTOR_STATUS_CLEAR +#define VP_PIOID_SHFT LVP_PIOID_SHFT +#define VP_PIOID_MASK LVP_PIOID_MASK +#define VP_WRITEID_SHFT LVP_WRITEID_SHFT +#define VP_WRITEID_MASK LVP_WRITEID_MASK +#define VP_ADDRESS_MASK LVP_ADDRESS_MASK +#define VP_TYPE_SHFT LVP_TYPE_SHFT +#define VP_TYPE_MASK LVP_TYPE_MASK +#define VS_VALID LVS_VALID +#define VS_OVERRUN LVS_OVERRUN +#define VS_TARGET_SHFT LVS_TARGET_SHFT +#define VS_TARGET_MASK LVS_TARGET_MASK +#define VS_PIOID_SHFT LVS_PIOID_SHFT +#define VS_PIOID_MASK LVS_PIOID_MASK +#define VS_WRITEID_SHFT LVS_WRITEID_SHFT +#define VS_WRITEID_MASK LVS_WRITEID_MASK +#define VS_ADDRESS_MASK LVS_ADDRESS_MASK +#define VS_TYPE_SHFT LVS_TYPE_SHFT +#define VS_TYPE_MASK LVS_TYPE_MASK +#define VS_ERROR_MASK LVS_ERROR_MASK +#endif + +#define NET_ERROR_NONE 0 /* No error */ +#define NET_ERROR_HARDWARE -1 /* Hardware error */ +#define NET_ERROR_OVERRUN -2 /* Extra response(s) */ +#define NET_ERROR_REPLY -3 /* Reply parms mismatch */ +#define NET_ERROR_ADDRESS -4 /* Addr error response */ +#define NET_ERROR_COMMAND -5 /* Cmd error response */ +#define NET_ERROR_PROT -6 /* Prot error response */ +#define NET_ERROR_TIMEOUT -7 /* Too many retries */ +#define NET_ERROR_VECTOR -8 /* Invalid vector/path */ +#define NET_ERROR_ROUTERLOCK -9 /* Timeout locking rtr */ +#define NET_ERROR_INVAL -10 /* Invalid vector request */ + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +typedef uint64_t net_reg_t; +typedef uint64_t net_vec_t; + +int vector_write(net_vec_t dest, + int write_id, int address, + uint64_t value); + +int vector_read(net_vec_t dest, + int write_id, int address, + uint64_t *value); + +int vector_write_node(net_vec_t dest, nasid_t nasid, + int write_id, int address, + uint64_t value); + +int vector_read_node(net_vec_t dest, nasid_t nasid, + int write_id, int address, + uint64_t *value); + +int vector_length(net_vec_t vec); +net_vec_t vector_get(net_vec_t vec, int n); +net_vec_t vector_prefix(net_vec_t vec, int n); +net_vec_t vector_modify(net_vec_t entry, int n, int route); +net_vec_t vector_reverse(net_vec_t vec); +net_vec_t vector_concat(net_vec_t vec1, net_vec_t vec2); + +char *net_errmsg(int); + +#ifndef _STANDALONE +int hub_vector_write(cnodeid_t cnode, net_vec_t vector, int writeid, + int addr, net_reg_t value); +int hub_vector_read(cnodeid_t cnode, net_vec_t vector, int writeid, + int addr, net_reg_t *value); +#endif + +#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ + +#endif /* _ASM_SN_VECTOR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/war.h linux-2.4.0-test12-lia/include/asm-ia64/sn/war.h --- linux-2.4.0-test12/include/asm-ia64/sn/war.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/war.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,17 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_WAR_H +#define _ASM_SN_WAR_H + +#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) +#include +#endif + +#endif /* _ASM_SN_WAR_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xbow.h linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xbow.h --- linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xbow.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xbow.h Wed Dec 13 23:52:11 2000 @@ -0,0 +1,895 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_SN_XTALK_XBOW_H +#define _ASM_SN_SN_XTALK_XBOW_H + +/* + * xbow.h - header file for crossbow chip and xbow section of xbridge + */ + +#include +#include +#include +#ifdef LANGUAGE_C +#include +#endif + + +#define XBOW_DRV_PREFIX "xbow_" + +/* The crossbow chip supports 8 8/16 bits I/O ports, numbered 0x8 through 0xf. + * It also implements the widget 0 address space and register set. + */ +#define XBOW_PORT_0 0x0 +#define XBOW_PORT_8 0x8 +#define XBOW_PORT_9 0x9 +#define XBOW_PORT_A 0xa +#define XBOW_PORT_B 0xb +#define XBOW_PORT_C 0xc +#define XBOW_PORT_D 0xd +#define XBOW_PORT_E 0xe +#define XBOW_PORT_F 0xf + +#define MAX_XBOW_PORTS 8 /* number of ports on xbow chip */ +#define BASE_XBOW_PORT XBOW_PORT_8 /* Lowest external port */ +#define MAX_PORT_NUM 0x10 /* maximum port number + 1 */ +#define XBOW_WIDGET_ID 0 /* xbow is itself widget 0 */ + +#define XBOW_CREDIT 4 + +#define MAX_XBOW_NAME 16 + +#if LANGUAGE_C +typedef uint32_t xbowreg_t; + +#define XBOWCONST (xbowreg_t) + +/* Generic xbow register, given base and offset */ +#define XBOW_REG_PTR(base, offset) ((volatile xbowreg_t*) \ + ((__psunsigned_t)(base) + (__psunsigned_t)(offset))) + +/* Register set for each xbow link */ +typedef volatile struct xb_linkregs_s { +#ifdef LITTLE_ENDIAN +/* + * we access these through synergy unswizzled space, so the address + * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) + * That's why we put the register first and filler second. + */ + xbowreg_t link_ibf; + xbowreg_t filler0; /* filler for proper alignment */ + xbowreg_t link_control; + xbowreg_t filler1; + xbowreg_t link_status; + xbowreg_t filler2; + xbowreg_t link_arb_upper; + xbowreg_t filler3; + xbowreg_t link_arb_lower; + xbowreg_t filler4; + xbowreg_t link_status_clr; + xbowreg_t filler5; + xbowreg_t link_reset; + xbowreg_t filler6; + xbowreg_t link_aux_status; + xbowreg_t filler7; +#else + xbowreg_t filler0; /* filler for proper alignment */ + xbowreg_t link_ibf; + xbowreg_t filler1; + xbowreg_t link_control; + xbowreg_t filler2; + xbowreg_t link_status; + xbowreg_t filler3; + xbowreg_t link_arb_upper; + xbowreg_t filler4; + xbowreg_t link_arb_lower; + xbowreg_t filler5; + xbowreg_t link_status_clr; + xbowreg_t filler6; + xbowreg_t link_reset; + xbowreg_t filler7; + xbowreg_t link_aux_status; +#endif /* LITTLE_ENDIAN */ +} xb_linkregs_t; + +typedef volatile struct xbow_s { + /* standard widget configuration 0x000000-0x000057 */ + widget_cfg_t xb_widget; /* 0x000000 */ + + /* helper fieldnames for accessing bridge widget */ + +#define xb_wid_id xb_widget.w_id +#define xb_wid_stat xb_widget.w_status +#define xb_wid_err_upper xb_widget.w_err_upper_addr +#define xb_wid_err_lower xb_widget.w_err_lower_addr +#define xb_wid_control xb_widget.w_control +#define xb_wid_req_timeout xb_widget.w_req_timeout +#define xb_wid_int_upper xb_widget.w_intdest_upper_addr +#define xb_wid_int_lower xb_widget.w_intdest_lower_addr +#define xb_wid_err_cmdword xb_widget.w_err_cmd_word +#define xb_wid_llp xb_widget.w_llp_cfg +#define xb_wid_stat_clr xb_widget.w_tflush + +#ifdef LITTLE_ENDIAN +/* + * we access these through synergy unswizzled space, so the address + * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) + * That's why we put the register first and filler second. + */ + /* xbow-specific widget configuration 0x000058-0x0000FF */ + xbowreg_t xb_wid_arb_reload; /* 0x00005C */ + xbowreg_t _pad_000058; + xbowreg_t xb_perf_ctr_a; /* 0x000064 */ + xbowreg_t _pad_000060; + xbowreg_t xb_perf_ctr_b; /* 0x00006c */ + xbowreg_t _pad_000068; + xbowreg_t xb_nic; /* 0x000074 */ + xbowreg_t _pad_000070; + + /* Xbridge only */ + xbowreg_t xb_w0_rst_fnc; /* 0x00007C */ + xbowreg_t _pad_000078; + xbowreg_t xb_l8_rst_fnc; /* 0x000084 */ + xbowreg_t _pad_000080; + xbowreg_t xb_l9_rst_fnc; /* 0x00008c */ + xbowreg_t _pad_000088; + xbowreg_t xb_la_rst_fnc; /* 0x000094 */ + xbowreg_t _pad_000090; + xbowreg_t xb_lb_rst_fnc; /* 0x00009c */ + xbowreg_t _pad_000098; + xbowreg_t xb_lc_rst_fnc; /* 0x0000a4 */ + xbowreg_t _pad_0000a0; + xbowreg_t xb_ld_rst_fnc; /* 0x0000ac */ + xbowreg_t _pad_0000a8; + xbowreg_t xb_le_rst_fnc; /* 0x0000b4 */ + xbowreg_t _pad_0000b0; + xbowreg_t xb_lf_rst_fnc; /* 0x0000bc */ + xbowreg_t _pad_0000b8; + xbowreg_t xb_lock; /* 0x0000c4 */ + xbowreg_t _pad_0000c0; + xbowreg_t xb_lock_clr; /* 0x0000cc */ + xbowreg_t _pad_0000c8; + /* end of Xbridge only */ + xbowreg_t _pad_0000d0[12]; +#else + /* xbow-specific widget configuration 0x000058-0x0000FF */ + xbowreg_t _pad_000058; + xbowreg_t xb_wid_arb_reload; /* 0x00005C */ + xbowreg_t _pad_000060; + xbowreg_t xb_perf_ctr_a; /* 0x000064 */ + xbowreg_t _pad_000068; + xbowreg_t xb_perf_ctr_b; /* 0x00006c */ + xbowreg_t _pad_000070; + xbowreg_t xb_nic; /* 0x000074 */ + + /* Xbridge only */ + xbowreg_t _pad_000078; + xbowreg_t xb_w0_rst_fnc; /* 0x00007C */ + xbowreg_t _pad_000080; + xbowreg_t xb_l8_rst_fnc; /* 0x000084 */ + xbowreg_t _pad_000088; + xbowreg_t xb_l9_rst_fnc; /* 0x00008c */ + xbowreg_t _pad_000090; + xbowreg_t xb_la_rst_fnc; /* 0x000094 */ + xbowreg_t _pad_000098; + xbowreg_t xb_lb_rst_fnc; /* 0x00009c */ + xbowreg_t _pad_0000a0; + xbowreg_t xb_lc_rst_fnc; /* 0x0000a4 */ + xbowreg_t _pad_0000a8; + xbowreg_t xb_ld_rst_fnc; /* 0x0000ac */ + xbowreg_t _pad_0000b0; + xbowreg_t xb_le_rst_fnc; /* 0x0000b4 */ + xbowreg_t _pad_0000b8; + xbowreg_t xb_lf_rst_fnc; /* 0x0000bc */ + xbowreg_t _pad_0000c0; + xbowreg_t xb_lock; /* 0x0000c4 */ + xbowreg_t _pad_0000c8; + xbowreg_t xb_lock_clr; /* 0x0000cc */ + /* end of Xbridge only */ + xbowreg_t _pad_0000d0[12]; +#endif /* LITTLE_ENDIAN */ + + /* Link Specific Registers, port 8..15 0x000100-0x000300 */ + xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS]; +#define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)] + +} xbow_t; + +/* Configuration structure which describes each xbow link */ +typedef struct xbow_cfg_s { + int xb_port; /* port number (0-15) */ + int xb_flags; /* port software flags */ + short xb_shift; /* shift for arb reg (mask is 0xff) */ + short xb_ul; /* upper or lower arb reg */ + int xb_pad; /* use this later (pad to ptr align) */ + xb_linkregs_t *xb_linkregs; /* pointer to link registers */ + widget_cfg_t *xb_widget; /* pointer to widget registers */ + char xb_name[MAX_XBOW_NAME]; /* port name */ + xbowreg_t xb_sh_arb_upper; /* shadow upper arb register */ + xbowreg_t xb_sh_arb_lower; /* shadow lower arb register */ +} xbow_cfg_t; + +#define XB_FLAGS_EXISTS 0x1 /* device exists */ +#define XB_FLAGS_MASTER 0x2 +#define XB_FLAGS_SLAVE 0x0 +#define XB_FLAGS_GBR 0x4 +#define XB_FLAGS_16BIT 0x8 +#define XB_FLAGS_8BIT 0x0 + +/* get xbow config information for port p */ +#define XB_CONFIG(p) xbow_cfg[xb_ports[p]] + +/* is widget port number valid? (based on version 7.0 of xbow spec) */ +#define XBOW_WIDGET_IS_VALID(wid) ((wid) >= XBOW_PORT_8 && (wid) <= XBOW_PORT_F) + +/* whether to use upper or lower arbitration register, given source widget id */ +#define XBOW_ARB_IS_UPPER(wid) ((wid) >= XBOW_PORT_8 && (wid) <= XBOW_PORT_B) +#define XBOW_ARB_IS_LOWER(wid) ((wid) >= XBOW_PORT_C && (wid) <= XBOW_PORT_F) + +/* offset of arbitration register, given source widget id */ +#define XBOW_ARB_OFF(wid) (XBOW_ARB_IS_UPPER(wid) ? 0x1c : 0x24) + +#endif /* LANGUAGE_C */ + +#define XBOW_WID_ID WIDGET_ID +#define XBOW_WID_STAT WIDGET_STATUS +#define XBOW_WID_ERR_UPPER WIDGET_ERR_UPPER_ADDR +#define XBOW_WID_ERR_LOWER WIDGET_ERR_LOWER_ADDR +#define XBOW_WID_CONTROL WIDGET_CONTROL +#define XBOW_WID_REQ_TO WIDGET_REQ_TIMEOUT +#define XBOW_WID_INT_UPPER WIDGET_INTDEST_UPPER_ADDR +#define XBOW_WID_INT_LOWER WIDGET_INTDEST_LOWER_ADDR +#define XBOW_WID_ERR_CMDWORD WIDGET_ERR_CMD_WORD +#define XBOW_WID_LLP WIDGET_LLP_CFG +#define XBOW_WID_STAT_CLR WIDGET_TFLUSH +#define XBOW_WID_ARB_RELOAD 0x5c +#define XBOW_WID_PERF_CTR_A 0x64 +#define XBOW_WID_PERF_CTR_B 0x6c +#define XBOW_WID_NIC 0x74 + +/* Xbridge only */ +#define XBOW_W0_RST_FNC 0x00007C +#define XBOW_L8_RST_FNC 0x000084 +#define XBOW_L9_RST_FNC 0x00008c +#define XBOW_LA_RST_FNC 0x000094 +#define XBOW_LB_RST_FNC 0x00009c +#define XBOW_LC_RST_FNC 0x0000a4 +#define XBOW_LD_RST_FNC 0x0000ac +#define XBOW_LE_RST_FNC 0x0000b4 +#define XBOW_LF_RST_FNC 0x0000bc +#define XBOW_RESET_FENCE(x) ((x) > 7 && (x) < 16) ? \ + (XBOW_W0_RST_FNC + ((x) - 7) * 8) : \ + ((x) == 0) ? XBOW_W0_RST_FNC : 0 +#define XBOW_LOCK 0x0000c4 +#define XBOW_LOCK_CLR 0x0000cc +/* End of Xbridge only */ + +/* used only in ide, but defined here within the reserved portion */ +/* of the widget0 address space (before 0xf4) */ +#define XBOW_WID_UNDEF 0xe4 + +/* pointer to link arbitration register, given xbow base, dst and src widget id */ +#define XBOW_PRIO_ARBREG_PTR(base, dst_wid, src_wid) \ + XBOW_REG_PTR(XBOW_PRIO_LINKREGS_PTR(base, dst_wid), XBOW_ARB_OFF(src_wid)) + +/* pointer to link registers base, given xbow base and destination widget id */ +#define XBOW_PRIO_LINKREGS_PTR(base, dst_wid) (xb_linkregs_t*) \ + XBOW_REG_PTR(base, XB_LINK_REG_BASE(dst_wid)) + +/* xbow link register set base, legal value for x is 0x8..0xf */ +#define XB_LINK_BASE 0x100 +#define XB_LINK_OFFSET 0x40 +#define XB_LINK_REG_BASE(x) (XB_LINK_BASE + ((x) & (MAX_XBOW_PORTS - 1)) * XB_LINK_OFFSET) + +#define XB_LINK_IBUF_FLUSH(x) (XB_LINK_REG_BASE(x) + 0x4) +#define XB_LINK_CTRL(x) (XB_LINK_REG_BASE(x) + 0xc) +#define XB_LINK_STATUS(x) (XB_LINK_REG_BASE(x) + 0x14) +#define XB_LINK_ARB_UPPER(x) (XB_LINK_REG_BASE(x) + 0x1c) +#define XB_LINK_ARB_LOWER(x) (XB_LINK_REG_BASE(x) + 0x24) +#define XB_LINK_STATUS_CLR(x) (XB_LINK_REG_BASE(x) + 0x2c) +#define XB_LINK_RESET(x) (XB_LINK_REG_BASE(x) + 0x34) +#define XB_LINK_AUX_STATUS(x) (XB_LINK_REG_BASE(x) + 0x3c) + +/* link_control(x) */ +#define XB_CTRL_LINKALIVE_IE 0x80000000 /* link comes alive */ + /* reserved: 0x40000000 */ +#define XB_CTRL_PERF_CTR_MODE_MSK 0x30000000 /* perf counter mode */ +#define XB_CTRL_IBUF_LEVEL_MSK 0x0e000000 /* input packet buffer level */ +#define XB_CTRL_8BIT_MODE 0x01000000 /* force link into 8 bit mode */ +#define XB_CTRL_BAD_LLP_PKT 0x00800000 /* force bad LLP packet */ +#define XB_CTRL_WIDGET_CR_MSK 0x007c0000 /* LLP widget credit mask */ +#define XB_CTRL_WIDGET_CR_SHFT 18 /* LLP widget credit shift */ +#define XB_CTRL_ILLEGAL_DST_IE 0x00020000 /* illegal destination */ +#define XB_CTRL_OALLOC_IBUF_IE 0x00010000 /* overallocated input buffer */ + /* reserved: 0x0000fe00 */ +#define XB_CTRL_BNDWDTH_ALLOC_IE 0x00000100 /* bandwidth alloc */ +#define XB_CTRL_RCV_CNT_OFLOW_IE 0x00000080 /* rcv retry overflow */ +#define XB_CTRL_XMT_CNT_OFLOW_IE 0x00000040 /* xmt retry overflow */ +#define XB_CTRL_XMT_MAX_RTRY_IE 0x00000020 /* max transmit retry */ +#define XB_CTRL_RCV_IE 0x00000010 /* receive */ +#define XB_CTRL_XMT_RTRY_IE 0x00000008 /* transmit retry */ + /* reserved: 0x00000004 */ +#define XB_CTRL_MAXREQ_TOUT_IE 0x00000002 /* maximum request timeout */ +#define XB_CTRL_SRC_TOUT_IE 0x00000001 /* source timeout */ + +/* link_status(x) */ +#define XB_STAT_LINKALIVE XB_CTRL_LINKALIVE_IE + /* reserved: 0x7ff80000 */ +#define XB_STAT_MULTI_ERR 0x00040000 /* multi error */ +#define XB_STAT_ILLEGAL_DST_ERR XB_CTRL_ILLEGAL_DST_IE +#define XB_STAT_OALLOC_IBUF_ERR XB_CTRL_OALLOC_IBUF_IE +#define XB_STAT_BNDWDTH_ALLOC_ID_MSK 0x0000ff00 /* port bitmask */ +#define XB_STAT_RCV_CNT_OFLOW_ERR XB_CTRL_RCV_CNT_OFLOW_IE +#define XB_STAT_XMT_CNT_OFLOW_ERR XB_CTRL_XMT_CNT_OFLOW_IE +#define XB_STAT_XMT_MAX_RTRY_ERR XB_CTRL_XMT_MAX_RTRY_IE +#define XB_STAT_RCV_ERR XB_CTRL_RCV_IE +#define XB_STAT_XMT_RTRY_ERR XB_CTRL_XMT_RTRY_IE + /* reserved: 0x00000004 */ +#define XB_STAT_MAXREQ_TOUT_ERR XB_CTRL_MAXREQ_TOUT_IE +#define XB_STAT_SRC_TOUT_ERR XB_CTRL_SRC_TOUT_IE + +/* link_aux_status(x) */ +#define XB_AUX_STAT_RCV_CNT 0xff000000 +#define XB_AUX_STAT_XMT_CNT 0x00ff0000 +#define XB_AUX_STAT_TOUT_DST 0x0000ff00 +#define XB_AUX_LINKFAIL_RST_BAD 0x00000040 +#define XB_AUX_STAT_PRESENT 0x00000020 +#define XB_AUX_STAT_PORT_WIDTH 0x00000010 + /* reserved: 0x0000000f */ + +/* + * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper + * register if (x) is 0x8..0xb, link_arb_lower if (x) is 0xc..0xf + */ +#define XB_ARB_GBR_MSK 0x1f +#define XB_ARB_RR_MSK 0x7 +#define XB_ARB_GBR_SHFT(x) (((x) & 0x3) * 8) +#define XB_ARB_RR_SHFT(x) (((x) & 0x3) * 8 + 5) +#define XB_ARB_GBR_CNT(reg,x) ((reg) >> XB_ARB_GBR_SHFT(x) & XB_ARB_GBR_MSK) +#define XB_ARB_RR_CNT(reg,x) ((reg) >> XB_ARB_RR_SHFT(x) & XB_ARB_RR_MSK) + +/* XBOW_WID_STAT */ +#define XB_WID_STAT_LINK_INTR_SHFT (24) +#define XB_WID_STAT_LINK_INTR_MASK (0xFF << XB_WID_STAT_LINK_INTR_SHFT) +#define XB_WID_STAT_LINK_INTR(x) (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT)) +#define XB_WID_STAT_WIDGET0_INTR 0x00800000 +#define XB_WID_STAT_SRCID_MASK 0x000003c0 /* Xbridge only */ +#define XB_WID_STAT_REG_ACC_ERR 0x00000020 +#define XB_WID_STAT_RECV_TOUT 0x00000010 /* Xbridge only */ +#define XB_WID_STAT_ARB_TOUT 0x00000008 /* Xbridge only */ +#define XB_WID_STAT_XTALK_ERR 0x00000004 +#define XB_WID_STAT_DST_TOUT 0x00000002 /* Xbridge only */ +#define XB_WID_STAT_MULTI_ERR 0x00000001 + +#define XB_WID_STAT_SRCID_SHFT 6 + +/* XBOW_WID_CONTROL */ +#define XB_WID_CTRL_REG_ACC_IE XB_WID_STAT_REG_ACC_ERR +#define XB_WID_CTRL_RECV_TOUT XB_WID_STAT_RECV_TOUT +#define XB_WID_CTRL_ARB_TOUT XB_WID_STAT_ARB_TOUT +#define XB_WID_CTRL_XTALK_IE XB_WID_STAT_XTALK_ERR + +/* XBOW_WID_INT_UPPER */ +/* defined in xwidget.h for WIDGET_INTDEST_UPPER_ADDR */ + +/* XBOW WIDGET part number, in the ID register */ +#define XBOW_WIDGET_PART_NUM 0x0 /* crossbow */ +#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ +#define XBOW_WIDGET_MFGR_NUM 0x0 +#define XXBOW_WIDGET_MFGR_NUM 0x0 + +#define XBOW_REV_1_0 0x1 /* xbow rev 1.0 is "1" */ +#define XBOW_REV_1_1 0x2 /* xbow rev 1.1 is "2" */ +#define XBOW_REV_1_2 0x3 /* xbow rev 1.2 is "3" */ +#define XBOW_REV_1_3 0x4 /* xbow rev 1.3 is "4" */ +#define XBOW_REV_2_0 0x5 /* xbow rev 2.0 is "5" */ + +#define XXBOW_PART_REV_1_0 (XXBOW_WIDGET_PART_NUM << 4 | 0x1 ) +#define XXBOW_PART_REV_2_0 (XXBOW_WIDGET_PART_NUM << 4 | 0x2 ) + +/* XBOW_WID_ARB_RELOAD */ +#define XBOW_WID_ARB_RELOAD_INT 0x3f /* GBR reload interval */ + + +#define nasid_has_xbridge(nasid) \ + (XWIDGET_PART_NUM(XWIDGET_ID_READ(nasid, 0)) == XXBOW_WIDGET_PART_NUM) + + +#ifdef _LANGUAGE_C +/* + * XBOW Widget 0 Register formats. + * Format for many of these registers are similar to the standard + * widget register format described as part of xtalk specification + * Standard widget register field format description is available in + * xwidget.h + * Following structures define the format for xbow widget 0 registers + */ +/* + * Xbow Widget 0 Command error word + */ +#ifdef LITTLE_ENDIAN + +typedef union xbw0_cmdword_u { + xbowreg_t cmdword; + struct { + uint32_t rsvd:8, /* Reserved */ + barr:1, /* Barrier operation */ + error:1, /* Error Occured */ + vbpm:1, /* Virtual Backplane message */ + gbr:1, /* GBR enable ? */ + ds:2, /* Data size */ + ct:1, /* Is it a coherent transaction */ + tnum:5, /* Transaction Number */ + pactyp:4, /* Packet type: */ + srcid:4, /* Source ID number */ + destid:4; /* Desination ID number */ + + } xbw0_cmdfield; +} xbw0_cmdword_t; + +#else + +typedef union xbw0_cmdword_u { + xbowreg_t cmdword; + struct { + uint32_t destid:4, /* Desination ID number */ + srcid:4, /* Source ID number */ + pactyp:4, /* Packet type: */ + tnum:5, /* Transaction Number */ + ct:1, /* Is it a coherent transaction */ + ds:2, /* Data size */ + gbr:1, /* GBR enable ? */ + vbpm:1, /* Virtual Backplane message */ + error:1, /* Error Occured */ + barr:1, /* Barrier operation */ + rsvd:8; /* Reserved */ + } xbw0_cmdfield; +} xbw0_cmdword_t; + +#endif + +#define xbcmd_destid xbw0_cmdfield.destid +#define xbcmd_srcid xbw0_cmdfield.srcid +#define xbcmd_pactyp xbw0_cmdfield.pactyp +#define xbcmd_tnum xbw0_cmdfield.tnum +#define xbcmd_ct xbw0_cmdfield.ct +#define xbcmd_ds xbw0_cmdfield.ds +#define xbcmd_gbr xbw0_cmdfield.gbr +#define xbcmd_vbpm xbw0_cmdfield.vbpm +#define xbcmd_error xbw0_cmdfield.error +#define xbcmd_barr xbw0_cmdfield.barr + +/* + * Values for field PACTYP in xbow error command word + */ +#define XBCMDTYP_READREQ 0 /* Read Request packet */ +#define XBCMDTYP_READRESP 1 /* Read Response packet */ +#define XBCMDTYP_WRREQ_RESP 2 /* Write Request with response */ +#define XBCMDTYP_WRRESP 3 /* Write Response */ +#define XBCMDTYP_WRREQ_NORESP 4 /* Write request with No Response */ +#define XBCMDTYP_FETCHOP 6 /* Fetch & Op packet */ +#define XBCMDTYP_STOREOP 8 /* Store & Op packet */ +#define XBCMDTYP_SPLPKT_REQ 0xE /* Special packet request */ +#define XBCMDTYP_SPLPKT_RESP 0xF /* Special packet response */ + +/* + * Values for field ds (datasize) in xbow error command word + */ +#define XBCMDSZ_DOUBLEWORD 0 +#define XBCMDSZ_QUARTRCACHE 1 +#define XBCMDSZ_FULLCACHE 2 + +/* + * Xbow widget 0 Status register format. + */ +#ifdef LITTLE_ENDIAN + +typedef union xbw0_status_u { + xbowreg_t statusword; + struct { + uint32_t mult_err:1, /* Multiple error occured */ + connect_tout:1, /* Connection timeout */ + xtalk_err:1, /* Xtalk pkt with error bit */ + /* End of Xbridge only */ + w0_arb_tout, /* arbiter timeout err */ + w0_recv_tout, /* receive timeout err */ + /* Xbridge only */ + regacc_err:1, /* Reg Access error */ + src_id:4, /* source id. Xbridge only */ + resvd1:13, + wid0intr:1; /* Widget 0 err intr */ + } xbw0_stfield; +} xbw0_status_t; + +#else + +typedef union xbw0_status_u { + xbowreg_t statusword; + struct { + uint32_t linkXintr:8, /* link(x) error intr */ + wid0intr:1, /* Widget 0 err intr */ + resvd1:13, + src_id:4, /* source id. Xbridge only */ + regacc_err:1, /* Reg Access error */ + /* Xbridge only */ + w0_recv_tout, /* receive timeout err */ + w0_arb_tout, /* arbiter timeout err */ + /* End of Xbridge only */ + xtalk_err:1, /* Xtalk pkt with error bit */ + connect_tout:1, /* Connection timeout */ + mult_err:1; /* Multiple error occured */ + } xbw0_stfield; +} xbw0_status_t; + +#endif + +#define xbst_linkXintr xbw0_stfield.linkXintr +#define xbst_w0intr xbw0_stfield.wid0intr +#define xbst_regacc_err xbw0_stfield.regacc_err +#define xbst_xtalk_err xbw0_stfield.xtalk_err +#define xbst_connect_tout xbw0_stfield.connect_tout +#define xbst_mult_err xbw0_stfield.mult_err +#define xbst_src_id xbw0_stfield.src_id /* Xbridge only */ +#define xbst_w0_recv_tout xbw0_stfield.w0_recv_tout /* Xbridge only */ +#define xbst_w0_arb_tout xbw0_stfield.w0_arb_tout /* Xbridge only */ + +/* + * Xbow widget 0 Control register format + */ +#ifdef LITTLE_ENDIAN + +typedef union xbw0_ctrl_u { + xbowreg_t ctrlword; + struct { + uint32_t + resvd3:1, + conntout_intr:1, + xtalkerr_intr:1, + w0_arg_tout_intr:1, /* Xbridge only */ + w0_recv_tout_intr:1, /* Xbridge only */ + accerr_intr:1, + enable_w0_tout_cntr:1, /* Xbridge only */ + enable_watchdog:1, /* Xbridge only */ + resvd1:24; + } xbw0_ctrlfield; +} xbw0_ctrl_t; + +#else + +typedef union xbw0_ctrl_u { + xbowreg_t ctrlword; + struct { + uint32_t + resvd1:24, + enable_watchdog:1, /* Xbridge only */ + enable_w0_tout_cntr:1, /* Xbridge only */ + accerr_intr:1, + w0_recv_tout_intr:1, /* Xbridge only */ + w0_arg_tout_intr:1, /* Xbridge only */ + xtalkerr_intr:1, + conntout_intr:1, + resvd3:1; + } xbw0_ctrlfield; +} xbw0_ctrl_t; + +#endif + +#ifdef LITTLE_ENDIAN + +typedef union xbow_linkctrl_u { + xbowreg_t xbl_ctrlword; + struct { + uint32_t srcto_intr:1, + maxto_intr:1, + rsvd3:1, + trx_retry_intr:1, + rcv_err_intr:1, + trx_max_retry_intr:1, + trxov_intr:1, + rcvov_intr:1, + bwalloc_intr:1, + rsvd2:7, + obuf_intr:1, + idest_intr:1, + llp_credit:5, + force_badllp:1, + send_bm8:1, + inbuf_level:3, + perf_mode:2, + rsvd1:1, + alive_intr:1; + + } xb_linkcontrol; +} xbow_linkctrl_t; + +#else + +typedef union xbow_linkctrl_u { + xbowreg_t xbl_ctrlword; + struct { + uint32_t alive_intr:1, + rsvd1:1, + perf_mode:2, + inbuf_level:3, + send_bm8:1, + force_badllp:1, + llp_credit:5, + idest_intr:1, + obuf_intr:1, + rsvd2:7, + bwalloc_intr:1, + rcvov_intr:1, + trxov_intr:1, + trx_max_retry_intr:1, + rcv_err_intr:1, + trx_retry_intr:1, + rsvd3:1, + maxto_intr:1, + srcto_intr:1; + } xb_linkcontrol; +} xbow_linkctrl_t; + +#endif + + +#define xbctl_accerr_intr (xbw0_ctrlfield.accerr_intr) +#define xbctl_xtalkerr_intr (xbw0_ctrlfield.xtalkerr_intr) +#define xbctl_cnntout_intr (xbw0_ctrlfield.conntout_intr) + +#define XBW0_CTRL_ACCERR_INTR (1 << 5) +#define XBW0_CTRL_XTERR_INTR (1 << 2) +#define XBW0_CTRL_CONNTOUT_INTR (1 << 1) + +/* + * Xbow Link specific Registers structure definitions. + */ + +#ifdef LITTLE_ENDIAN + +typedef union xbow_linkX_status_u { + xbowreg_t linkstatus; + struct { + uint32_t pkt_toutsrc:1, + pkt_toutconn:1, /* max_req_tout in Xbridge */ + pkt_toutdest:1, /* reserved in Xbridge */ + llp_xmitretry:1, + llp_rcverror:1, + llp_maxtxretry:1, + llp_txovflow:1, + llp_rxovflow:1, + bw_errport:8, /* BW allocation error port */ + ioe:1, /* Input overallocation error */ + illdest:1, + merror:1, + resvd1:12, + alive:1; + } xb_linkstatus; +} xbwX_stat_t; + +#else + +typedef union xbow_linkX_status_u { + xbowreg_t linkstatus; + struct { + uint32_t alive:1, + resvd1:12, + merror:1, + illdest:1, + ioe:1, /* Input overallocation error */ + bw_errport:8, /* BW allocation error port */ + llp_rxovflow:1, + llp_txovflow:1, + llp_maxtxretry:1, + llp_rcverror:1, + llp_xmitretry:1, + pkt_toutdest:1, /* reserved in Xbridge */ + pkt_toutconn:1, /* max_req_tout in Xbridge */ + pkt_toutsrc:1; + } xb_linkstatus; +} xbwX_stat_t; + +#endif + +#define link_alive xb_linkstatus.alive +#define link_multierror xb_linkstatus.merror +#define link_illegal_dest xb_linkstatus.illdest +#define link_ioe xb_linkstatus.ioe +#define link_max_req_tout xb_linkstatus.pkt_toutconn /* Xbridge */ +#define link_pkt_toutconn xb_linkstatus.pkt_toutconn /* Xbow */ +#define link_pkt_toutdest xb_linkstatus.pkt_toutdest +#define link_pkt_toutsrc xb_linkstatus.pkt_toutsrc + +#ifdef LITTLE_ENDIAN + +typedef union xbow_aux_linkX_status_u { + xbowreg_t aux_linkstatus; + struct { + uint32_t rsvd2:4, + bit_mode_8:1, + wid_present:1, + fail_mode:1, + rsvd1:1, + to_src_loc:8, + tx_retry_cnt:8, + rx_err_cnt:8; + } xb_aux_linkstatus; +} xbow_aux_link_status_t; + +#else + +typedef union xbow_aux_linkX_status_u { + xbowreg_t aux_linkstatus; + struct { + uint32_t rx_err_cnt:8, + tx_retry_cnt:8, + to_src_loc:8, + rsvd1:1, + fail_mode:1, + wid_present:1, + bit_mode_8:1, + rsvd2:4; + } xb_aux_linkstatus; +} xbow_aux_link_status_t; + +#endif + + +#ifdef LITTLE_ENDIAN + +typedef union xbow_perf_count_u { + xbowreg_t xb_counter_val; + struct { + uint32_t count:20, + link_select:3, + rsvd:9; + } xb_perf; +} xbow_perfcount_t; + +#else + +typedef union xbow_perf_count_u { + xbowreg_t xb_counter_val; + struct { + uint32_t rsvd:9, + link_select:3, + count:20; + } xb_perf; +} xbow_perfcount_t; + +#endif + +#define XBOW_COUNTER_MASK 0xFFFFF + +extern int xbow_widget_present(xbow_t * xbow, int port); + +extern xwidget_intr_preset_f xbow_intr_preset; +extern xswitch_reset_link_f xbow_reset_link; +void xbow_mlreset(xbow_t *); + +/* ======================================================================== + */ + +#ifdef MACROFIELD_LINE +/* + * This table forms a relation between the byte offset macros normally + * used for ASM coding and the calculated byte offsets of the fields + * in the C structure. + * + * See xbow_check.c xbow_html.c for further details. + */ +#ifndef MACROFIELD_LINE_BITFIELD +#define MACROFIELD_LINE_BITFIELD(m) /* ignored */ +#endif + +struct macrofield_s xbow_macrofield[] = +{ + + MACROFIELD_LINE(XBOW_WID_ID, xb_wid_id) + MACROFIELD_LINE(XBOW_WID_STAT, xb_wid_stat) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0xF)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0xE)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0xD)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0xC)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0xB)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0xA)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0x9)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_LINK_INTR(0x8)) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_WIDGET0_INTR) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_REG_ACC_ERR) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_XTALK_ERR) + MACROFIELD_LINE_BITFIELD(XB_WID_STAT_MULTI_ERR) + MACROFIELD_LINE(XBOW_WID_ERR_UPPER, xb_wid_err_upper) + MACROFIELD_LINE(XBOW_WID_ERR_LOWER, xb_wid_err_lower) + MACROFIELD_LINE(XBOW_WID_CONTROL, xb_wid_control) + MACROFIELD_LINE_BITFIELD(XB_WID_CTRL_REG_ACC_IE) + MACROFIELD_LINE_BITFIELD(XB_WID_CTRL_XTALK_IE) + MACROFIELD_LINE(XBOW_WID_REQ_TO, xb_wid_req_timeout) + MACROFIELD_LINE(XBOW_WID_INT_UPPER, xb_wid_int_upper) + MACROFIELD_LINE(XBOW_WID_INT_LOWER, xb_wid_int_lower) + MACROFIELD_LINE(XBOW_WID_ERR_CMDWORD, xb_wid_err_cmdword) + MACROFIELD_LINE(XBOW_WID_LLP, xb_wid_llp) + MACROFIELD_LINE(XBOW_WID_STAT_CLR, xb_wid_stat_clr) + MACROFIELD_LINE(XBOW_WID_ARB_RELOAD, xb_wid_arb_reload) + MACROFIELD_LINE(XBOW_WID_PERF_CTR_A, xb_perf_ctr_a) + MACROFIELD_LINE(XBOW_WID_PERF_CTR_B, xb_perf_ctr_b) + MACROFIELD_LINE(XBOW_WID_NIC, xb_nic) + MACROFIELD_LINE(XB_LINK_REG_BASE(8), xb_link(8)) + MACROFIELD_LINE(XB_LINK_IBUF_FLUSH(8), xb_link(8).link_ibf) + MACROFIELD_LINE(XB_LINK_CTRL(8), xb_link(8).link_control) + MACROFIELD_LINE_BITFIELD(XB_CTRL_LINKALIVE_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_PERF_CTR_MODE_MSK) + MACROFIELD_LINE_BITFIELD(XB_CTRL_IBUF_LEVEL_MSK) + MACROFIELD_LINE_BITFIELD(XB_CTRL_8BIT_MODE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_BAD_LLP_PKT) + MACROFIELD_LINE_BITFIELD(XB_CTRL_WIDGET_CR_MSK) + MACROFIELD_LINE_BITFIELD(XB_CTRL_ILLEGAL_DST_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_OALLOC_IBUF_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_BNDWDTH_ALLOC_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_RCV_CNT_OFLOW_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_XMT_CNT_OFLOW_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_XMT_MAX_RTRY_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_RCV_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_XMT_RTRY_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_MAXREQ_TOUT_IE) + MACROFIELD_LINE_BITFIELD(XB_CTRL_SRC_TOUT_IE) + MACROFIELD_LINE(XB_LINK_STATUS(8), xb_link(8).link_status) + MACROFIELD_LINE_BITFIELD(XB_STAT_LINKALIVE) + MACROFIELD_LINE_BITFIELD(XB_STAT_MULTI_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_ILLEGAL_DST_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_OALLOC_IBUF_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_BNDWDTH_ALLOC_ID_MSK) + MACROFIELD_LINE_BITFIELD(XB_STAT_RCV_CNT_OFLOW_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_XMT_CNT_OFLOW_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_XMT_MAX_RTRY_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_RCV_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_XMT_RTRY_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_MAXREQ_TOUT_ERR) + MACROFIELD_LINE_BITFIELD(XB_STAT_SRC_TOUT_ERR) + MACROFIELD_LINE(XB_LINK_ARB_UPPER(8), xb_link(8).link_arb_upper) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0xb)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0xb)) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0xa)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0xa)) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0x9)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0x9)) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0x8)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0x8)) + MACROFIELD_LINE(XB_LINK_ARB_LOWER(8), xb_link(8).link_arb_lower) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0xf)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0xf)) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0xe)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0xe)) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0xd)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0xd)) + MACROFIELD_LINE_BITFIELD(XB_ARB_RR_MSK << XB_ARB_RR_SHFT(0xc)) + MACROFIELD_LINE_BITFIELD(XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(0xc)) + MACROFIELD_LINE(XB_LINK_STATUS_CLR(8), xb_link(8).link_status_clr) + MACROFIELD_LINE(XB_LINK_RESET(8), xb_link(8).link_reset) + MACROFIELD_LINE(XB_LINK_AUX_STATUS(8), xb_link(8).link_aux_status) + MACROFIELD_LINE_BITFIELD(XB_AUX_STAT_RCV_CNT) + MACROFIELD_LINE_BITFIELD(XB_AUX_STAT_XMT_CNT) + MACROFIELD_LINE_BITFIELD(XB_AUX_LINKFAIL_RST_BAD) + MACROFIELD_LINE_BITFIELD(XB_AUX_STAT_PRESENT) + MACROFIELD_LINE_BITFIELD(XB_AUX_STAT_PORT_WIDTH) + MACROFIELD_LINE_BITFIELD(XB_AUX_STAT_TOUT_DST) + MACROFIELD_LINE(XB_LINK_REG_BASE(0x8), xb_link(0x8)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0x9), xb_link(0x9)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0xA), xb_link(0xA)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0xB), xb_link(0xB)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0xC), xb_link(0xC)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0xD), xb_link(0xD)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0xE), xb_link(0xE)) + MACROFIELD_LINE(XB_LINK_REG_BASE(0xF), xb_link(0xF)) +}; /* xbow_macrofield[] */ + +#endif /* MACROFIELD_LINE */ + +#endif /* _LANGUAGE_C */ +#endif /* _ASM_SN_SN_XTALK_XBOW_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xbow_info.h linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xbow_info.h --- linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xbow_info.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xbow_info.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,67 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_XTALK_XBOW_INFO_H +#define _ASM_SN_XTALK_XBOW_INFO_H + +#define XBOW_PERF_MODES 0x03 +#define XBOW_PERF_COUNTERS 0x02 + +#define XBOW_MONITOR_NONE 0x00 +#define XBOW_MONITOR_SRC_LINK 0x01 +#define XBOW_MONITOR_DEST_LINK 0x02 +#define XBOW_MONITOR_INP_PKT 0x03 +#define XBOW_MONITOR_MULTIPLEX 0x04 + +#define XBOW_LINK_MULTIPLEX 0x20 + +#define XBOW_PERF_TIMEOUT 4 +#define XBOW_STATS_TIMEOUT HZ + +typedef struct xbow_perf_link { + uint64_t xlp_cumulative[XBOW_PERF_MODES]; + unsigned char xlp_link_alive; +} xbow_perf_link_t; + + +typedef struct xbow_link_status { + uint64_t rx_err_count; + uint64_t tx_retry_count; +} xbow_link_status_t; + + + +typedef struct xbow_perf { + uint32_t xp_current; + unsigned char xp_link; + unsigned char xp_mode; + unsigned char xp_curlink; + unsigned char xp_curmode; + volatile uint32_t *xp_perf_reg; +} xbow_perf_t; + +extern void xbow_update_perf_counters(devfs_handle_t); +extern xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t); +extern int xbow_enable_perf_counter(devfs_handle_t, int, int, int); + +#define XBOWIOC_PERF_ENABLE 1 +#define XBOWIOC_PERF_DISABLE 2 +#define XBOWIOC_PERF_GET 3 +#define XBOWIOC_LLP_ERROR_ENABLE 4 +#define XBOWIOC_LLP_ERROR_DISABLE 5 +#define XBOWIOC_LLP_ERROR_GET 6 + + +struct xbow_perfarg_t { + int link; + int mode; + int counter; +}; + +#endif /* _ASM_SN_XTALK_XBOW_INFO_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xswitch.h linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xswitch.h --- linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xswitch.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xswitch.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,59 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_XTALK_XSWITCH_H +#define _ASM_SN_XTALK_XSWITCH_H + +/* + * xswitch.h - controls the format of the data + * provided by xswitch verticies back to the + * xtalk bus providers. + */ + +#if LANGUAGE_C + +typedef struct xswitch_info_s *xswitch_info_t; + +typedef int + xswitch_reset_link_f(devfs_handle_t xconn); + +typedef struct xswitch_provider_s { + xswitch_reset_link_f *reset_link; +} xswitch_provider_t; + +extern void xswitch_provider_register(devfs_handle_t sw_vhdl, xswitch_provider_t * xsw_fns); + +xswitch_reset_link_f xswitch_reset_link; + +extern xswitch_info_t xswitch_info_new(devfs_handle_t vhdl); + +extern void xswitch_info_link_is_ok(xswitch_info_t xswitch_info, + xwidgetnum_t port); +extern void xswitch_info_vhdl_set(xswitch_info_t xswitch_info, + xwidgetnum_t port, + devfs_handle_t xwidget); +extern void xswitch_info_master_assignment_set(xswitch_info_t xswitch_info, + xwidgetnum_t port, + devfs_handle_t master_vhdl); + +extern xswitch_info_t xswitch_info_get(devfs_handle_t vhdl); + +extern int xswitch_info_link_ok(xswitch_info_t xswitch_info, + xwidgetnum_t port); +extern devfs_handle_t xswitch_info_vhdl_get(xswitch_info_t xswitch_info, + xwidgetnum_t port); +extern devfs_handle_t xswitch_info_master_assignment_get(xswitch_info_t xswitch_info, + xwidgetnum_t port); + +extern int xswitch_id_get(devfs_handle_t vhdl); +extern void xswitch_id_set(devfs_handle_t vhdl,int xbow_num); + +#endif /* LANGUAGE_C */ + +#endif /* _ASM_SN_XTALK_XSWITCH_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xtalk.h linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xtalk.h --- linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xtalk.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xtalk.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,408 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_XTALK_XTALK_H +#define _ASM_SN_XTALK_XTALK_H + +/* + * xtalk.h -- platform-independent crosstalk interface + */ +/* + * User-level device driver visible types + */ +typedef char xwidgetnum_t; /* xtalk widget number (0..15) */ + +#define XWIDGET_NONE -1 + +typedef int xwidget_part_num_t; /* xtalk widget part number */ + +#define XWIDGET_PART_NUM_NONE -1 + +typedef int xwidget_rev_num_t; /* xtalk widget revision number */ + +#define XWIDGET_REV_NUM_NONE -1 + +typedef int xwidget_mfg_num_t; /* xtalk widget manufacturing ID */ + +#define XWIDGET_MFG_NUM_NONE -1 + +typedef struct xtalk_piomap_s *xtalk_piomap_t; + +/* It is often convenient to fold the XIO target port + * number into the XIO address. + */ +#define XIO_NOWHERE (0xFFFFFFFFFFFFFFFFull) +#define XIO_ADDR_BITS (0x0000FFFFFFFFFFFFull) +#define XIO_PORT_BITS (0xF000000000000000ull) +#define XIO_PORT_SHIFT (60) + +#define XIO_PACKED(x) (((x)&XIO_PORT_BITS) != 0) +#define XIO_ADDR(x) ((x)&XIO_ADDR_BITS) +#define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT)) +#define XIO_PACK(p,o) ((((uint64_t)(p))< +#include +#include +#include +#include +#include + +struct xwidget_hwid_s; + +/* + * Acceptable flag bits for xtalk service calls + * + * XTALK_FIXED: require that mappings be established + * using fixed sharable resources; address + * translation results will be permanently + * available. (PIOMAP_FIXED and DMAMAP_FIXED are + * the same numeric value and are acceptable). + * XTALK_NOSLEEP: if any part of the operation would + * sleep waiting for resoruces, return an error + * instead. (PIOMAP_NOSLEEP and DMAMAP_NOSLEEP are + * the same numeric value and are acceptable). + * XTALK_INPLACE: when operating on alenlist structures, + * reuse the source alenlist rather than creating a + * new one. (PIOMAP_INPLACE and DMAMAP_INPLACE are + * the same numeric value and are acceptable). + */ +#define XTALK_FIXED DMAMAP_FIXED +#define XTALK_NOSLEEP DMAMAP_NOSLEEP +#define XTALK_INPLACE DMAMAP_INPLACE + +/* PIO MANAGEMENT */ +typedef xtalk_piomap_t +xtalk_piomap_alloc_f (devfs_handle_t dev, /* set up mapping for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* map for this xtalk_addr range */ + size_t byte_count, + size_t byte_count_max, /* maximum size of a mapping */ + unsigned flags); /* defined in sys/pio.h */ +typedef void +xtalk_piomap_free_f (xtalk_piomap_t xtalk_piomap); + +typedef caddr_t +xtalk_piomap_addr_f (xtalk_piomap_t xtalk_piomap, /* mapping resources */ + iopaddr_t xtalk_addr, /* map for this xtalk address */ + size_t byte_count); /* map this many bytes */ + +typedef void +xtalk_piomap_done_f (xtalk_piomap_t xtalk_piomap); + +typedef caddr_t +xtalk_piotrans_addr_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* Crosstalk address */ + size_t byte_count, /* map this many bytes */ + unsigned flags); /* (currently unused) */ + +extern caddr_t +xtalk_pio_addr (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + iopaddr_t xtalk_addr, /* Crosstalk address */ + size_t byte_count, /* map this many bytes */ + xtalk_piomap_t *xtalk_piomapp, /* RETURNS mapping resources */ + unsigned flags); /* (currently unused) */ + +/* DMA MANAGEMENT */ + +typedef struct xtalk_dmamap_s *xtalk_dmamap_t; + +typedef xtalk_dmamap_t +xtalk_dmamap_alloc_f (devfs_handle_t dev, /* set up mappings for this device */ + device_desc_t dev_desc, /* device descriptor */ + size_t byte_count_max, /* max size of a mapping */ + unsigned flags); /* defined in dma.h */ + +typedef void +xtalk_dmamap_free_f (xtalk_dmamap_t dmamap); + +typedef iopaddr_t +xtalk_dmamap_addr_f (xtalk_dmamap_t dmamap, /* use these mapping resources */ + paddr_t paddr, /* map for this address */ + size_t byte_count); /* map this many bytes */ + +typedef alenlist_t +xtalk_dmamap_list_f (xtalk_dmamap_t dmamap, /* use these mapping resources */ + alenlist_t alenlist, /* map this address/length list */ + unsigned flags); + +typedef void +xtalk_dmamap_done_f (xtalk_dmamap_t dmamap); + +typedef iopaddr_t +xtalk_dmatrans_addr_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + paddr_t paddr, /* system physical address */ + size_t byte_count, /* length */ + unsigned flags); + +typedef alenlist_t +xtalk_dmatrans_list_f (devfs_handle_t dev, /* translate for this device */ + device_desc_t dev_desc, /* device descriptor */ + alenlist_t palenlist, /* system address/length list */ + unsigned flags); + +typedef void +xtalk_dmamap_drain_f (xtalk_dmamap_t map); /* drain this map's channel */ + +typedef void +xtalk_dmaaddr_drain_f (devfs_handle_t vhdl, /* drain channel from this device */ + paddr_t addr, /* to this physical address */ + size_t bytes); /* for this many bytes */ + +typedef void +xtalk_dmalist_drain_f (devfs_handle_t vhdl, /* drain channel from this device */ + alenlist_t list); /* for this set of physical blocks */ + + +/* INTERRUPT MANAGEMENT */ + +/* + * A xtalk interrupt resource handle. When resources are allocated + * in order to satisfy a xtalk_intr_alloc request, a xtalk_intr handle + * is returned. xtalk_intr_connect associates a software handler with + + * these system resources. + */ +typedef struct xtalk_intr_s *xtalk_intr_t; + + +/* + * When a crosstalk device connects an interrupt, it passes in a function + * that knows how to set its xtalk interrupt register appropriately. The + * low-level interrupt code may invoke this function later in order to + * migrate an interrupt transparently to the device driver(s) that use this + * interrupt. + * + * The argument passed to this function contains enough information for a + * crosstalk device to (re-)target an interrupt. A function of this type + * must be supplied by every crosstalk driver. + */ +typedef int +xtalk_intr_setfunc_f (xtalk_intr_t intr_hdl); /* interrupt handle */ + +typedef xtalk_intr_t +xtalk_intr_alloc_f (devfs_handle_t dev, /* which crosstalk device */ + device_desc_t dev_desc, /* device descriptor */ + devfs_handle_t owner_dev); /* owner of this intr */ + +typedef void +xtalk_intr_free_f (xtalk_intr_t intr_hdl); + +typedef int +xtalk_intr_connect_f (xtalk_intr_t intr_hdl, /* xtalk intr resource handle */ + intr_func_t intr_func, /* xtalk intr handler */ + void *intr_arg, /* arg to intr handler */ + xtalk_intr_setfunc_f *setfunc, /* func to set intr hw */ + void *setfunc_arg, /* arg to setfunc. This must be */ + /* sufficient to determine which */ + /* interrupt on which board needs */ + /* to be set. */ + void *thread); /* which intr thread to use */ + +typedef void +xtalk_intr_disconnect_f (xtalk_intr_t intr_hdl); + +typedef devfs_handle_t +xtalk_intr_cpu_get_f (xtalk_intr_t intr_hdl); /* xtalk intr resource handle */ + +/* CONFIGURATION MANAGEMENT */ + +typedef void +xtalk_provider_startup_f (devfs_handle_t xtalk_provider); + +typedef void +xtalk_provider_shutdown_f (devfs_handle_t xtalk_provider); + +typedef void +xtalk_widgetdev_enable_f (devfs_handle_t, int); + +typedef void +xtalk_widgetdev_shutdown_f (devfs_handle_t, int); + +typedef int +xtalk_dma_enabled_f (devfs_handle_t); + +/* Error Management */ + +typedef int +xtalk_error_devenable_f (devfs_handle_t xconn_vhdl, + int devnum, + int error_code); + +/* Early Action Support */ +typedef caddr_t +xtalk_early_piotrans_addr_f (xwidget_part_num_t part_num, + xwidget_mfg_num_t mfg_num, + int which, + iopaddr_t xtalk_addr, + size_t byte_count, + unsigned flags); + +/* + * Adapters that provide a crosstalk interface adhere to this software interface. + */ +typedef struct xtalk_provider_s { + /* PIO MANAGEMENT */ + xtalk_piomap_alloc_f *piomap_alloc; + xtalk_piomap_free_f *piomap_free; + xtalk_piomap_addr_f *piomap_addr; + xtalk_piomap_done_f *piomap_done; + xtalk_piotrans_addr_f *piotrans_addr; + + /* DMA MANAGEMENT */ + xtalk_dmamap_alloc_f *dmamap_alloc; + xtalk_dmamap_free_f *dmamap_free; + xtalk_dmamap_addr_f *dmamap_addr; + xtalk_dmamap_list_f *dmamap_list; + xtalk_dmamap_done_f *dmamap_done; + xtalk_dmatrans_addr_f *dmatrans_addr; + xtalk_dmatrans_list_f *dmatrans_list; + xtalk_dmamap_drain_f *dmamap_drain; + xtalk_dmaaddr_drain_f *dmaaddr_drain; + xtalk_dmalist_drain_f *dmalist_drain; + + /* INTERRUPT MANAGEMENT */ + xtalk_intr_alloc_f *intr_alloc; + xtalk_intr_free_f *intr_free; + xtalk_intr_connect_f *intr_connect; + xtalk_intr_disconnect_f *intr_disconnect; + xtalk_intr_cpu_get_f *intr_cpu_get; + + /* CONFIGURATION MANAGEMENT */ + xtalk_provider_startup_f *provider_startup; + xtalk_provider_shutdown_f *provider_shutdown; + + /* Error Management */ + xtalk_error_devenable_f *error_devenable; +} xtalk_provider_t; + +/* Crosstalk devices use these standard Crosstalk provider interfaces */ +extern xtalk_piomap_alloc_f xtalk_piomap_alloc; +extern xtalk_piomap_free_f xtalk_piomap_free; +extern xtalk_piomap_addr_f xtalk_piomap_addr; +extern xtalk_piomap_done_f xtalk_piomap_done; +extern xtalk_piotrans_addr_f xtalk_piotrans_addr; +extern xtalk_dmamap_alloc_f xtalk_dmamap_alloc; +extern xtalk_dmamap_free_f xtalk_dmamap_free; +extern xtalk_dmamap_addr_f xtalk_dmamap_addr; +extern xtalk_dmamap_list_f xtalk_dmamap_list; +extern xtalk_dmamap_done_f xtalk_dmamap_done; +extern xtalk_dmatrans_addr_f xtalk_dmatrans_addr; +extern xtalk_dmatrans_list_f xtalk_dmatrans_list; +extern xtalk_dmamap_drain_f xtalk_dmamap_drain; +extern xtalk_dmaaddr_drain_f xtalk_dmaaddr_drain; +extern xtalk_dmalist_drain_f xtalk_dmalist_drain; +extern xtalk_intr_alloc_f xtalk_intr_alloc; +extern xtalk_intr_free_f xtalk_intr_free; +extern xtalk_intr_connect_f xtalk_intr_connect; +extern xtalk_intr_disconnect_f xtalk_intr_disconnect; +extern xtalk_intr_cpu_get_f xtalk_intr_cpu_get; +extern xtalk_provider_startup_f xtalk_provider_startup; +extern xtalk_provider_shutdown_f xtalk_provider_shutdown; +extern xtalk_widgetdev_enable_f xtalk_widgetdev_enable; +extern xtalk_widgetdev_shutdown_f xtalk_widgetdev_shutdown; +extern xtalk_dma_enabled_f xtalk_dma_enabled; +extern xtalk_error_devenable_f xtalk_error_devenable; +extern xtalk_early_piotrans_addr_f xtalk_early_piotrans_addr; + +/* error management */ + +extern int xtalk_error_handler(devfs_handle_t, + int, + ioerror_mode_t, + ioerror_t *); + +/* + * Generic crosstalk interface, for use with all crosstalk providers + * and all crosstalk devices. + */ +typedef unchar xtalk_intr_vector_t; /* crosstalk interrupt vector (0..255) */ + +#define XTALK_INTR_VECTOR_NONE (xtalk_intr_vector_t)0 + +/* Generic crosstalk interrupt interfaces */ +extern devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t xtalk_intr); +extern xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t xtalk_intr); +extern xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t xtalk_intr); +extern iopaddr_t xtalk_intr_addr_get(xtalk_intr_t xtalk_intr); +extern devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t xtalk_intr); +extern void *xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr); + +extern int xtalk_intr_flags_get(xtalk_intr_t xtalk_intr); +/* XTALK_INTR flags */ +#define XTALK_INTR_NOTHREAD 1 /* interrupt handler wants to be called at interrupt level */ + +/* Generic crosstalk pio interfaces */ +extern devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap); +extern xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap); +extern iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap); +extern size_t xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap); +extern caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap); + +/* Generic crosstalk dma interfaces */ +extern devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap); +extern xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap); + +/* Register/unregister Crosstalk providers and get implementation handle */ +extern void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *); +extern void xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns); +extern void xtalk_provider_unregister(devfs_handle_t provider); +extern xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t provider); + +/* Crosstalk Switch generic layer, for use by initialization code */ +extern void xswitch_census(devfs_handle_t xswitchv); +extern void xswitch_init_widgets(devfs_handle_t xswitchv); + +/* early init interrupt management */ + +typedef void +xwidget_intr_preset_f (void *which_widget, + int which_widget_intr, + xwidgetnum_t targ, + iopaddr_t addr, + xtalk_intr_vector_t vect); + +typedef void +xtalk_intr_prealloc_f (void *which_xtalk, + xtalk_intr_vector_t xtalk_vector, + xwidget_intr_preset_f *preset_func, + void *which_widget, + int which_widget_intr); + +typedef void +xtalk_intr_preconn_f (void *which_xtalk, + xtalk_intr_vector_t xtalk_vector, + intr_func_t intr_func, + intr_arg_t intr_arg); + + +#define XTALK_ADDR_TO_UPPER(xtalk_addr) (((iopaddr_t)(xtalk_addr) >> 32) & 0xffff) +#define XTALK_ADDR_TO_LOWER(xtalk_addr) ((iopaddr_t)(xtalk_addr) & 0xffffffff) + +typedef xtalk_intr_setfunc_f *xtalk_intr_setfunc_t; + +typedef void xtalk_iter_f(devfs_handle_t vhdl); + +extern void xtalk_iterate(char *prefix, xtalk_iter_f *func); + +extern int xtalk_device_powerup(devfs_handle_t, xwidgetnum_t); +extern int xtalk_device_shutdown(devfs_handle_t, xwidgetnum_t); +extern int xtalk_device_inquiry(devfs_handle_t, xwidgetnum_t); + +#endif /* __KERNEL__ */ +#endif /* _ASM_SN_XTALK_XTALK_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xtalk_private.h linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xtalk_private.h --- linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xtalk_private.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xtalk_private.h Wed Dec 6 21:56:16 2000 @@ -0,0 +1,90 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_XTALK_XTALK_PRIVATE_H +#define _ASM_SN_XTALK_XTALK_PRIVATE_H + +#ifdef IRIX +#include /* for error function and arg types */ +#else +#include /* for error function and arg types */ +#endif + +/* + * xtalk_private.h -- private definitions for xtalk + * crosstalk drivers should NOT include this file. + */ + +/* + * All Crosstalk providers set up PIO using this information. + */ +struct xtalk_piomap_s { + devfs_handle_t xp_dev; /* a requestor of this mapping */ + xwidgetnum_t xp_target; /* target (node's widget number) */ + iopaddr_t xp_xtalk_addr; /* which crosstalk addr is mapped */ + size_t xp_mapsz; /* size of this mapping */ + caddr_t xp_kvaddr; /* kernel virtual address to use */ +}; + +/* + * All Crosstalk providers set up DMA using this information. + */ +struct xtalk_dmamap_s { + devfs_handle_t xd_dev; /* a requestor of this mapping */ + xwidgetnum_t xd_target; /* target (node's widget number) */ +}; + +/* + * All Crosstalk providers set up interrupts using this information. + */ +struct xtalk_intr_s { + int xi_flags; /* XTALK_INTR flags */ + devfs_handle_t xi_dev; /* requestor of this intr */ + xwidgetnum_t xi_target; /* master's widget number */ + xtalk_intr_vector_t xi_vector; /* 8-bit interrupt vector */ + iopaddr_t xi_addr; /* xtalk address to generate intr */ + void *xi_sfarg; /* argument for setfunc */ + xtalk_intr_setfunc_t xi_setfunc; /* device's setfunc routine */ +}; + +/* + * Xtalk interrupt handler structure access functions + */ +#define xtalk_intr_arg(xt) ((xt)->xi_sfarg) + +#define xwidget_hwid_is_sn0_xswitch(_hwid) \ + (((_hwid)->part_num == XBOW_WIDGET_PART_NUM ) && \ + ((_hwid)->mfg_num == XBOW_WIDGET_MFGR_NUM )) + +#define xwidget_hwid_is_sn1_xswitch(_hwid) \ + (((_hwid)->part_num == XXBOW_WIDGET_PART_NUM ) && \ + ((_hwid)->mfg_num == XXBOW_WIDGET_MFGR_NUM )) + +#define xwidget_hwid_is_xswitch(_hwid) \ + (xwidget_hwid_is_sn0_xswitch(_hwid) || \ + xwidget_hwid_is_sn1_xswitch(_hwid)) + +/* common iograph info for all widgets, + * stashed in FASTINFO of widget connection points. + */ +struct xwidget_info_s { + char *w_fingerprint; + devfs_handle_t w_vertex; /* back pointer to vertex */ + xwidgetnum_t w_id; /* widget id */ + struct xwidget_hwid_s w_hwid; /* hardware identification (part/rev/mfg) */ + devfs_handle_t w_master; /* CACHED widget's master */ + xwidgetnum_t w_masterid; /* CACHED widget's master's widgetnum */ + error_handler_f *w_efunc; /* error handling function */ + error_handler_arg_t w_einfo; /* first parameter for efunc */ + char *w_name; /* canonical hwgraph name */ +}; + +extern char widget_info_fingerprint[]; + +#endif /* _ASM_SN_XTALK_XTALK_PRIVATE_H */ diff -urN linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xtalkaddrs.h linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xtalkaddrs.h --- linux-2.4.0-test12/include/asm-ia64/sn/xtalk/xtalkaddrs.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/asm-ia64/sn/xtalk/xtalkaddrs.h Wed Dec 13 19:35:44 2000 @@ -0,0 +1,111 @@ +/* $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 Silicon Graphics, Inc. + * Copyright (C) 2000 by Colin Ngam + */ +#ifndef _ASM_SN_XTALK_XTALKADDRS_H +#define _ASM_SN_XTALK_XTALKADDRS_H + +/* + * CrossTalk to SN0 Hub addressing support + * + * This file defines the mapping conventions used by the Hub's + * I/O interface when it receives a read or write request from + * a CrossTalk widget. + * + * Format for non-Memory accesses: + * + * +--------------+------------------------------------------------+ + * | 0 | XXXXX | SN0Addr | + * +----+---------+------------------------------------------------+ + * 47 46 40 39 0 + * bit 47 indicates Memory (0) + * bits 46..40 are unused + * bits 39..0 hold the memory address + * (bits 39..31 hold the nodeID in N mode + * bits 39..32 hold the nodeID in M mode + * By design, this looks exactly like a 0-extended SN0 Address, so + * we don't need to do any conversions. + * + * + * + * Format for non-Memory accesses: + * + * +--------------+------+---------+------+--+---------------------+ + * | 1 | DstNode | XXXX | BigW=0 | SW=1 | 1| Addr | + * +----+---------+------+---------+------+--+---------------------+ + * 47 46 38 37 31 30 28 27 24 23 22 0 + * + * bit 47 indicates IO (1) + * bits 46..38 hold the destination node ID + * bits 37..31 are unused + * bits 30..28 hold the big window being addressed + * bits 27..24 hold the small window being addressed + * 0 always refers to the xbow + * 1 always refers to the hub itself + * bit 23 indicates local (0) or remote (1) + * no accessing checks are done if this bit is 0 + * bits 22..0 hold the register address + * bits 22..21 determine which section of the hub + * 00 -> PI + * 01 -> MD + * 10 -> IO + * 11 -> NI + * This looks very much like a REMOTE_HUB access, except the nodeID + * is in a different place, and the highest xtalk bit is set. + */ + +/* Hub-specific xtalk definitions */ + +#define HX_MEM_BIT 0L /* Hub's idea of xtalk memory access */ +#define HX_IO_BIT 1L /* Hub's idea of xtalk register access */ +#define HX_ACCTYPE_SHIFT 47 + +#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC +#define HX_NODE_SHIFT 39 +#endif + +#define HX_BIGWIN_SHIFT 28 + +#define HX_SWIN_SHIFT 23 + +#define HX_LOCACC 0L /* local access */ +#define HX_REMACC 1L /* remote access */ +#define HX_ACCESS_SHIFT 23 + +/* + * Pre-calculate the fixed portion of a crosstalk address that maps + * to local register space on a hub. + */ +#define HX_REG_BASE ((HX_IO_BIT< +#if LANGUAGE_C +#include +#endif /* LANGUAGE_C */ + +#ifdef LITTLE_ENDIAN +#define WIDGET_ID 0x00 +#define WIDGET_STATUS 0x08 +#define WIDGET_ERR_UPPER_ADDR 0x10 +#define WIDGET_ERR_LOWER_ADDR 0x18 +#define WIDGET_CONTROL 0x20 +#define WIDGET_REQ_TIMEOUT 0x28 +#define WIDGET_INTDEST_UPPER_ADDR 0x30 +#define WIDGET_INTDEST_LOWER_ADDR 0x38 +#define WIDGET_ERR_CMD_WORD 0x40 +#define WIDGET_LLP_CFG 0x48 +#define WIDGET_TFLUSH 0x50 +#else /* !LITTLE_ENDIAN */ +#define WIDGET_ID 0x04 +#define WIDGET_STATUS 0x0c +#define WIDGET_ERR_UPPER_ADDR 0x14 +#define WIDGET_ERR_LOWER_ADDR 0x1c +#define WIDGET_CONTROL 0x24 +#define WIDGET_REQ_TIMEOUT 0x2c +#define WIDGET_INTDEST_UPPER_ADDR 0x34 +#define WIDGET_INTDEST_LOWER_ADDR 0x3c +#define WIDGET_ERR_CMD_WORD 0x44 +#define WIDGET_LLP_CFG 0x4c +#define WIDGET_TFLUSH 0x54 +#endif + +/* WIDGET_ID */ +#define WIDGET_REV_NUM 0xf0000000 +#define WIDGET_PART_NUM 0x0ffff000 +#define WIDGET_MFG_NUM 0x00000ffe +#define WIDGET_REV_NUM_SHFT 28 +#define WIDGET_PART_NUM_SHFT 12 +#define WIDGET_MFG_NUM_SHFT 1 + +#define XWIDGET_PART_NUM(widgetid) (((widgetid) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT) +#define XWIDGET_REV_NUM(widgetid) (((widgetid) & WIDGET_REV_NUM) >> WIDGET_REV_NUM_SHFT) +#define XWIDGET_MFG_NUM(widgetid) (((widgetid) & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT) +#define XWIDGET_PART_REV_NUM(widgetid) ((XWIDGET_PART_NUM(widgetid) << 4) | \ + XWIDGET_REV_NUM(widgetid)) + +/* WIDGET_STATUS */ +#define WIDGET_LLP_REC_CNT 0xff000000 +#define WIDGET_LLP_TX_CNT 0x00ff0000 +#define WIDGET_PENDING 0x0000001f + +/* WIDGET_ERR_UPPER_ADDR */ +#define WIDGET_ERR_UPPER_ADDR_ONLY 0x0000ffff + +/* WIDGET_CONTROL */ +#define WIDGET_F_BAD_PKT 0x00010000 +#define WIDGET_LLP_XBAR_CRD 0x0000f000 +#define WIDGET_LLP_XBAR_CRD_SHFT 12 +#define WIDGET_CLR_RLLP_CNT 0x00000800 +#define WIDGET_CLR_TLLP_CNT 0x00000400 +#define WIDGET_SYS_END 0x00000200 +#define WIDGET_MAX_TRANS 0x000001f0 +#define WIDGET_PCI_SPEED 0x00000030 +#define WIDGET_PCI_SPEED_SHFT 4 +#define WIDGET_PCI_SPEED_33MHZ 0 +#define WIDGET_PCI_SPEED_66MHZ 1 +#define WIDGET_WIDGET_ID 0x0000000f + +/* WIDGET_INTDEST_UPPER_ADDR */ +#define WIDGET_INT_VECTOR 0xff000000 +#define WIDGET_INT_VECTOR_SHFT 24 +#define WIDGET_TARGET_ID 0x000f0000 +#define WIDGET_TARGET_ID_SHFT 16 +#define WIDGET_UPP_ADDR 0x0000ffff + +/* WIDGET_ERR_CMD_WORD */ +#define WIDGET_DIDN 0xf0000000 +#define WIDGET_SIDN 0x0f000000 +#define WIDGET_PACTYP 0x00f00000 +#define WIDGET_TNUM 0x000f8000 +#define WIDGET_COHERENT 0x00004000 +#define WIDGET_DS 0x00003000 +#define WIDGET_GBR 0x00000800 +#define WIDGET_VBPM 0x00000400 +#define WIDGET_ERROR 0x00000200 +#define WIDGET_BARRIER 0x00000100 + +/* WIDGET_LLP_CFG */ +#define WIDGET_LLP_MAXRETRY 0x03ff0000 +#define WIDGET_LLP_MAXRETRY_SHFT 16 +#define WIDGET_LLP_NULLTIMEOUT 0x0000fc00 +#define WIDGET_LLP_NULLTIMEOUT_SHFT 10 +#define WIDGET_LLP_MAXBURST 0x000003ff +#define WIDGET_LLP_MAXBURST_SHFT 0 + +/* + * according to the crosstalk spec, only 32-bits access to the widget + * configuration registers is allowed. some widgets may allow 64-bits + * access but software should not depend on it. registers beyond the + * widget target flush register are widget dependent thus will not be + * defined here + */ +#if _LANGUAGE_C +typedef uint32_t widgetreg_t; + +/* widget configuration registers */ +typedef volatile struct widget_cfg { +#ifdef LITTLE_ENDIAN +/* + * we access these through synergy unswizzled space, so the address + * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) + * That's why we put the register first and filler second. + */ + widgetreg_t w_id; /* 0x04 */ + widgetreg_t w_pad_0; /* 0x00 */ + widgetreg_t w_status; /* 0x0c */ + widgetreg_t w_pad_1; /* 0x08 */ + widgetreg_t w_err_upper_addr; /* 0x14 */ + widgetreg_t w_pad_2; /* 0x10 */ + widgetreg_t w_err_lower_addr; /* 0x1c */ + widgetreg_t w_pad_3; /* 0x18 */ + widgetreg_t w_control; /* 0x24 */ + widgetreg_t w_pad_4; /* 0x20 */ + widgetreg_t w_req_timeout; /* 0x2c */ + widgetreg_t w_pad_5; /* 0x28 */ + widgetreg_t w_intdest_upper_addr; /* 0x34 */ + widgetreg_t w_pad_6; /* 0x30 */ + widgetreg_t w_intdest_lower_addr; /* 0x3c */ + widgetreg_t w_pad_7; /* 0x38 */ + widgetreg_t w_err_cmd_word; /* 0x44 */ + widgetreg_t w_pad_8; /* 0x40 */ + widgetreg_t w_llp_cfg; /* 0x4c */ + widgetreg_t w_pad_9; /* 0x48 */ + widgetreg_t w_tflush; /* 0x54 */ + widgetreg_t w_pad_10; /* 0x50 */ +#else + widgetreg_t w_pad_0; /* 0x00 */ + widgetreg_t w_id; /* 0x04 */ + widgetreg_t w_pad_1; /* 0x08 */ + widgetreg_t w_status; /* 0x0c */ + widgetreg_t w_pad_2; /* 0x10 */ + widgetreg_t w_err_upper_addr; /* 0x14 */ + widgetreg_t w_pad_3; /* 0x18 */ + widgetreg_t w_err_lower_addr; /* 0x1c */ + widgetreg_t w_pad_4; /* 0x20 */ + widgetreg_t w_control; /* 0x24 */ + widgetreg_t w_pad_5; /* 0x28 */ + widgetreg_t w_req_timeout; /* 0x2c */ + widgetreg_t w_pad_6; /* 0x30 */ + widgetreg_t w_intdest_upper_addr; /* 0x34 */ + widgetreg_t w_pad_7; /* 0x38 */ + widgetreg_t w_intdest_lower_addr; /* 0x3c */ + widgetreg_t w_pad_8; /* 0x40 */ + widgetreg_t w_err_cmd_word; /* 0x44 */ + widgetreg_t w_pad_9; /* 0x48 */ + widgetreg_t w_llp_cfg; /* 0x4c */ + widgetreg_t w_pad_10; /* 0x50 */ + widgetreg_t w_tflush; /* 0x54 */ +#endif /* LITTLE_ENDIAN */ +} widget_cfg_t; + +#ifdef LITTLE_ENDIAN +typedef struct { + unsigned other:8; + unsigned bo:1; + unsigned error:1; + unsigned vbpm:1; + unsigned gbr:1; + unsigned ds:2; + unsigned ct:1; + unsigned tnum:5; + unsigned pactyp:4; + unsigned sidn:4; + unsigned didn:4; +} w_err_cmd_word_f; +#else +typedef struct { + unsigned didn:4; + unsigned sidn:4; + unsigned pactyp:4; + unsigned tnum:5; + unsigned ct:1; + unsigned ds:2; + unsigned gbr:1; + unsigned vbpm:1; + unsigned error:1; + unsigned bo:1; + unsigned other:8; +} w_err_cmd_word_f; +#endif + +#ifdef LITTLE_ENDIAN +typedef union { + w_err_cmd_word_f f; + widgetreg_t r; +} w_err_cmd_word_u; +#else +typedef union { + widgetreg_t r; + w_err_cmd_word_f f; +} w_err_cmd_word_u; +#endif + +/* IO widget initialization function */ +typedef struct xwidget_info_s *xwidget_info_t; + +/* + * Crosstalk Widget Hardware Identification, as defined in the Crosstalk spec. + */ +#ifdef LITTLE_ENDIAN +typedef struct xwidget_hwid_s { + xwidget_mfg_num_t mfg_num; + xwidget_rev_num_t rev_num; + xwidget_part_num_t part_num; +} *xwidget_hwid_t; +#else +typedef struct xwidget_hwid_s { + xwidget_part_num_t part_num; + xwidget_rev_num_t rev_num; + xwidget_mfg_num_t mfg_num; +} *xwidget_hwid_t; +#endif + + +/* + * Returns 1 if a driver that handles devices described by hwid1 is able + * to manage a device with hardwareid hwid2. NOTE: We don't check rev + * numbers at all. + */ +#define XWIDGET_HARDWARE_ID_MATCH(hwid1, hwid2) \ + (((hwid1)->part_num == (hwid2)->part_num) && \ + (((hwid1)->mfg_num == XWIDGET_MFG_NUM_NONE) || \ + ((hwid2)->mfg_num == XWIDGET_MFG_NUM_NONE) || \ + ((hwid1)->mfg_num == (hwid2)->mfg_num))) + + +/* Generic crosstalk widget initialization interface */ +#if __KERNEL__ + +extern int xwidget_driver_register(xwidget_part_num_t part_num, + xwidget_mfg_num_t mfg_num, + char *driver_prefix, + unsigned flags); + +extern void xwidget_driver_unregister(char *driver_prefix); + +extern int xwidget_register(struct xwidget_hwid_s *hwid, + devfs_handle_t dev, + xwidgetnum_t id, + devfs_handle_t master, + xwidgetnum_t targetid, + async_attach_t aa); + +extern int xwidget_unregister(devfs_handle_t); +extern void xwidget_error_register(devfs_handle_t xwidget, + error_handler_f * efunc, + error_handler_arg_t einfo); + +extern void xwidget_reset(devfs_handle_t xwidget); +extern void xwidget_gfx_reset(devfs_handle_t xwidget); +extern char *xwidget_name_get(devfs_handle_t xwidget); + +/* Generic crosstalk widget information access interface */ +extern xwidget_info_t xwidget_info_chk(devfs_handle_t widget); +extern xwidget_info_t xwidget_info_get(devfs_handle_t widget); +extern void xwidget_info_set(devfs_handle_t widget, xwidget_info_t widget_info); +extern devfs_handle_t xwidget_info_dev_get(xwidget_info_t xwidget_info); +extern xwidgetnum_t xwidget_info_id_get(xwidget_info_t xwidget_info); +extern int xwidget_info_type_get(xwidget_info_t xwidget_info); +extern int xwidget_info_state_get(xwidget_info_t xwidget_info); +extern devfs_handle_t xwidget_info_master_get(xwidget_info_t xwidget_info); +extern xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t xwidget_info); +extern xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t xwidget_info); +extern xwidget_rev_num_t xwidget_info_rev_num_get(xwidget_info_t xwidget_info); +extern xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t xwidget_info); + + +/* + * TBD: DELETE THIS ENTIRE STRUCTURE! Equivalent is now in + * xtalk_private.h: xwidget_info_s + * This is just here for now because we still have a lot of + * junk referencing it. + * However, since nobody looks inside ... + */ +typedef struct v_widget_s { + unsigned v_widget_s_is_really_empty; +#define v_widget_s_is_really_empty and using this would be a syntax error. +} v_widget_t; +#endif /* _KERNEL */ + +#endif /* _LANGUAGE_C */ + +#endif /* __ASM_SN_XTALK_XWIDGET_H__ */ diff -urN linux-2.4.0-test12/include/asm-ia64/spinlock.h linux-2.4.0-test12-lia/include/asm-ia64/spinlock.h --- linux-2.4.0-test12/include/asm-ia64/spinlock.h Mon Oct 9 17:55:00 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/spinlock.h Wed Dec 6 23:13:06 2000 @@ -18,8 +18,9 @@ #undef NEW_LOCK #ifdef NEW_LOCK + typedef struct { - volatile unsigned char lock; + volatile unsigned int lock; } spinlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } @@ -38,7 +39,7 @@ "mov r30=1\n" \ "mov ar.ccv=r0\n" \ ";;\n" \ - IA64_SEMFIX"cmpxchg1.acq r30=[%0],r30,ar.ccv\n" \ + IA64_SEMFIX"cmpxchg4.acq r30=[%0],r30,ar.ccv\n" \ ";;\n" \ "cmp.ne p15,p0=r30,r0\n" \ "(p15) br.call.spnt.few b7=ia64_spinlock_contention\n" \ @@ -48,18 +49,16 @@ : "ar.ccv", "ar.pfs", "b7", "p15", "r28", "r29", "r30", "memory"); \ } -#define spin_trylock(x) \ -({ \ - register char *addr __asm__ ("r31") = (char *) &(x)->lock; \ - register long result; \ - \ - __asm__ __volatile__ ( \ - "mov r30=1\n" \ - "mov ar.ccv=r0\n" \ - ";;\n" \ - IA64_SEMFIX"cmpxchg1.acq %0=[%1],r30,ar.ccv\n" \ - : "=r"(result) : "r"(addr) : "ar.ccv", "r30", "memory"); \ - (result == 0); \ +#define spin_trylock(x) \ +({ \ + register long result; \ + \ + __asm__ __volatile__ ( \ + "mov ar.ccv=r0\n" \ + ";;\n" \ + IA64_SEMFIX"cmpxchg4.acq %0=[%2],%1,ar.ccv\n" \ + : "=r"(result) : "r"(1), "r"(&(x)->lock) : "ar.ccv", "memory"); \ + (result == 0); \ }) #define spin_is_locked(x) ((x)->lock != 0) diff -urN linux-2.4.0-test12/include/asm-ia64/system.h linux-2.4.0-test12-lia/include/asm-ia64/system.h --- linux-2.4.0-test12/include/asm-ia64/system.h Mon Oct 9 17:55:00 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/system.h Wed Dec 6 23:13:06 2000 @@ -27,7 +27,8 @@ #define GATE_ADDR (0xa000000000000000 + PAGE_SIZE) -#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC) +#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \ + || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC) /* Workaround for Errata 97. */ # define IA64_SEMFIX_INSN mf; # define IA64_SEMFIX "mf;" diff -urN linux-2.4.0-test12/include/asm-ia64/uaccess.h linux-2.4.0-test12-lia/include/asm-ia64/uaccess.h --- linux-2.4.0-test12/include/asm-ia64/uaccess.h Mon Oct 9 17:55:00 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/uaccess.h Wed Dec 6 23:13:11 2000 @@ -125,46 +125,28 @@ struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) -#define __get_user_64(addr) \ +/* We need to declare the __ex_table section before we can use it in .xdata. */ +__asm__ (".section \"__ex_table\", \"a\"\n\t.previous"); + +#define __get_user_64(addr) \ __asm__ ("\n1:\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 (2b-1b)|1\n" \ - "\t.previous" \ - : "=r"(__gu_val), "=r"(__gu_err) \ - : "m"(__m(addr)), "1"(__gu_err)); + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n" \ + : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); -#define __get_user_32(addr) \ +#define __get_user_32(addr) \ __asm__ ("\n1:\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 (2b-1b)|1\n" \ - "\t.previous" \ - : "=r"(__gu_val), "=r"(__gu_err) \ - : "m"(__m(addr)), "1"(__gu_err)); + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n" \ + : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); -#define __get_user_16(addr) \ +#define __get_user_16(addr) \ __asm__ ("\n1:\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 (2b-1b)|1\n" \ - "\t.previous" \ - : "=r"(__gu_val), "=r"(__gu_err) \ - : "m"(__m(addr)), "1"(__gu_err)); + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n" \ + : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); -#define __get_user_8(addr) \ +#define __get_user_8(addr) \ __asm__ ("\n1:\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 (2b-1b)|1\n" \ - "\t.previous" \ - : "=r"(__gu_val), "=r"(__gu_err) \ - : "m"(__m(addr)), "1"(__gu_err)); - + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n" \ + : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); extern void __put_user_unknown (void); @@ -206,46 +188,26 @@ #define __put_user_64(x,addr) \ __asm__ __volatile__ ( \ "\n1:\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 2b-1b\n" \ - "\t.previous" \ - : "=r"(__pu_err) \ - : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n" \ + : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) #define __put_user_32(x,addr) \ __asm__ __volatile__ ( \ "\n1:\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 2b-1b\n" \ - "\t.previous" \ - : "=r"(__pu_err) \ - : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n" \ + : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) #define __put_user_16(x,addr) \ __asm__ __volatile__ ( \ "\n1:\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 2b-1b\n" \ - "\t.previous" \ - : "=r"(__pu_err) \ - : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n" \ + : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) #define __put_user_8(x,addr) \ __asm__ __volatile__ ( \ "\n1:\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "2:\n" \ - "\t.section __ex_table,\"a\"\n" \ - "\t\tdata4 @gprel(1b)\n" \ - "\t\tdata4 2b-1b\n" \ - "\t.previous" \ - : "=r"(__pu_err) \ - : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) + "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n" \ + : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) /* * Complex access routines diff -urN linux-2.4.0-test12/include/asm-ia64/unistd.h linux-2.4.0-test12-lia/include/asm-ia64/unistd.h --- linux-2.4.0-test12/include/asm-ia64/unistd.h Mon Oct 9 17:55:01 2000 +++ linux-2.4.0-test12-lia/include/asm-ia64/unistd.h Wed Dec 6 22:39:55 2000 @@ -160,7 +160,7 @@ #define __NR_nanosleep 1168 #define __NR_nfsservctl 1169 #define __NR_prctl 1170 -#define __NR_getpagesize 1171 +/* 1171 is reserved for backwards compatibility with old __NR_getpagesize */ #define __NR_mmap2 1172 #define __NR_pciconfig_read 1173 #define __NR_pciconfig_write 1174 @@ -196,7 +196,7 @@ #define __NR_getsockopt 1204 #define __NR_sendmsg 1205 #define __NR_recvmsg 1206 -#define __NR_sys_pivot_root 1207 +#define __NR_pivot_root 1207 #define __NR_mincore 1208 #define __NR_madvise 1209 #define __NR_stat 1210 diff -urN linux-2.4.0-test12/include/linux/crc32.h linux-2.4.0-test12-lia/include/linux/crc32.h --- linux-2.4.0-test12/include/linux/crc32.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/include/linux/crc32.h Wed Dec 6 22:40:05 2000 @@ -0,0 +1,17 @@ +/* + * crc32.h + * See linux/lib/crc32.c for license and changes + */ +#ifndef _LINUX_CRC32_H +#define _LINUX_CRC32_H + +#include + +/* + * This computes a 32 bit CRC of the data in the buffer, and returns the CRC. + * The polynomial used is 0xedb88320. + */ + +extern u32 crc32 (const void *buf, unsigned long len, u32 seed); + +#endif /* _LINUX_CRC32_H */ diff -urN linux-2.4.0-test12/include/linux/highmem.h linux-2.4.0-test12-lia/include/linux/highmem.h --- linux-2.4.0-test12/include/linux/highmem.h Wed Dec 13 17:30:34 2000 +++ linux-2.4.0-test12-lia/include/linux/highmem.h Thu Dec 14 14:51:06 2000 @@ -45,7 +45,7 @@ /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ static inline void clear_user_highpage(struct page *page, unsigned long vaddr) { - clear_user_page(kmap(page), vaddr); + clear_user_page(kmap(page), vaddr, page); kunmap(page); } @@ -87,7 +87,7 @@ vfrom = kmap(from); vto = kmap(to); - copy_user_page(vto, vfrom, vaddr); + copy_user_page(vto, vfrom, vaddr, to); kunmap(from); kunmap(to); } diff -urN linux-2.4.0-test12/include/linux/irq.h linux-2.4.0-test12-lia/include/linux/irq.h --- linux-2.4.0-test12/include/linux/irq.h Tue Oct 31 11:18:05 2000 +++ linux-2.4.0-test12-lia/include/linux/irq.h Thu Dec 14 14:51:17 2000 @@ -56,6 +56,8 @@ #include /* the arch dependent stuff */ +extern unsigned int do_IRQ (unsigned long irq, struct pt_regs *regs); +extern void do_IRQ_per_cpu (unsigned long irq, struct pt_regs *regs); extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); extern int setup_irq(unsigned int , struct irqaction * ); diff -urN linux-2.4.0-test12/include/linux/mm.h linux-2.4.0-test12-lia/include/linux/mm.h --- linux-2.4.0-test12/include/linux/mm.h Wed Dec 13 17:30:35 2000 +++ linux-2.4.0-test12-lia/include/linux/mm.h Wed Dec 13 17:32:09 2000 @@ -96,6 +96,8 @@ #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ +#define VM_WRITECOMBINED 0x00100000 /* Write-combined */ +#define VM_NONCACHED 0x00200000 /* Noncached access */ #define VM_STACK_FLAGS 0x00000177 diff -urN linux-2.4.0-test12/init/main.c linux-2.4.0-test12-lia/init/main.c --- linux-2.4.0-test12/init/main.c Wed Dec 13 17:30:37 2000 +++ linux-2.4.0-test12-lia/init/main.c Wed Dec 13 17:32:09 2000 @@ -74,7 +74,6 @@ * with a gcc that is known to be too old from the very beginning. */ #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91) -#error Sorry, your GCC is too old. It builds incorrect kernels. #endif extern char _stext, _etext; @@ -110,6 +109,9 @@ #if defined(CONFIG_QUOTA) extern void dquot_init_hash(void); #endif +#ifdef CONFIG_PERFMON +extern void perfmon_init(void); +#endif /* * Boot command-line arguments @@ -553,6 +555,9 @@ #endif mem_init(); kmem_cache_sizes_init(); +#ifdef CONFIG_PERFMON + perfmon_init(); +#endif #ifdef CONFIG_3215_CONSOLE con3215_activate(); #endif diff -urN linux-2.4.0-test12/kernel/printk.c linux-2.4.0-test12-lia/kernel/printk.c --- linux-2.4.0-test12/kernel/printk.c Mon Oct 16 12:58:51 2000 +++ linux-2.4.0-test12-lia/kernel/printk.c Wed Nov 15 19:49:26 2000 @@ -14,6 +14,8 @@ * manfreds@colorfullife.com */ +#include + #include #include #include @@ -296,6 +298,12 @@ break; } } +#ifdef CONFIG_IA64_EARLY_PRINTK + if (!console_drivers) { + static void early_printk (const char *str); + early_printk(msg); + } else +#endif if (msg_level < console_loglevel && console_drivers) { struct console *c = console_drivers; while(c) { @@ -412,6 +420,10 @@ } if ((console->flags & CON_PRINTBUFFER) == 0) goto done; +#ifdef CONFIG_IA64_EARLY_PRINTK + goto done; +#endif + /* * Print out buffered log messages. */ @@ -495,3 +507,47 @@ tty->driver.write(tty, 0, msg, strlen(msg)); return; } + +#ifdef CONFIG_IA64_EARLY_PRINTK + +#include + +#define VGABASE ((char *)0xc0000000000b8000) + +static int current_ypos = 50, current_xpos = 0; + +void +early_printk (const char *str) +{ + char c; + int i, k, j; + + while ((c = *str++) != '\0') { + if (current_ypos >= 50) { + /* scroll 1 line up */ + for (k = 1, j = 0; k < 50; k++, j++) { + for (i = 0; i < 80; i++) { + writew(readw(VGABASE + 2*(80*k + i)), + VGABASE + 2*(80*j + i)); + } + } + for (i = 0; i < 80; i++) { + writew(0x720, VGABASE + 2*(80*j + i)); + } + current_ypos = 49; + } + if (c == '\n') { + current_xpos = 0; + current_ypos++; + } else if (c != '\r') { + writew(((0x7 << 8) | (unsigned short) c), + VGABASE + 2*(80*current_ypos + current_xpos++)); + if (current_xpos >= 80) { + current_xpos = 0; + current_ypos++; + } + } + } +} + +#endif /* CONFIG_IA64_EARLY_PRINTK */ diff -urN linux-2.4.0-test12/kernel/ptrace.c linux-2.4.0-test12-lia/kernel/ptrace.c --- linux-2.4.0-test12/kernel/ptrace.c Wed Dec 6 18:33:42 2000 +++ linux-2.4.0-test12-lia/kernel/ptrace.c Thu Dec 14 14:52:18 2000 @@ -53,14 +53,14 @@ flush_cache_page(vma, addr); if (write) { - maddr = kmap(page); - memcpy(maddr + (addr & ~PAGE_MASK), buf, len); + maddr = kmap(page) + (addr & ~PAGE_MASK); + memcpy(maddr, buf, len); flush_page_to_ram(page); - flush_icache_page(vma, page); + flush_icache_range((unsigned long) maddr, (unsigned long)maddr + len); kunmap(page); } else { - maddr = kmap(page); - memcpy(buf, maddr + (addr & ~PAGE_MASK), len); + maddr = kmap(page) + (addr & ~PAGE_MASK); + memcpy(buf, maddr, len); flush_page_to_ram(page); kunmap(page); } diff -urN linux-2.4.0-test12/kernel/timer.c linux-2.4.0-test12-lia/kernel/timer.c --- linux-2.4.0-test12/kernel/timer.c Wed Dec 13 17:30:37 2000 +++ linux-2.4.0-test12-lia/kernel/timer.c Wed Dec 13 17:32:12 2000 @@ -673,7 +673,7 @@ void do_timer(struct pt_regs *regs) { - (*(unsigned long *)&jiffies)++; + (*(volatile unsigned long *)&jiffies)++; #ifndef CONFIG_SMP /* SMP process accounting uses the local APIC timer */ diff -urN linux-2.4.0-test12/lib/Makefile linux-2.4.0-test12-lia/lib/Makefile --- linux-2.4.0-test12/lib/Makefile Fri Jul 7 16:41:11 2000 +++ linux-2.4.0-test12-lia/lib/Makefile Wed Dec 6 22:41:02 2000 @@ -7,7 +7,7 @@ # L_TARGET := lib.a -L_OBJS := errno.o ctype.o string.o vsprintf.o brlock.o +L_OBJS := errno.o ctype.o string.o vsprintf.o brlock.o crc32.o LX_OBJS := cmdline.o ifneq ($(CONFIG_HAVE_DEC_LOCK),y) diff -urN linux-2.4.0-test12/lib/crc32.c linux-2.4.0-test12-lia/lib/crc32.c --- linux-2.4.0-test12/lib/crc32.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test12-lia/lib/crc32.c Wed Dec 6 22:41:15 2000 @@ -0,0 +1,125 @@ +/* + * Dec 5, 2000 Matt Domsch + * - Copied crc32.c from the linux/drivers/net/cipe directory. + * - Now pass seed as an arg + * - changed unsigned long to u32, added #include + * - changed len to be an unsigned long + * - changed crc32val to be a register + * - License remains unchanged! It's still GPL-compatable! + */ + + /* ============================================================= */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* Note that we take it "backwards" and put the highest-order term in */ + /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ + /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ + /* the MSB being 1. */ + /* */ + /* Note that the usual hardware shift register implementation, which */ + /* is what we're using (we're merely optimizing it by doing eight-bit */ + /* chunks at a time) shifts bits into the lowest-order term. In our */ + /* implementation, that means shifting towards the right. Why do we */ + /* do it this way? Because the calculated CRC must be transmitted in */ + /* order from highest-order term to lowest-order term. UARTs transmit */ + /* characters in order from LSB to MSB. By storing the CRC this way, */ + /* we hand it to the UART in the order low-byte to high-byte; the UART */ + /* sends each low-bit to hight-bit; and the result is transmission bit */ + /* by bit from highest- to lowest-order term without requiring any bit */ + /* shuffling on our part. Reception works similarly. */ + /* */ + /* The feedback terms table consists of 256, 32-bit entries. Notes: */ + /* */ + /* The table can be generated at runtime if desired; code to do so */ + /* is shown later. It might not be obvious, but the feedback */ + /* terms simply represent the results of eight shift/xor opera- */ + /* tions for all combinations of data and CRC register values. */ + /* */ + /* The values must be right-shifted by eight bits by the "updcrc" */ + /* logic; the shift must be unsigned (bring in zeroes). On some */ + /* hardware you could probably optimize the shift in assembler by */ + /* using byte-swap instructions. */ + /* polynomial $edb88320 */ + /* */ + /* -------------------------------------------------------------------- */ + +#include + +static u32 crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL + }; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +u32 +crc32(const void *buf, unsigned long len, u32 seed) +{ + unsigned long i; + register u32 crc32val; + const unsigned char *s = buf; + + crc32val = seed; + for (i = 0; i < len; i ++) + { + crc32val = + crc32_tab[(crc32val ^ s[i]) & 0xff] ^ + (crc32val >> 8); + } + return crc32val; +} diff -urN linux-2.4.0-test12/mm/memory.c linux-2.4.0-test12-lia/mm/memory.c --- linux-2.4.0-test12/mm/memory.c Wed Dec 13 17:30:38 2000 +++ linux-2.4.0-test12-lia/mm/memory.c Thu Dec 14 14:52:29 2000 @@ -1030,7 +1030,6 @@ return -1; flush_page_to_ram(page); - flush_icache_page(vma, page); } mm->rss++; @@ -1118,7 +1117,6 @@ * handle that later. */ flush_page_to_ram(new_page); - flush_icache_page(vma, new_page); entry = mk_pte(new_page, vma->vm_page_prot); if (write_access) { entry = pte_mkwrite(pte_mkdirty(entry)); diff -urN linux-2.4.0-test12/mm/mmap.c linux-2.4.0-test12-lia/mm/mmap.c --- linux-2.4.0-test12/mm/mmap.c Wed Dec 13 17:30:38 2000 +++ linux-2.4.0-test12-lia/mm/mmap.c Wed Dec 13 17:32:14 2000 @@ -178,6 +178,12 @@ _trans(prot, PROT_WRITE, VM_WRITE) | _trans(prot, PROT_EXEC, VM_EXEC); flag_bits = +#ifdef MAP_WRITECOMBINED + _trans(flags, MAP_WRITECOMBINED, VM_WRITECOMBINED) | +#endif +#ifdef MAP_NONCACHED + _trans(flags, MAP_NONCACHED, VM_NONCACHED) | +#endif _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) | _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) | _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE);