diff -urN linux-2.4.0-test7/Documentation/Configure.help linux-2.4.0-test7-lia/Documentation/Configure.help --- linux-2.4.0-test7/Documentation/Configure.help Thu Aug 24 08:17:28 2000 +++ linux-2.4.0-test7-lia/Documentation/Configure.help Fri Aug 25 00:12:18 2000 @@ -16508,6 +16508,108 @@ another UltraSPARC-IIi-cEngine boardset with a 7-segment display, you should say N to this option. +IA-64 system type +CONFIG_IA64_GENERIC + This selects the system type of your hardware. A "generic" kernel + will run on any supported IA-64 system. However, if you configure + a kernel for your specific system, it will be faster and smaller. + + To find out what type of IA-64 system you have, you may want to + check the IA-64 Linux web site at http://www.linux-ia64.org/. + As of the time of this writing, most hardware is DIG compliant, + so the "DIG-compliant" option is usually the right choice. + + HP-simulator For the HP simulator (http://software.hp.com/ia64linux/). + SN1-simulator For the SGI SN1 simulator. + DIG-compliant For DIG ("Developer's Interface Guide") compliant system. + + If you don't know what to do, choose "generic". + +Kernel page size +CONFIG_IA64_PAGE_SIZE_4KB + + This lets you select the page size of the kernel. For best IA-64 + performance, a page size of 8KB or 16KB is recommended. For best + IA-32 compatibility, a page size of 4KB should be selected (the vast + majority of IA-32 binaries work perfectly fine with a larger page + size). For Itanium systems, do NOT chose a page size larger than + 16KB. + + 4KB For best IA-32 compatibility + 8KB For best IA-64 performance + 16KB For best IA-64 performance + 64KB Not for Itanium. + + If you don't know what to do, choose 8KB. + +Enable Itanium A-step specific code +CONFIG_ITANIUM_ASTEP_SPECIFIC + 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 + Select this option to build a kernel for an Itanium prototype system + with a B-step CPU. You have a B-step CPU if the "revision" field in + /proc/cpuinfo has a value in the range from 1 to 4. + +Enable Itanium B0-step specific code +CONFIG_ITANIUM_B0_SPECIFIC + Select this option to bild a kernel for an Itanium prototype system + with a B0-step CPU. You have a B0-step CPU if the "revision" field in + /proc/cpuinfo is 1. + +Force interrupt redirection +CONFIG_IA64_HAVE_IRQREDIR + Select this option if you know that your system has the ability to + redirect interrupts to different CPUs. Select N here if you're + unsure. + +Enable use of global TLB purge instruction (ptc.g) +CONFIG_ITANIUM_PTCG + Say Y here if you want the kernel to use the IA-64 "ptc.g" + instruction to flush the TLB on all CPUs. Select N here if + you're unsure. + +Enable SoftSDV hacks +CONFIG_IA64_SOFTSDV_HACKS + Say Y here to enable hacks to make the kernel work on the Intel + SoftSDV simulator. Select N here if you're unsure. + +Enable AzusA hacks +CONFIG_IA64_AZUSA_HACKS + Say Y here to enable hacks to make the kernel work on the NEC + AzusA platform. Select N here if you're unsure. + +Enable IA-64 Machine Check Abort +CONFIG_IA64_MCA + Say Y here to enable machine check support for IA-64. If you're + unsure, answer Y. + +Performance monitor support +CONFIG_PERFMON + Selects whether support for the IA-64 performance monitor hardware + is included in the kernel. This makes some kernel data-structures a + little bigger and slows down execution a bit, but it is still + usually a good idea to turn this on. If you're unsure, say N. + +/proc/pal support +CONFIG_IA64_PALINFO + If you say Y here, you are able to get PAL (Processor Abstraction + Layer) information in /proc/pal. This contains useful information + about the processors in your systems, such as cache and TLB sizes + and the PAL firmware version in use. + + To use this option, you have to check that the "/proc file system + support" (CONFIG_PROC_FS) is enabled, too. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff -urN linux-2.4.0-test7/Documentation/ia64/README linux-2.4.0-test7-lia/Documentation/ia64/README --- linux-2.4.0-test7/Documentation/ia64/README Thu Aug 10 19:56:17 2000 +++ linux-2.4.0-test7-lia/Documentation/ia64/README Fri Aug 25 00:14:17 2000 @@ -1,6 +1,6 @@ - Linux kernel release 2.3.xx for the IA-64 Platform + Linux kernel release 2.4.xx for the IA-64 Platform - These are the release notes for Linux version 2.3 for IA-64 + These are the release notes for Linux version 2.4 for IA-64 platform. This document provides information specific to IA-64 ONLY, to get additional information about the Linux kernel also read the original Linux README provided with the kernel. @@ -31,46 +31,13 @@ IA-64 SPECIFICS - - Security related issues: - - o mmap needs to check whether mapping would overlap with the - address-space hole in a region or whether the mapping would be - across regions. In both cases, mmap should fail. - - o ptrace is a huge security hole right now as it does not reject - writing to security sensitive bits (such as the PSR!). - - General issues: - o Kernel modules aren't supported yet. - - o For non-RT signals, siginfo isn't passed through from the kernel - to the point where the signal is actually delivered. Also, we - should make sure the siginfo data is compliant with the UNIX - ABI. - o Hardly any performance tuning has been done. Obvious targets - include the library routines (memcpy, IP checksum, etc.). Less + include the library routines (IP checksum, etc.). Less obvious targets include making sure we don't flush the TLB - needlessly, etc. Also, the TLB handlers should probably try to - do a speculative load from the virtually mapped linear page - table and only if that fails fall back on walking the page table - tree. + needlessly, etc. - o Discontiguous large memory support; memory above 4GB will be - discontiguous since the 4GB-64MB is reserved for firmware and I/O - space. - - o Correct mapping for PAL runtime code; PAL code needs to be - mapped by a TR. - - o Make current IRQ/IOSAPIC handling closer to IA32 such as, - disable/enable interrupts, use of INPROGRESS flag etc. - - o clone system call implementation; needs to setup proper backing - store - o SMP locks cleanup/optimization - o IA32 support. Currently experimental. It mostly works but - there are problems with some dynamically loaded programs. + o IA32 support. Currently experimental. It mostly works. diff -urN linux-2.4.0-test7/Makefile linux-2.4.0-test7-lia/Makefile --- linux-2.4.0-test7/Makefile Thu Aug 24 08:17:29 2000 +++ linux-2.4.0-test7-lia/Makefile Fri Aug 25 01:51:18 2000 @@ -87,7 +87,7 @@ CPPFLAGS := -D__KERNEL__ -I$(HPATH) -CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -g -O2 -fomit-frame-pointer AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) # @@ -184,14 +184,14 @@ # use '-fno-strict-aliasing', but only if the compiler can take it CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi) -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-test7/arch/ia64/Makefile linux-2.4.0-test7-lia/arch/ia64/Makefile --- linux-2.4.0-test7/arch/ia64/Makefile Wed Aug 2 18:54:01 2000 +++ linux-2.4.0-test7-lia/arch/ia64/Makefile Fri Aug 25 01:34:44 2000 @@ -14,12 +14,17 @@ export AWK LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds -AFLAGS += -Wa,-x +AFLAGS += -Wa,-x +AFLAGS_KERNEL := -mconstant-gp EXTRA = CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \ -funwind-tables CFLAGS_KERNEL := -mconstant-gp + +ifeq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y) + CFLAGS += -ma-step +endif ifdef CONFIG_IA64_GENERIC CORE_FILES := arch/$(ARCH)/hp/hp.a \ diff -urN linux-2.4.0-test7/arch/ia64/boot/bootloader.c linux-2.4.0-test7-lia/arch/ia64/boot/bootloader.c --- linux-2.4.0-test7/arch/ia64/boot/bootloader.c Tue Jul 11 19:02:37 2000 +++ linux-2.4.0-test7-lia/arch/ia64/boot/bootloader.c Fri Aug 25 00:19:09 2000 @@ -68,15 +68,16 @@ void enter_virtual_mode (unsigned long new_psr) { + long tmp; + + asm volatile ("movl %0=1f" : "=r"(tmp)); asm volatile ("mov cr.ipsr=%0" :: "r"(new_psr)); - asm volatile ("mov cr.iip=%0" :: "r"(&&target)); + asm volatile ("mov cr.iip=%0" :: "r"(tmp)); asm volatile ("mov cr.ifs=r0"); - asm volatile ("rfi;;"); /* must be last insn in an insn group */ - - target: + asm volatile ("rfi;;"); + asm volatile ("1:"); } - #define MAX_ARGS 32 void @@ -96,7 +97,7 @@ char *kpath, *args; long arglen = 0; - asm volatile ("movl gp=__gp" ::: "memory"); + asm volatile ("movl gp=__gp;;" ::: "memory"); asm volatile ("mov sp=%0" :: "r"(stack) : "memory"); asm volatile ("bsw.1;;"); #ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC diff -urN linux-2.4.0-test7/arch/ia64/config.in linux-2.4.0-test7-lia/arch/ia64/config.in --- linux-2.4.0-test7/arch/ia64/config.in Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/config.in Fri Aug 25 00:19:46 2000 @@ -51,6 +51,13 @@ 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 ' ACPI kernel configuration manager (EXPERIMENTAL)' CONFIG_ACPI_KERNEL_CONFIG + if [ "$CONFIG_ACPI_KERNEL_CONFIG" = "y" ]; then + define_bool CONFIG_PM y + define_bool CONFIG_ACPI y + define_bool CONFIG_ACPI_INTERPRETER y + fi fi if [ "$CONFIG_IA64_SGI_SN1_SIM" = "y" ]; then @@ -160,6 +167,10 @@ fi # !HP_SIM +# +# input before char - char/joystick depends on it. As does USB. +# +source drivers/input/Config.in source drivers/char/Config.in #source drivers/misc/Config.in @@ -191,7 +202,6 @@ endmenu source drivers/usb/Config.in -source drivers/input/Config.in fi # !HP_SIM diff -urN linux-2.4.0-test7/arch/ia64/dig/iosapic.c linux-2.4.0-test7-lia/arch/ia64/dig/iosapic.c --- linux-2.4.0-test7/arch/ia64/dig/iosapic.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/dig/iosapic.c Fri Aug 25 01:35:18 2000 @@ -31,6 +31,10 @@ #include #include +#ifdef CONFIG_ACPI_KERNEL_CONFIG +# include +#endif + #undef DEBUG_IRQ_ROUTING static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; @@ -228,7 +232,7 @@ { struct hw_interrupt_type *irq_type; struct pci_vector_struct *vectors; - int i, irq; + int i, irq, num_pci_vectors; if (irqbase == 0) /* @@ -255,9 +259,14 @@ * 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; - for (i = 0; i < ia64_boot_param.num_pci_vectors; i++) { + 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); @@ -277,11 +286,11 @@ iosapic_trigger(irq) = IO_SAPIC_LEVEL; iosapic_polarity(irq) = IO_SAPIC_POL_LOW; -#ifdef DEBUG_IRQ_ROUTING +# 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 } #endif /* CONFIG_IA64_SOFTSDV_HACKS */ diff -urN linux-2.4.0-test7/arch/ia64/ia32/Makefile linux-2.4.0-test7-lia/arch/ia64/ia32/Makefile --- linux-2.4.0-test7/arch/ia64/ia32/Makefile Wed Aug 2 18:54:01 2000 +++ linux-2.4.0-test7-lia/arch/ia64/ia32/Makefile Fri Aug 25 00:22:12 2000 @@ -3,9 +3,9 @@ # .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: ia32.o diff -urN linux-2.4.0-test7/arch/ia64/ia32/sys_ia32.c linux-2.4.0-test7-lia/arch/ia64/ia32/sys_ia32.c --- linux-2.4.0-test7/arch/ia64/ia32/sys_ia32.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/ia32/sys_ia32.c Fri Aug 25 00:22:45 2000 @@ -788,7 +788,8 @@ } static int -fillonedir32 (void * __buf, const char * name, int namlen, off_t offset, ino_t ino) +fillonedir32 (void * __buf, const char * name, int namlen, off_t offset, ino_t ino, + unsigned int d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct old_linux32_dirent * dirent; diff -urN linux-2.4.0-test7/arch/ia64/kernel/Makefile linux-2.4.0-test7-lia/arch/ia64/kernel/Makefile --- linux-2.4.0-test7/arch/ia64/kernel/Makefile Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/Makefile Fri Aug 25 00:23:23 2000 @@ -3,9 +3,9 @@ # .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: kernel.o head.o init_task.o diff -urN linux-2.4.0-test7/arch/ia64/kernel/acpi.c linux-2.4.0-test7-lia/arch/ia64/kernel/acpi.c --- linux-2.4.0-test7/arch/ia64/kernel/acpi.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/acpi.c Fri Aug 25 01:36:37 2000 @@ -24,18 +24,17 @@ #include #include #include +#ifdef CONFIG_ACPI_KERNEL_CONFIG +# include +#endif #undef ACPI_DEBUG /* Guess what this does? */ -#ifdef CONFIG_SMP -extern struct smp_boot_data smp; -#endif - /* These are ugly but will be reclaimed by the kernel */ -int __initdata available_cpus = 0; -int __initdata total_cpus = 0; +int __initdata available_cpus; +int __initdata total_cpus; -void (*pm_idle) (void); +void (*pm_idle)(void); /* * Identify usable CPU's and remember them for SMP bringup later. @@ -60,18 +59,16 @@ 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 -# if LARGE_CPU_ID_OK - smp.cpu_map[total_cpus] = (lsapic->id << 8) | lsapic->eid; -# else - smp.cpu_map[total_cpus] = lsapic->id; -# endif -#endif + smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid; +#endif /* CONFIG_SMP */ } - total_cpus++; } @@ -172,10 +169,6 @@ /* Base address of IPI Message Block */ ipi_base_addr = (unsigned long) ioremap(msapic->interrupt_block, 0); -#ifdef CONFIG_SMP - memset(&smp, -1, sizeof(smp)); -#endif - p = (char *) (msapic + 1); end = p + (msapic->header.length - sizeof(acpi_sapic_t)); @@ -248,6 +241,10 @@ printk("ACPI: %.6s %.8s %d.%d\n", rsdt->header.oem_id, rsdt->header.oem_table_id, rsdt->header.oem_revision >> 16, rsdt->header.oem_revision & 0xffff); +#ifdef CONFIG_ACPI_KERNEL_CONFIG + acpi_cf_init(rsdp); +#endif + tables = (rsdt->header.length - sizeof(acpi_desc_table_hdr_t)) / 8; for (i = 0; i < tables; i++) { hdrp = (acpi_desc_table_hdr_t *) __va(rsdt->entry_ptrs[i]); @@ -259,12 +256,16 @@ acpi_parse_msapic((acpi_sapic_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.cpu_count = available_cpus; + smp_boot_data.cpu_count = available_cpus; #endif return 1; } @@ -286,4 +287,4 @@ # error Unknown platform. Fix acpi.c. # endif #endif -} +} diff -urN linux-2.4.0-test7/arch/ia64/kernel/fw-emu.c linux-2.4.0-test7-lia/arch/ia64/kernel/fw-emu.c --- linux-2.4.0-test7/arch/ia64/kernel/fw-emu.c Wed Aug 2 18:54:01 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/fw-emu.c Fri Aug 25 00:30:24 2000 @@ -20,7 +20,7 @@ #define MB (1024*1024UL) -#define NUM_MEM_DESCS 3 +#define NUM_MEM_DESCS 2 static char fw_mem[( sizeof(efi_system_table_t) + sizeof(efi_runtime_services_t) @@ -453,6 +453,12 @@ md->num_pages = (1*MB) >> 12; /* 1MB (in 4KB pages) */ md->attribute = EFI_MEMORY_WB; +#if 0 + /* + * XXX bootmem is broken for now... (remember to NUM_MEM_DESCS + * if you re-enable this!) + */ + /* descriptor for high memory (>4GB): */ md = &efi_memmap[2]; md->type = EFI_CONVENTIONAL_MEMORY; @@ -461,6 +467,7 @@ md->virt_addr = 0; md->num_pages = (32*MB) >> 12; /* 32MB (in 4KB pages) */ md->attribute = EFI_MEMORY_WB; +#endif bp = id(ZERO_PAGE_ADDR); bp->efi_systab = __pa(&fw_mem); diff -urN linux-2.4.0-test7/arch/ia64/kernel/head.S linux-2.4.0-test7-lia/arch/ia64/kernel/head.S --- linux-2.4.0-test7/arch/ia64/kernel/head.S Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/head.S Fri Aug 25 00:31:03 2000 @@ -111,7 +111,7 @@ * be implemented more efficiently (for example, __switch_to() * always sets the psr.dfh bit of the task it is switching to). */ - addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 + addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2 addl r2=IA64_RBS_OFFSET,r2 // initialize the RSE mov ar.rsc=r0 // place RSE in enforced lazy mode ;; diff -urN linux-2.4.0-test7/arch/ia64/kernel/irq_ia64.c linux-2.4.0-test7-lia/arch/ia64/kernel/irq_ia64.c --- linux-2.4.0-test7/arch/ia64/kernel/irq_ia64.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/irq_ia64.c Fri Aug 25 00:32:15 2000 @@ -220,13 +220,23 @@ { unsigned long ipi_addr; unsigned long ipi_data; + unsigned long phys_cpu_id; #ifdef CONFIG_ITANIUM_A1_SPECIFIC unsigned long flags; #endif -# define EID 0 + +#ifdef CONFIG_SMP + phys_cpu_id = cpu_physical_id(cpu); +#else + phys_cpu_id = (ia64_get_lid() >> 16) & 0xffff; +#endif + + /* + * cpu number is in 8bit ID and 8bit EID + */ ipi_data = (delivery_mode << 8) | (vector & 0xff); - ipi_addr = ipi_base_addr | ((cpu << 8 | EID) << 4) | ((redirect & 1) << 3); + ipi_addr = ipi_base_addr | (phys_cpu_id << 4) | ((redirect & 1) << 3); #ifdef CONFIG_ITANIUM_A1_SPECIFIC spin_lock_irqsave(&ivr_read_lock, flags); diff -urN linux-2.4.0-test7/arch/ia64/kernel/ivt.S linux-2.4.0-test7-lia/arch/ia64/kernel/ivt.S --- linux-2.4.0-test7/arch/ia64/kernel/ivt.S Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/ivt.S Fri Aug 25 00:32:49 2000 @@ -4,6 +4,8 @@ * Copyright (C) 1998-2000 Hewlett-Packard Co * Copyright (C) 1998, 1999 Stephane Eranian * Copyright (C) 1998-2000 David Mosberger + * + * 00/08/23 Asit Mallick TLB handling for SMP */ /* * This file defines the interrupt vector table used by the CPU. @@ -134,32 +136,51 @@ (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry ;; -(p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) +(p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) shr.u r19=r16,PAGE_SHIFT // shift L3 index into position ;; -(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? - dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry +(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L2 entry NULL? + dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L3 page table entry ;; -(p7) ld8 r18=[r17] // read the L3 PTE +(p7) ld8 r18=[r21] // read the L3 PTE mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss ;; (p7) tbit.z p6,p7=r18,0 // page present bit cleared? - mov r21=cr.iha // get the VHPT address that caused the TLB miss + mov r22=cr.iha // get the VHPT address that caused the TLB miss ;; // avoid RAW on p7 (p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss? - dep r17=0,r17,0,PAGE_SHIFT // clear low bits to get page address + dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address ;; (p10) itc.i r18 // insert the instruction TLB entry (p11) itc.d r18 // insert the data TLB entry (p6) br.spnt.few page_fault // handle bad address/page not present (page fault) - mov cr.ifa=r21 + mov cr.ifa=r22 // Now compute and insert the TLB entry for the virtual page table. // We never execute in a page table page so there is no need to set // the exception deferral bit. - adds r16=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r17 + adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23 + ;; +(p7) itc.d r24 ;; -(p7) itc.d r16 +#ifdef CONFIG_SMP + // + // Re-check L2 and L3 pagetable. If they changed, we may have received + // a ptc.g between reading the pagetable and the "itc". If so, + // flush the entry we inserted and retry. + // + ld8 r25=[r21] // read L3 PTE again + ld8 r26=[r17] // read L2 entry again + ;; + cmp.ne p6,p7=r26,r20 // did L2 entry change + mov r27=PAGE_SHIFT<<2 + ;; +(p6) ptc.l r22,r27 // purge PTE page translation +(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L3 PTE change + ;; +(p6) ptc.l r16,r27 // purge translation +#endif + mov pr=r31,-1 // restore predicate registers rfi @@ -176,15 +197,25 @@ * for the L3 page table page we're trying to access. */ mov r16=cr.iha // get virtual address of L3 PTE + mov r19=cr.ifa // get virtual address ;; - ld8.s r16=[r16] // try to read L3 PTE + ld8.s r17=[r16] // try to read L3 PTE mov r31=pr // save predicates ;; tnat.nz p6,p0=r16 // did read succeed? (p6) br.cond.spnt.many 1f ;; - itc.i r16 + itc.i r17 + ;; +#ifdef CONFIG_SMP + ld8.s r18=[r16] // try to read L3 PTE again and see if same + mov r20=PAGE_SHIFT<<2 // setup page size for purge + ;; + cmp.eq p6,p7=r17,r18 ;; +(p7) ptc.l r19,r20 +#endif + mov pr=r31,-1 rfi @@ -228,6 +259,15 @@ (p7) itc.i r18 // insert the instruction TLB entry (p6) br.spnt.few page_fault // handle bad address/page not present (page fault) ;; +#ifdef CONFIG_SMP + ld8 r19=[r17] // re-read the PTE and check if same + ;; + cmp.eq p6,p7=r18,r19 + mov r20=PAGE_SHIFT<<2 + ;; +(p7) ptc.l r16,r20 // PTE changed purge translation +#endif + mov pr=r31,-1 // restore predicate registers rfi @@ -244,15 +284,24 @@ * for the L3 page table page we're trying to access. */ mov r16=cr.iha // get virtual address of L3 PTE + mov r19=cr.ifa // get virtual address ;; - ld8.s r16=[r16] // try to read L3 PTE + ld8.s r17=[r16] // try to read L3 PTE mov r31=pr // save predicates ;; tnat.nz p6,p0=r16 // did read succeed? (p6) br.cond.spnt.many 1f ;; - itc.d r16 + itc.d r17 + ;; +#ifdef CONFIG_SMP + ld8.s r18=[r16] // try to read L3 PTE again and see if same + mov r20=PAGE_SHIFT<<2 // setup page size for purge + ;; + cmp.eq p6,p7=r17,r18 ;; +(p7) ptc.l r19,r20 +#endif mov pr=r31,-1 rfi @@ -296,6 +345,14 @@ (p7) itc.d r18 // insert the instruction TLB entry (p6) br.spnt.few page_fault // handle bad address/page not present (page fault) ;; +#ifdef CONFIG_SMP + ld8 r19=[r17] // re-read the PTE and check if same + ;; + cmp.eq p6,p7=r18,r19 + mov r20=PAGE_SHIFT<<2 + ;; +(p7) ptc.l r16,r20 // PTE changed purge translation +#endif mov pr=r31,-1 // restore predicate registers rfi @@ -452,6 +509,7 @@ // a nested TLB miss hit where we look up the physical address of the L3 PTE // and then continue at label 1 below. // +#ifndef CONFIG_SMP mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault ;; @@ -465,6 +523,36 @@ ;; st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE +#else + mov r16=cr.ifa // get the address that caused the fault + movl r30=1f // load continuation point in case of nested fault + ;; + thash r17=r16 // compute virtual address of L3 PTE + mov r28=ar.ccv // save ar.ccv + mov r29=b0 // save b0 in case of nested fault + mov r27=pr + ;; +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 + ;; + cmpxchg8.acq r26=[r17],r25,ar.ccv + mov r24=PAGE_SHIFT<<2 + ;; + cmp.eq p6,p7=r26,r18 + ;; +(p6) itc.d r25 // install updated PTE + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 + mov pr=r27,-1 +#endif rfi .align 1024 @@ -486,6 +574,8 @@ (p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa mov pr=r31,-1 #endif /* CONFIG_ITANIUM */ + +#ifndef CONFIG_SMP movl r30=1f // load continuation point in case of nested fault ;; thash r17=r16 // compute virtual address of L3 PTE @@ -515,12 +605,58 @@ ;; st8 [r17]=r18 // store back updated PTE itc.i r18 // install updated PTE +#else + movl r30=1f // load continuation point in case of nested fault + ;; + thash r17=r16 // compute virtual address of L3 PTE + mov r28=ar.ccv // save ar.ccv + mov r29=b0 // save b0 in case of nested fault) + mov r27=pr + ;; +1: ld8 r18=[r17] +#if defined(CONFIG_IA32_SUPPORT) && \ + (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_B0_SPECIFIC)) + // + // Erratum 85 (Access bit fault could be reported before page not present fault) + // If the PTE is indicates the page is not present, then just turn this into a + // page fault. + // + ;; + tbit.nz p6,p0=r18,0 // page present bit set? +(p6) br.cond.sptk 1f + ;; // avoid WAW on p6 + mov pr=r27,-1 + br.cond.sptk page_fault // page wasn't present +1: +#else + ;; // avoid RAW on r18 +#endif + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_A,r18 // set the accessed bit + ;; + cmpxchg8.acq r26=[r17],r25,ar.ccv + mov r24=PAGE_SHIFT<<2 + ;; + cmp.eq p6,p7=r26,r18 + ;; +(p6) itc.i r25 // install updated PTE + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 + mov pr=r27,-1 +#endif rfi .align 1024 ///////////////////////////////////////////////////////////////////////////////////////// // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) // Like Entry 8, except for data access +#ifndef CONFIG_SMP mov r16=cr.ifa // get the address that caused the fault movl r30=1f // load continuation point in case of nested fault ;; @@ -534,6 +670,36 @@ ;; st8 [r17]=r18 // store back updated PTE itc.d r18 // install updated PTE +#else + mov r16=cr.ifa // get the address that caused the fault + movl r30=1f // load continuation point in case of nested fault + ;; + thash r17=r16 // compute virtual address of L3 PTE + mov r28=ar.ccv // save ar.ccv + mov r29=b0 // save b0 in case of nested fault + mov r27=pr + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_A,r18 // set the dirty bit + ;; + cmpxchg8.acq r26=[r17],r25,ar.ccv + mov r24=PAGE_SHIFT<<2 + ;; + cmp.eq p6,p7=r26,r18 + ;; +(p6) itc.d r25 // install updated PTE + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 + mov pr=r27,-1 +#endif rfi .align 1024 diff -urN linux-2.4.0-test7/arch/ia64/kernel/mca.c linux-2.4.0-test7-lia/arch/ia64/kernel/mca.c --- linux-2.4.0-test7/arch/ia64/kernel/mca.c Wed Aug 2 18:54:02 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/mca.c Fri Aug 25 01:37:00 2000 @@ -43,10 +43,6 @@ u64 ia64_mca_bspstore[1024]; u64 ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16))); -#if defined(SAL_MPINIT_WORKAROUND) && !defined(CONFIG_SMP) -int bootstrap_processor = -1; -#endif - static void ia64_mca_cmc_vector_setup(int enable, int_vector_t cmc_vector); static void ia64_mca_wakeup_ipi_wait(void); @@ -223,12 +219,6 @@ IA64_MCA_DEBUG("ia64_mca_init : begin\n"); -#if defined(SAL_MPINIT_WORKAROUND) && !defined(CONFIG_SMP) - /* XXX -- workaround for SAL bug for running on MP system, but UP kernel */ - - bootstrap_processor = hard_smp_processor_id(); -#endif - /* Clear the Rendez checkin flag for all cpus */ for(i = 0 ; i < IA64_MAXCPUS; i++) ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; @@ -386,7 +376,7 @@ int cpu; /* Clear the Rendez checkin flag for all cpus */ - for(cpu = 0 ; cpu < IA64_MAXCPUS; cpu++) + for(cpu = 0 ; cpu < smp_num_cpus; cpu++) if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE) ia64_mca_wakeup(cpu); @@ -404,11 +394,14 @@ void ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) { - int flags; + int flags, cpu = 0; /* Mask all interrupts */ save_and_cli(flags); - ia64_mc_info.imi_rendez_checkin[ia64_get_cpuid(0)] = IA64_MCA_RENDEZ_CHECKIN_DONE; +#ifdef CONFIG_SMP + cpu = cpu_logical_id(hard_smp_processor_id()); +#endif + ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; /* Register with the SAL monarch that the slave has * reached SAL */ diff -urN linux-2.4.0-test7/arch/ia64/kernel/mca_asm.S linux-2.4.0-test7-lia/arch/ia64/kernel/mca_asm.S --- linux-2.4.0-test7/arch/ia64/kernel/mca_asm.S Wed Aug 2 18:54:02 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/mca_asm.S Fri Aug 25 00:51:43 2000 @@ -680,32 +680,22 @@ .proc ia64_monarch_init_handler ia64_monarch_init_handler: -#if defined(SAL_MPINIT_WORKAROUND) +#if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND) // // work around SAL bug that sends all processors to monarch entry // - .global bootstrap_processor - - movl r21=24 - movl r20=16 mov r17=cr.lid - movl r18=bootstrap_processor + movl r18=__cpu_physical_id ;; - dep r18=0,r18,61,3 // convert bsp to physical address + dep r18=0,r18,61,3 // convert to physical address ;; - shr r19=r17,r20 - shr r22=r17,r21 + shr.u r17=r17,16 ld4 r18=[r18] // get the BSP ID ;; - and r19=0xf, r19 - and r22=0xf, r22 + dep r17=0,r17,16,48 ;; - shl r19=r19,8 // get them in the right order - ;; - or r22=r22,r19 // combine EID and LID - ;; - cmp.eq p6,p7=r22,r18 // Am I the BSP ? -(p7) br.cond.spnt slave_init_spin_me + cmp4.ne p6,p0=r17,r18 // Am I the BSP ? +(p6) br.cond.spnt slave_init_spin_me ;; #endif diff -urN linux-2.4.0-test7/arch/ia64/kernel/palinfo.c linux-2.4.0-test7-lia/arch/ia64/kernel/palinfo.c --- linux-2.4.0-test7/arch/ia64/kernel/palinfo.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/palinfo.c Fri Aug 25 01:37:21 2000 @@ -10,13 +10,12 @@ * Copyright (C) 2000 Stephane Eranian * * 05/26/2000 S.Eranian initial release + * 08/21/2000 S.Eranian updated to July 2000 PAL specs * * ISSUES: - * - because of some PAL bugs, some calls return invalid results or - * are empty for now. - * - remove hack to avoid problem with <= 256M RAM for itr. + * - as of 2.2.9/2.2.12, the following values are still wrong + * PAL_VM_SUMMARY: key & rid sizes */ -#include #include #include #include @@ -111,7 +110,7 @@ #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *)) /* - * The current revision of the Volume 2 of + * The current revision of the Volume 2 (July 2000) of * IA-64 Architecture Software Developer's Manual is wrong. * Table 4-10 has invalid information concerning the ma field: * Correct table is: @@ -502,7 +501,7 @@ "RSE load/store hints : %ld (%s)\n", phys_stacked, hints.ph_data, - hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(??)"); + hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(\?\?)"); if (ia64_pal_debug_info(&iregs, &dregs)) return 0; @@ -569,7 +568,9 @@ "Enable Half Transfer", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + "Enable Cache Line Repl. Exclusive", + "Enable Cache Line Repl. Shared", "Disable Transaction Queuing", "Disable Reponse Error Checking", "Disable Bus Error Checking", diff -urN linux-2.4.0-test7/arch/ia64/kernel/pci-dma.c linux-2.4.0-test7-lia/arch/ia64/kernel/pci-dma.c --- linux-2.4.0-test7/arch/ia64/kernel/pci-dma.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/pci-dma.c Fri Aug 25 00:52:00 2000 @@ -394,7 +394,7 @@ * 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 inline dma_addr_t +dma_addr_t pci_map_single (struct pci_dev *hwdev, void *ptr, size_t size, int direction) { if (direction == PCI_DMA_NONE) @@ -410,7 +410,7 @@ * After this call, reads by the cpu to the buffer are guarenteed to see * whatever the device wrote there. */ -extern inline void +void pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) { if (direction == PCI_DMA_NONE) @@ -433,7 +433,7 @@ * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -extern inline int +int pci_map_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { if (direction == PCI_DMA_NONE) @@ -446,7 +446,7 @@ * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern inline void +void pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { if (direction == PCI_DMA_NONE) @@ -463,7 +463,7 @@ * next point you give the PCI dma address back to the card, the * device again owns the buffer. */ -extern inline void +void pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) { if (direction == PCI_DMA_NONE) @@ -478,7 +478,7 @@ * The same as pci_dma_sync_single but for a scatter-gather list, * same rules and usage. */ -extern inline void +void pci_dma_sync_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) { if (direction == PCI_DMA_NONE) diff -urN linux-2.4.0-test7/arch/ia64/kernel/setup.c linux-2.4.0-test7-lia/arch/ia64/kernel/setup.c --- linux-2.4.0-test7/arch/ia64/kernel/setup.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/setup.c Fri Aug 25 00:56:06 2000 @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM # include @@ -43,7 +44,7 @@ extern char _end; -/* cpu_data[bootstrap_processor] is data for the bootstrap processor: */ +/* cpu_data[0] is data for the bootstrap processor: */ struct cpuinfo_ia64 cpu_data[NR_CPUS]; unsigned long ia64_cycles_per_usec; @@ -157,7 +158,7 @@ if (initrd_start >= PAGE_OFFSET) printk("Warning: boot loader passed virtual address " "for initrd, please upgrade the loader\n"); - } else + else #endif /* * The loader ONLY passes physical addresses @@ -215,8 +216,8 @@ ia64_sal_init(efi.sal_systab); #ifdef CONFIG_SMP - bootstrap_processor = hard_smp_processor_id(); - current->processor = bootstrap_processor; + current->processor = 0; + cpu_physical_id(0) = hard_smp_processor_id(); #endif cpu_init(); /* initialize the bootstrap CPU */ diff -urN linux-2.4.0-test7/arch/ia64/kernel/smp.c linux-2.4.0-test7-lia/arch/ia64/kernel/smp.c --- linux-2.4.0-test7/arch/ia64/kernel/smp.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/smp.c Fri Aug 25 01:00:23 2000 @@ -6,6 +6,7 @@ * * Lots of stuff stolen from arch/alpha/kernel/smp.c * + * 00/08/23 Asit Mallick fixed logical processor id * 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. @@ -27,6 +28,7 @@ #include #include #include +#include #include #include @@ -47,16 +49,15 @@ extern volatile unsigned long cpu_online_map; /* Bitmap of available cpu's */ extern struct cpuinfo_ia64 cpu_data[NR_CPUS]; /* Duh... */ +struct smp_boot_data smp_boot_data __initdata; + spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; -struct smp_boot_data __initdata smp; -char __initdata no_int_routing = 0; +char __initdata no_int_routing; unsigned char smp_int_redirect; /* are INT and IPI redirectable by the chipset? */ -volatile int __cpu_number_map[NR_CPUS] = { -1, }; /* SAPIC ID -> Logical ID */ -volatile int __cpu_logical_map[NR_CPUS] = { -1, }; /* logical ID -> SAPIC ID */ +volatile int __cpu_physical_id[NR_CPUS] = { -1, }; /* Logical ID -> SAPIC ID */ int smp_num_cpus = 1; -int bootstrap_processor = -1; /* SAPIC ID of BSP */ int smp_threads_ready = 0; /* Set when the idlers are all forked */ cycles_t cacheflush_time = 0; unsigned long ap_wakeup_vector = -1; /* External Int to use to wakeup AP's */ @@ -135,6 +136,7 @@ static inline int pointer_lock(void *lock, void *data, int retry) { + volatile long *ptr = lock; again: if (cmpxchg_acq((void **) lock, 0, data) == 0) return 0; @@ -142,7 +144,7 @@ if (!retry) return -EBUSY; - while (*(void **) lock) + while (*ptr) ; goto again; @@ -275,12 +277,10 @@ send_IPI_allbutself(int op) { int i; - int cpu_id = 0; for (i = 0; i < smp_num_cpus; i++) { - cpu_id = __cpu_logical_map[i]; - if (cpu_id != smp_processor_id()) - send_IPI_single(cpu_id, op); + if (i != smp_processor_id()) + send_IPI_single(i, op); } } @@ -290,7 +290,7 @@ int i; for (i = 0; i < smp_num_cpus; i++) - send_IPI_single(__cpu_logical_map[i], op); + send_IPI_single(i, op); } static inline void @@ -534,12 +534,11 @@ #ifdef CONFIG_PERFMON extern void perfmon_init_percpu(void); #endif + int cpu = smp_processor_id(); efi_map_pal_code(); - cpu_init(); - - smp_setup_percpu_timer(smp_processor_id()); + smp_setup_percpu_timer(cpu); /* setup the CPU local timer tick */ ia64_init_itm(); @@ -552,16 +551,16 @@ ia64_set_lrr0(0, 1); ia64_set_lrr1(0, 1); - if (test_and_set_bit(smp_processor_id(), &cpu_online_map)) { - printk("CPU#%d already initialized!\n", smp_processor_id()); + if (test_and_set_bit(cpu, &cpu_online_map)) { + printk("CPU#%d already initialized!\n", cpu); machine_halt(); } while (!smp_threads_ready) mb(); local_irq_enable(); /* Interrupts have been off until now */ - smp_calibrate_delay(smp_processor_id()); - printk("SMP: CPU %d starting idle loop\n", smp_processor_id()); + smp_calibrate_delay(cpu); + printk("SMP: CPU %d starting idle loop\n", cpu); cpu_idle(NULL); } @@ -583,14 +582,13 @@ } /* - * Bring one cpu online. - * - * NB: cpuid is the CPU BUS-LOCAL ID, not the entire SAPIC ID. See asm/smp.h. + * Bring one cpu online. Return 0 if this fails for any reason. */ static int __init -smp_boot_one_cpu(int cpuid, int cpunum) +smp_boot_one_cpu(int cpu) { struct task_struct *idle; + int cpu_phys_id = cpu_physical_id(cpu); long timeout; /* @@ -603,29 +601,27 @@ * Sheesh . . . */ if (fork_by_hand() < 0) - panic("failed fork for CPU %d", cpuid); + panic("failed fork for CPU 0x%x", cpu_phys_id); /* * We remove it from the pidhash and the runqueue * once we got the process: */ idle = init_task.prev_task; if (!idle) - panic("No idle process for CPU %d", cpuid); - init_tasks[cpunum] = idle; + panic("No idle process for CPU 0x%x", cpu_phys_id); + init_tasks[cpu] = idle; del_from_runqueue(idle); unhash_process(idle); /* Schedule the first task manually. */ - idle->processor = cpuid; + idle->processor = cpu; idle->has_cpu = 1; /* Let _start know what logical CPU we're booting (offset into init_tasks[] */ - cpu_now_booting = cpunum; - + cpu_now_booting = cpu; + /* Kick the AP in the butt */ - ipi_send(cpuid, ap_wakeup_vector, IA64_IPI_DM_INT, 0); - ia64_srlz_i(); - mb(); + ipi_send(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0); /* * OK, wait a bit for that CPU to finish staggering about. smp_callin() will @@ -633,19 +629,16 @@ * is waiting for smp_threads_ready to be 1 and we can move on. */ for (timeout = 0; timeout < 100000; timeout++) { - if (test_bit(cpuid, &cpu_online_map)) + if (test_bit(cpu, &cpu_online_map)) goto alive; udelay(100); barrier(); } - printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid); + printk(KERN_ERR "SMP: Processor 0x%x is stuck.\n", cpu_phys_id); return 0; alive: - /* Remember the AP data */ - __cpu_number_map[cpuid] = cpunum; - __cpu_logical_map[cpunum] = cpuid; return 1; } @@ -663,21 +656,19 @@ unsigned long bogosum; /* Take care of some initial bookkeeping. */ - memset(&__cpu_number_map, -1, sizeof(__cpu_number_map)); - memset(&__cpu_logical_map, -1, sizeof(__cpu_logical_map)); + memset(&__cpu_physical_id, -1, sizeof(__cpu_physical_id)); memset(&ipi_op, 0, sizeof(ipi_op)); /* Setup BSP mappings */ - __cpu_number_map[bootstrap_processor] = 0; - __cpu_logical_map[0] = bootstrap_processor; + __cpu_physical_id[0] = hard_smp_processor_id(); smp_calibrate_delay(smp_processor_id()); #if 0 smp_tune_scheduling(); #endif - smp_setup_percpu_timer(bootstrap_processor); + smp_setup_percpu_timer(0); - if (test_and_set_bit(bootstrap_processor, &cpu_online_map)) { + if (test_and_set_bit(0, &cpu_online_map)) { printk("CPU#%d already initialized!\n", smp_processor_id()); machine_halt(); } @@ -692,16 +683,18 @@ if (max_cpus != -1) printk("Limiting CPUs to %d\n", max_cpus); - if (smp.cpu_count > 1) { + if (smp_boot_data.cpu_count > 1) { printk(KERN_INFO "SMP: starting up secondaries.\n"); - for (i = 0; i < NR_CPUS; i++) { - if (smp.cpu_map[i] == -1 || - smp.cpu_map[i] == bootstrap_processor) + for (i = 0; i < smp_boot_data.cpu_count; i++) { + /* skip performance restricted and bootstrap cpu: */ + if (smp_boot_data.cpu_phys_id[i] == -1 + || smp_boot_data.cpu_phys_id[i] == hard_smp_processor_id()) continue; - if (smp_boot_one_cpu(smp.cpu_map[i], cpu_count) == 0) - continue; + cpu_physical_id(cpu_count) = smp_boot_data.cpu_phys_id[i]; + if (!smp_boot_one_cpu(cpu_count)) + continue; /* failed */ cpu_count++; /* Count good CPUs only... */ /* @@ -759,9 +752,7 @@ * * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP(). * - * So this just gets the BSP SAPIC ID and print's it out. Dull, huh? - * - * Not anymore. This also registers the AP OS_MC_REDVEZ address with SAL. + * This also registers the AP OS_MC_REDVEZ address with SAL. */ void __init init_smp_config(void) @@ -771,9 +762,6 @@ unsigned long gp; } *ap_startup; long sal_ret; - - /* Grab the BSP ID */ - bootstrap_processor = hard_smp_processor_id(); /* Tell SAL where to drop the AP's. */ ap_startup = (struct fptr *) start_ap; diff -urN linux-2.4.0-test7/arch/ia64/kernel/time.c linux-2.4.0-test7-lia/arch/ia64/kernel/time.c --- linux-2.4.0-test7/arch/ia64/kernel/time.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/time.c Fri Aug 25 01:00:41 2000 @@ -183,7 +183,7 @@ #ifdef CONFIG_SMP smp_do_timer(regs); - if (smp_processor_id() == bootstrap_processor) + if (smp_processor_id() == 0) do_timer(regs); #else do_timer(regs); diff -urN linux-2.4.0-test7/arch/ia64/kernel/traps.c linux-2.4.0-test7-lia/arch/ia64/kernel/traps.c --- linux-2.4.0-test7/arch/ia64/kernel/traps.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/traps.c Fri Aug 25 01:01:14 2000 @@ -255,12 +255,12 @@ f6_15[1] = regs->f7; f6_15[2] = regs->f8; f6_15[3] = regs->f9; - __asm__ ("stf.spill %0=f10" : "=m"(f6_15[4])); - __asm__ ("stf.spill %0=f11" : "=m"(f6_15[5])); - __asm__ ("stf.spill %0=f12" : "=m"(f6_15[6])); - __asm__ ("stf.spill %0=f13" : "=m"(f6_15[7])); - __asm__ ("stf.spill %0=f14" : "=m"(f6_15[8])); - __asm__ ("stf.spill %0=f15" : "=m"(f6_15[9])); + __asm__ ("stf.spill %0=f10%P0" : "=m"(f6_15[4])); + __asm__ ("stf.spill %0=f11%P0" : "=m"(f6_15[5])); + __asm__ ("stf.spill %0=f12%P0" : "=m"(f6_15[6])); + __asm__ ("stf.spill %0=f13%P0" : "=m"(f6_15[7])); + __asm__ ("stf.spill %0=f14%P0" : "=m"(f6_15[8])); + __asm__ ("stf.spill %0=f15%P0" : "=m"(f6_15[9])); fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) f6_15; #endif /* @@ -279,12 +279,12 @@ (unsigned long *) isr, (unsigned long *) pr, (unsigned long *) ifs, &fp_state); #ifdef FPSWA_BUG - __asm__ ("ldf.fill f10=%0" :: "m"(f6_15[4])); - __asm__ ("ldf.fill f11=%0" :: "m"(f6_15[5])); - __asm__ ("ldf.fill f12=%0" :: "m"(f6_15[6])); - __asm__ ("ldf.fill f13=%0" :: "m"(f6_15[7])); - __asm__ ("ldf.fill f14=%0" :: "m"(f6_15[8])); - __asm__ ("ldf.fill f15=%0" :: "m"(f6_15[9])); + __asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_15[4])); + __asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_15[5])); + __asm__ ("ldf.fill f12=%0%P0" :: "m"(f6_15[6])); + __asm__ ("ldf.fill f13=%0%P0" :: "m"(f6_15[7])); + __asm__ ("ldf.fill f14=%0%P0" :: "m"(f6_15[8])); + __asm__ ("ldf.fill f15=%0%P0" :: "m"(f6_15[9])); regs->f6 = f6_15[0]; regs->f7 = f6_15[1]; regs->f8 = f6_15[2]; diff -urN linux-2.4.0-test7/arch/ia64/kernel/unwind.c linux-2.4.0-test7-lia/arch/ia64/kernel/unwind.c --- linux-2.4.0-test7/arch/ia64/kernel/unwind.c Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/kernel/unwind.c Fri Aug 25 01:01:28 2000 @@ -1603,8 +1603,7 @@ int have_write_lock = 0; struct unw_script *scr; - if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf)) || rgn_index(info->ip) != RGN_KERNEL) - { + if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) { /* don't let obviously bad addresses pollute the cache */ debug(1, "unwind: rejecting bad ip=0x%lx\n", info->ip); info->rp = 0; diff -urN linux-2.4.0-test7/arch/ia64/lib/Makefile linux-2.4.0-test7-lia/arch/ia64/lib/Makefile --- linux-2.4.0-test7/arch/ia64/lib/Makefile Wed Aug 2 18:54:02 2000 +++ linux-2.4.0-test7-lia/arch/ia64/lib/Makefile Fri Aug 25 01:01:39 2000 @@ -3,30 +3,35 @@ # .S.o: - $(CC) $(AFLAGS) -c $< -o $@ + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c $< -o $@ L_TARGET = lib.a -L_OBJS = __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 memcpy.o memset.o strncpy_from_user.o \ - strlen.o strlen_user.o strnlen_user.o \ +L_OBJS = __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 +ifneq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y) + L_OBJS += memcpy.o memset.o strlen.o +endif + LX_OBJS = io.o IGNORE_FLAGS_OBJS = __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o -include $(TOPDIR)/Rules.make +$(L_TARGET): __divdi3.o: idiv.S - $(CC) $(AFLAGS) -c -o $@ $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $@ $< __udivdi3.o: idiv.S - $(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DUNSIGNED -c -o $@ $< __moddi3.o: idiv.S - $(CC) $(AFLAGS) -c -DMODULO -c -o $@ $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DMODULO -c -o $@ $< __umoddi3.o: idiv.S - $(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $< + $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -DMODULO -DUNSIGNED -c -o $@ $< + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.0-test7/arch/ia64/tools/Makefile linux-2.4.0-test7-lia/arch/ia64/tools/Makefile --- linux-2.4.0-test7/arch/ia64/tools/Makefile Wed Aug 2 18:54:03 2000 +++ linux-2.4.0-test7-lia/arch/ia64/tools/Makefile Fri Aug 25 01:01:47 2000 @@ -46,4 +46,4 @@ endif -.PHONY: all modules +.PHONY: all modules modules_install diff -urN linux-2.4.0-test7/arch/ia64/vmlinux.lds.S linux-2.4.0-test7-lia/arch/ia64/vmlinux.lds.S --- linux-2.4.0-test7/arch/ia64/vmlinux.lds.S Thu Aug 24 08:17:30 2000 +++ linux-2.4.0-test7-lia/arch/ia64/vmlinux.lds.S Fri Aug 25 01:02:07 2000 @@ -107,6 +107,21 @@ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - PAGE_OFFSET) { *(.data.cacheline_aligned) } +#if defined(CONFIG_KDB) + /* Kernel symbols and strings for kdb */ +# define KDB_MEAN_SYMBOL_SIZE 48 +# define KDB_SPACE (CONFIG_KDB_STBSIZE * KDB_MEAN_SYMBOL_SIZE) + . = ALIGN(8); + _skdb = .; + .kdb : AT(ADDR(.kdb) - PAGE_OFFSET) + { + *(kdbsymtab) + *(kdbstrings) + } + _ekdb = .; + . = _skdb + KDB_SPACE; +#endif + /* Kernel symbol names for modules: */ .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET) { *(.kstrtab) } diff -urN linux-2.4.0-test7/drivers/acpi/Makefile linux-2.4.0-test7-lia/drivers/acpi/Makefile --- linux-2.4.0-test7/drivers/acpi/Makefile Wed Jul 12 13:21:57 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/Makefile Fri Aug 25 01:02:26 2000 @@ -11,7 +11,11 @@ O_OBJS := M_OBJS := +ifdef CONFIG_ACPI_KERNEL_CONFIG +ACPI_OBJS := acpiconf.o osconf.o os.o +else ACPI_OBJS := driver.o ec.o cpu.o os.o sys.o tables.o +endif ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard */*.c)) EXTRA_CFLAGS += -I./include -D_LINUX diff -urN linux-2.4.0-test7/drivers/acpi/acpiconf.c linux-2.4.0-test7-lia/drivers/acpi/acpiconf.c --- linux-2.4.0-test7/drivers/acpi/acpiconf.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/acpi/acpiconf.c Fri Aug 25 01:02:35 2000 @@ -0,0 +1,379 @@ +/* + * acpiconf.c - ACPI based kernel configuration + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + */ + + +#include +#include +#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_INIT_DATA acpi_init_data; + + acpi_os_bind_osd(ACPI_CF_PHASE_BOOTTIME); + + acpi_init_data.RSDP_physical_address = rsdp; + status = acpi_initialize (&acpi_init_data); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:acpi initialize error=0x%x\n", status); + return status; + } else + printk ("Acpi cfg:acpi initialize pass\n"); + + status = acpi_load_firmware_tables (); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:acpi load firmware tables error=0x%x\n", status); + return status; + } else + printk ("Acpi cfg:acpi load firmware tables pass\n"); + + status = acpi_load_namespace (); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:acpi load namespace error=0x%x\n", status); + return status; + } else + printk ("Acpi cfg:acpi load namespace 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_terminate (); + if (ACPI_FAILURE(status)) { + printk ("Acpi cfg:acpi terminate error=0x%x\n", status); + /* fall thru...*/ + } else + printk ("Acpi cfg:acpi terminate pass\n"); + + 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; + + printk ("Acpi cfg:get pci vectors\n"); + 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)) { + 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 + + 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_HANDLE parent_handle; + 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: + 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); + 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; + } + + status = acpi_get_parent(handle, &parent_handle); + if (ACPI_FAILURE(status)) { + printk("Acpi cfg:get parent fail=0x%x\n", status); + acpi_os_free(prt); + return AE_OK; + } + + 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; + 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) + printk("Acpi cfg:_STA not found: 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) { + printk("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; + 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 = (PCI_ROUTING_TABLE *) ROUND_UP_TO_4BYTES(prt); + } + } + } + + *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 = *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 = (PCI_ROUTING_TABLE *) ROUND_UP_TO_4BYTES(prt); + } + acpi_os_free((void *)prt); + } + } + + vectors_to_free = *vectors; + + return AE_OK; +} + + +void __init +acpi_cf_cleanup ( void ) +{ + if (vectors_to_free) + acpi_os_free((void *)vectors_to_free); +} + + +#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-test7/drivers/acpi/acpiconf.h linux-2.4.0-test7-lia/drivers/acpi/acpiconf.h --- linux-2.4.0-test7/drivers/acpi/acpiconf.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/acpi/acpiconf.h Fri Aug 25 01:02:39 2000 @@ -0,0 +1,54 @@ +/* + * acpiconf.h - ACPI based kernel configuration + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + */ + + +#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) +#else +#define ACPI_CF_INITIALIZED() 1 +#endif + + +static ACPI_STATUS __init acpi_cf_get_prt (void **prts); + +extern void __init +acpi_os_bind_osd(int acpi_phase); + + +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-test7/drivers/acpi/common/cmglobal.c linux-2.4.0-test7-lia/drivers/acpi/common/cmglobal.c --- linux-2.4.0-test7/drivers/acpi/common/cmglobal.c Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/common/cmglobal.c Fri Aug 25 01:02:53 2000 @@ -177,7 +177,8 @@ /* 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} + /* SPIC 9 */ {SPIC_SIG, SPIC_SIG, sizeof (SPIC_SIG)-1, ACPI_TABLE_MULTIPLE, AE_OK, NULL}, + /* BOOT 10 */{BOOT_SIG, BOOT_SIG, sizeof (BOOT_SIG)-1, ACPI_TABLE_SINGLE, AE_SUPPORT, NULL} }; ACPI_INIT_DATA acpi_gbl_acpi_init_data; diff -urN linux-2.4.0-test7/drivers/acpi/dispatcher/dsobject.c linux-2.4.0-test7-lia/drivers/acpi/dispatcher/dsobject.c --- linux-2.4.0-test7/drivers/acpi/dispatcher/dsobject.c Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/dispatcher/dsobject.c Fri Aug 25 01:03:02 2000 @@ -199,7 +199,7 @@ ACPI_WALK_STATE *walk_state, ACPI_GENERIC_OP *op, u16 opcode, - ACPI_OBJECT_INTERNAL *obj_desc) + ACPI_OBJECT_INTERNAL **obj_desc) { ACPI_STATUS status; ACPI_GENERIC_OP *arg; @@ -218,7 +218,7 @@ /* Get and prepare the first argument */ - switch (obj_desc->common.type) + switch ((*obj_desc)->common.type) { case ACPI_TYPE_BUFFER: @@ -245,15 +245,15 @@ /* Get the value, delete the internal object */ - obj_desc->buffer.length = arg_desc->number.value; + (*obj_desc)->buffer.length = arg_desc->number.value; acpi_cm_remove_reference (arg_desc); /* Allocate the buffer */ - obj_desc->buffer.pointer = - acpi_cm_callocate (obj_desc->buffer.length); + (*obj_desc)->buffer.pointer = + acpi_cm_callocate ((*obj_desc)->buffer.length); - if (!obj_desc->buffer.pointer) { + if (!(*obj_desc)->buffer.pointer) { return AE_NO_MEMORY; } @@ -271,21 +271,25 @@ return AE_TYPE; } - MEMCPY (obj_desc->buffer.pointer, byte_list->data, - obj_desc->buffer.length); + MEMCPY ((*obj_desc)->buffer.pointer, byte_list->data, + (*obj_desc)->buffer.length); } break; + case ACPI_TYPE_PACKAGE: + status = acpi_ds_build_internal_object(walk_state, op, obj_desc); + break; + case ACPI_TYPE_NUMBER: - obj_desc->number.value = op->value.integer; + (*obj_desc)->number.value = op->value.integer; break; case ACPI_TYPE_STRING: - obj_desc->string.pointer = op->value.string; - obj_desc->string.length = STRLEN (op->value.string); + (*obj_desc)->string.pointer = op->value.string; + (*obj_desc)->string.length = STRLEN (op->value.string); break; @@ -301,16 +305,16 @@ /* Split the opcode into a base opcode + offset */ - obj_desc->reference.op_code = AML_LOCAL_OP; - obj_desc->reference.offset = opcode - AML_LOCAL_OP; + (*obj_desc)->reference.op_code = AML_LOCAL_OP; + (*obj_desc)->reference.offset = opcode - AML_LOCAL_OP; break; case OPTYPE_METHOD_ARGUMENT: /* Split the opcode into a base opcode + offset */ - obj_desc->reference.op_code = AML_ARG_OP; - obj_desc->reference.offset = opcode - AML_ARG_OP; + (*obj_desc)->reference.op_code = AML_ARG_OP; + (*obj_desc)->reference.offset = opcode - AML_ARG_OP; break; default: /* Constants, Literals, etc.. */ @@ -318,10 +322,10 @@ if (op->opcode == AML_NAMEPATH_OP) { /* Nte was saved in Op */ - obj_desc->reference.nte = op->acpi_named_object; + (*obj_desc)->reference.nte = op->acpi_named_object; } - obj_desc->reference.op_code = opcode; + (*obj_desc)->reference.op_code = opcode; break; } @@ -403,7 +407,7 @@ } status = acpi_ds_init_object_from_op (walk_state, op, - op->opcode, obj_desc); + op->opcode, &obj_desc); if (ACPI_FAILURE (status)) { acpi_cm_remove_reference (obj_desc); @@ -466,7 +470,7 @@ REPORT_ERROR ("Ds_build_internal_package_obj: Package vector allocation failure"); - acpi_cm_free (obj_desc); + acpi_cm_delete_object_desc (obj_desc); return (AE_NO_MEMORY); } diff -urN linux-2.4.0-test7/drivers/acpi/dispatcher/dsutils.c linux-2.4.0-test7-lia/drivers/acpi/dispatcher/dsutils.c --- linux-2.4.0-test7/drivers/acpi/dispatcher/dsutils.c Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/dispatcher/dsutils.c Fri Aug 25 01:03:08 2000 @@ -338,9 +338,9 @@ /* Initialize the new object */ status = acpi_ds_init_object_from_op (walk_state, arg, - opcode, obj_desc); + opcode, &obj_desc); if (ACPI_FAILURE (status)) { - acpi_cm_free (obj_desc); + acpi_cm_delete_object_desc (obj_desc); return (status); } } diff -urN linux-2.4.0-test7/drivers/acpi/events/evregion.c linux-2.4.0-test7-lia/drivers/acpi/events/evregion.c --- linux-2.4.0-test7/drivers/acpi/events/evregion.c Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/events/evregion.c Fri Aug 25 01:03:16 2000 @@ -297,6 +297,7 @@ ADDRESS_SPACE_SETUP region_setup; ACPI_OBJECT_INTERNAL *handler_desc; void *region_context; + void *save_context = NULL; /* @@ -348,6 +349,7 @@ /* * Save the returned context for use in all accesses to the region */ + save_context = handler_desc->addr_handler.context; handler_desc->addr_handler.context = region_context; } @@ -378,6 +380,9 @@ acpi_aml_enter_interpreter (); } + + if (save_context) + handler_desc->addr_handler.context = save_context; return (status); } diff -urN linux-2.4.0-test7/drivers/acpi/hardware/hwxface.c linux-2.4.0-test7-lia/drivers/acpi/hardware/hwxface.c --- linux-2.4.0-test7/drivers/acpi/hardware/hwxface.c Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/hardware/hwxface.c Fri Aug 25 01:03:26 2000 @@ -68,8 +68,10 @@ NATIVE_UINT num_throttle_states; NATIVE_UINT buffer_space_needed; NATIVE_UINT i; - u8 duty_offset; - u8 duty_width; +#ifndef _IA64 + u8 duty_offset = 0; +#endif + u8 duty_width = 0; ACPI_NAMED_OBJECT *cpu_entry; ACPI_OBJECT_INTERNAL *cpu_obj; ACPI_CPU_THROTTLING_STATE *state_ptr; @@ -100,9 +102,10 @@ return (AE_NOT_FOUND); } +#ifndef _IA64 duty_offset = acpi_gbl_FACP->duty_offset; duty_width = acpi_gbl_FACP->duty_width; - +#endif /* * P0 must always have a P_BLK all others may be null * in either case, we can't thottle a processor that has no P_BLK @@ -172,9 +175,9 @@ ACPI_NAMED_OBJECT *cpu_entry; ACPI_OBJECT_INTERNAL *cpu_obj; u32 num_throttle_states; - u32 duty_cycle; - u8 duty_offset; - u8 duty_width; + u32 duty_cycle = 0; + u8 duty_offset = 0; + u8 duty_width = 0; /* Convert and validate the device handle */ @@ -191,8 +194,10 @@ return (AE_NOT_FOUND); } +#ifndef _IA64 duty_offset = acpi_gbl_FACP->duty_offset; duty_width = acpi_gbl_FACP->duty_width; +#endif /* * Must have a valid P_BLK P0 must have a P_BLK all others may be null @@ -273,8 +278,10 @@ return (AE_NOT_FOUND); } +#ifndef _IA64 duty_offset = acpi_gbl_FACP->duty_offset; duty_width = acpi_gbl_FACP->duty_width; +#endif /* * Must have a valid P_BLK P0 must have a P_BLK all others may be null diff -urN linux-2.4.0-test7/drivers/acpi/include/acenv.h linux-2.4.0-test7-lia/drivers/acpi/include/acenv.h --- linux-2.4.0-test7/drivers/acpi/include/acenv.h Thu Jul 6 01:22:24 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/acenv.h Fri Aug 25 01:03:34 2000 @@ -75,6 +75,7 @@ #include #include #include +#include /* Single threaded */ @@ -226,9 +227,54 @@ #define BREAKPOINT3 #define disable() __cli() #define enable() __sti() -#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") #define wbinvd() +#ifdef _IA64 +#define halt() /* PAL_HALT[_LIGHT] */ +#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) + +#else +#define halt() __asm__ __volatile__ ("sti; hlt":::"memory") /*! [Begin] no source code translation * @@ -239,33 +285,34 @@ * Immediate values in the assembly are preceded by "$" as in "$0x1" * The final asm parameter is the non-output registers altered by the operation */ + #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ + asm("1: movl (%2),%%eax;" \ "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ + "andl %3,%%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"); \ + :"=a"(Acq),"=c"(GLptr):"c"(GLptr),"i"(~1L):"dx"); \ } while(0) #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ do { \ - int dummy; \ - asm("1: movl (%1),%%eax;" \ + asm("1: movl (%2),%%eax;" \ "movl %%eax,%%edx;" \ - "andl %2,%%edx;" \ + "andl %3,%%edx;" \ "lock; cmpxchgl %%edx,(%1);" \ "jnz 1b;" \ "andl $0x1,%%eax" \ - :"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \ + :"=a"(Acq),"=c"(GLptr):"c"(GLptr),"i"(~3L):"dx"); \ } while(0) /*! [End] no source code translation !*/ + +#endif #endif /* __GNUC__ */ diff -urN linux-2.4.0-test7/drivers/acpi/include/actables.h linux-2.4.0-test7-lia/drivers/acpi/include/actables.h --- linux-2.4.0-test7/drivers/acpi/include/actables.h Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/actables.h Fri Aug 25 01:03:43 2000 @@ -40,6 +40,7 @@ #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 SPIC_SIG "SPIC" /* iosapic table */ #define BOOT_SIG "BOOT" /* Boot table */ @@ -61,16 +62,6 @@ * The architecture dependent tables are in separate files */ -typedef struct /* Root System Descriptor Pointer */ -{ - char signature [8]; /* contains "RSD PTR " */ - u8 checksum; /* to make sum of struct == 0 */ - char oem_id [6]; /* OEM identification */ - u8 reserved; /* reserved - must be zero */ - u32 rsdt_physical_address; /* physical address of RSDT */ - -} ROOT_SYSTEM_DESCRIPTOR_POINTER; - typedef struct /* ACPI common table header */ { @@ -178,7 +169,7 @@ * Get the architecture-specific tables */ -#ifdef IA64 +#ifdef _IA64 #include "actbl64.h" #else #include "actbl32.h" diff -urN linux-2.4.0-test7/drivers/acpi/include/actbl32.h linux-2.4.0-test7-lia/drivers/acpi/include/actbl32.h --- linux-2.4.0-test7/drivers/acpi/include/actbl32.h Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/actbl32.h Fri Aug 25 01:03:50 2000 @@ -26,6 +26,17 @@ #define __ACTBL32_H__ +/* IA32 Root System Descriptor Pointer */ +typedef struct +{ + char signature [8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + char oem_id [6]; /* OEM identification */ + u8 reserved; /* reserved - must be zero */ + u32 rsdt_physical_address; /* physical address of RSDT */ +} ROOT_SYSTEM_DESCRIPTOR_POINTER; + + /* IA32 Root System Description Table */ typedef struct diff -urN linux-2.4.0-test7/drivers/acpi/include/actbl64.h linux-2.4.0-test7-lia/drivers/acpi/include/actbl64.h --- linux-2.4.0-test7/drivers/acpi/include/actbl64.h Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/actbl64.h Fri Aug 25 01:03:55 2000 @@ -29,6 +29,17 @@ typedef UINT64 IO_ADDRESS; /* Only for clarity in declarations */ +/* IA64 Root System Descriptor Pointer */ + +typedef struct +{ + char signature [8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + char oem_id [6]; /* OEM identification */ + u8 reserved; /* reserved - must be zero */ + u32 rsdt_physical_address; /* physical address of RSDT. u64!!! */ +} ROOT_SYSTEM_DESCRIPTOR_POINTER; + /* IA64 Root System Description Table */ @@ -65,7 +76,7 @@ ACPI_TABLE_HEADER header; /* table header */ u32 reserved_pad; /* IA64 alignment, must be 0 */ ACPI_TBLPTR firmware_ctrl; /* Physical address of FACS */ - ACPI_TBLPTR acpi_dsdt; /* Physical address of DSDT */ + 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 */ @@ -90,8 +101,8 @@ 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 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 */ @@ -99,7 +110,7 @@ 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 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 */ diff -urN linux-2.4.0-test7/drivers/acpi/include/actypes.h linux-2.4.0-test7-lia/drivers/acpi/include/actypes.h --- linux-2.4.0-test7/drivers/acpi/include/actypes.h Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/actypes.h Fri Aug 25 01:04:05 2000 @@ -216,9 +216,10 @@ #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_SPIC (ACPI_TABLE_TYPE) 9 +#define ACPI_TABLE_BOOT (ACPI_TABLE_TYPE) 10 +#define ACPI_TABLE_MAX 10 +#define NUM_ACPI_TABLES 11 /* diff -urN linux-2.4.0-test7/drivers/acpi/include/dispatch.h linux-2.4.0-test7-lia/drivers/acpi/include/dispatch.h --- linux-2.4.0-test7/drivers/acpi/include/dispatch.h Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/dispatch.h Fri Aug 25 01:04:14 2000 @@ -258,7 +258,7 @@ ACPI_WALK_STATE *walk_state, ACPI_GENERIC_OP *op, u16 opcode, - ACPI_OBJECT_INTERNAL *obj_desc); + ACPI_OBJECT_INTERNAL **obj_desc); ACPI_STATUS acpi_ds_create_named_object ( @@ -380,4 +380,4 @@ void); -#endif /* _DISPATCH_H_ */ \ No newline at end of file +#endif /* _DISPATCH_H_ */ diff -urN linux-2.4.0-test7/drivers/acpi/include/macros.h linux-2.4.0-test7-lia/drivers/acpi/include/macros.h --- linux-2.4.0-test7/drivers/acpi/include/macros.h Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/include/macros.h Fri Aug 25 01:04:26 2000 @@ -133,13 +133,15 @@ * Rounding macros (Power of two boundaries only) */ +#define ROUND_UP_TO_4BYTES(val) ((NATIVE_UINT)(((NATIVE_UINT)(val)+3)&~3)) + #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) #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_NATIVE_WORD(a) ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY) -#define ROUND_UP_TO_32_bITS(a) ROUND_UP(a,4) +#define ROUND_UP_TO_32_BITS(a) ROUND_UP(a,4) #define ROUND_UP_TO_NATIVE_WORD(a) ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY) diff -urN linux-2.4.0-test7/drivers/acpi/namespace/nseval.c linux-2.4.0-test7-lia/drivers/acpi/namespace/nseval.c --- linux-2.4.0-test7/drivers/acpi/namespace/nseval.c Wed Jul 5 11:23:12 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/namespace/nseval.c Fri Aug 25 01:04:42 2000 @@ -161,11 +161,9 @@ /* Build an internal name string for the method */ - if (pathname[0] != '\\' || pathname[1] != '/') { - status = acpi_ns_internalize_name (pathname, &internal_path); - if (ACPI_FAILURE (status)) { - return (status); - } + status = acpi_ns_internalize_name (pathname, &internal_path); + if (ACPI_FAILURE (status)) { + return (status); } acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); diff -urN linux-2.4.0-test7/drivers/acpi/os.c linux-2.4.0-test7-lia/drivers/acpi/os.c --- linux-2.4.0-test7/drivers/acpi/os.c Thu Jul 13 09:39:49 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/os.c Fri Aug 25 01:04:48 2000 @@ -2,6 +2,7 @@ * os.c - OS-dependent functions * * Copyright (C) 2000 Andrew Henroid + * 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,6 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include + #include #include #include @@ -29,6 +32,36 @@ #include "acpi.h" #include "driver.h" + +#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; @@ -81,13 +114,13 @@ } 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) @@ -96,7 +129,7 @@ } void -acpi_os_free(void *ptr) +acpi_os_free_rt(void *ptr) { kfree(ptr); } @@ -209,8 +242,9 @@ outl(val, port); } + ACPI_STATUS -acpi_os_read_pci_cfg_byte( +acpi_os_read_pci_cfg_byte_rt( u32 bus, u32 func, u32 addr, @@ -224,7 +258,7 @@ } ACPI_STATUS -acpi_os_read_pci_cfg_word( +acpi_os_read_pci_cfg_word_rt( u32 bus, u32 func, u32 addr, @@ -238,7 +272,7 @@ } ACPI_STATUS -acpi_os_read_pci_cfg_dword( +acpi_os_read_pci_cfg_dword_rt( u32 bus, u32 func, u32 addr, @@ -252,7 +286,7 @@ } ACPI_STATUS -acpi_os_write_pci_cfg_byte( +acpi_os_write_pci_cfg_byte_rt( u32 bus, u32 func, u32 addr, @@ -266,7 +300,7 @@ } ACPI_STATUS -acpi_os_write_pci_cfg_word( +acpi_os_write_pci_cfg_word_rt( u32 bus, u32 func, u32 addr, @@ -280,7 +314,7 @@ } ACPI_STATUS -acpi_os_write_pci_cfg_dword( +acpi_os_write_pci_cfg_dword_rt( u32 bus, u32 func, u32 addr, @@ -298,13 +332,18 @@ */ ACPI_STATUS -acpi_os_queue_for_execution( +acpi_os_queue_for_execution_rt( u32 priority, OSD_EXECUTION_CALLBACK callback, void *context) { +#ifndef CONFIG_ACPI_KERNEL_CONFIG if (acpi_run(callback, context)) return AE_ERROR; +#else + /* run callbakc immediately until driver.c works */ + (*callback)(context); +#endif return AE_OK; } diff -urN linux-2.4.0-test7/drivers/acpi/osconf.c linux-2.4.0-test7-lia/drivers/acpi/osconf.c --- linux-2.4.0-test7/drivers/acpi/osconf.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/acpi/osconf.c Fri Aug 25 01:04:53 2000 @@ -0,0 +1,334 @@ +/* + * 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 + +#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; + //printk("Acpi cfg: alloc_bootmem 0x%lx, 0x%lx\n", ptr, size); +}; + +static void __init +acpi_cf_bm_checkout(void *ptr, u32 size) +{ + bm_free_count_max++; + bm_alloc_size -= size; + //printk("Acpi cfg: free_bootmem 0x%lx, 0x%lx\n", ptr, 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 until driver.c works */ + (*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-test7/drivers/acpi/osconf.h linux-2.4.0-test7-lia/drivers/acpi/osconf.h --- linux-2.4.0-test7/drivers/acpi/osconf.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/acpi/osconf.h Fri Aug 25 01:04:57 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-test7/drivers/acpi/resources/rsaddr.c linux-2.4.0-test7-lia/drivers/acpi/resources/rsaddr.c --- linux-2.4.0-test7/drivers/acpi/resources/rsaddr.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rsaddr.c Fri Aug 25 01:05:16 2000 @@ -75,7 +75,7 @@ */ buffer += 1; - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); *bytes_consumed = temp16 + 3; @@ -234,7 +234,7 @@ * Struct_size to the next 32-bit boundry. */ temp8 = (u8) (index + 1); - struct_size += ROUND_UP_TO_32_bITS (temp8); + struct_size += ROUND_UP_TO_32_BITS (temp8); } else { output_struct->data.address16.resource_source_index = 0x00; @@ -615,7 +615,7 @@ * Struct_size to the next 32-bit boundry. */ temp8 = (u8) (index + 1); - struct_size += ROUND_UP_TO_32_bITS (temp8); + struct_size += ROUND_UP_TO_32_BITS (temp8); } else { diff -urN linux-2.4.0-test7/drivers/acpi/resources/rscalc.c linux-2.4.0-test7-lia/drivers/acpi/resources/rscalc.c --- linux-2.4.0-test7/drivers/acpi/resources/rscalc.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rscalc.c Fri Aug 25 01:05:23 2000 @@ -360,7 +360,7 @@ /* * Ensure a 32-bit boundary for the structure */ - temp16 = (u16) ROUND_UP_TO_32_bITS (temp16); + temp16 = (u16) ROUND_UP_TO_32_BITS (temp16); structure_size = sizeof (VENDOR_RESOURCE) + RESOURCE_LENGTH_NO_DATA + @@ -419,7 +419,7 @@ /* * Ensure a 32-bit boundary for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ROUND_UP_TO_32_BITS (temp8); structure_size = sizeof (ADDRESS32_RESOURCE) + RESOURCE_LENGTH_NO_DATA + @@ -457,7 +457,7 @@ /* * Ensure a 32-bit boundry for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ROUND_UP_TO_32_BITS (temp8); structure_size = sizeof (ADDRESS16_RESOURCE) + RESOURCE_LENGTH_NO_DATA + @@ -512,7 +512,7 @@ /* * Ensure a 32-bit boundry for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ROUND_UP_TO_32_BITS (temp8); structure_size = sizeof (EXTENDED_IRQ_RESOURCE) + RESOURCE_LENGTH_NO_DATA + @@ -699,7 +699,7 @@ /* * Ensure a 32-bit boundry for the structure */ - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ROUND_UP_TO_32_BITS (temp8); structure_size = sizeof (VENDOR_RESOURCE) + RESOURCE_LENGTH_NO_DATA + diff -urN linux-2.4.0-test7/drivers/acpi/resources/rscreate.c linux-2.4.0-test7-lia/drivers/acpi/resources/rscreate.c --- linux-2.4.0-test7/drivers/acpi/resources/rscreate.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rscreate.c Fri Aug 25 01:05:30 2000 @@ -247,6 +247,7 @@ * terminating NULL */ buffer_size_needed += ((*sub_object_list)->string.length); + buffer_size_needed = ROUND_UP_TO_4BYTES(buffer_size_needed); } else { @@ -255,6 +256,7 @@ * translated as a u32 zero. */ buffer_size_needed += sizeof(u32); + buffer_size_needed = ROUND_UP_TO_4BYTES(buffer_size_needed); } /* @@ -293,6 +295,7 @@ * earlier */ buffer += user_prt->length; + buffer = (u8 *) ROUND_UP_TO_4BYTES(buffer); user_prt = (PCI_ROUTING_TABLE *)buffer; @@ -355,6 +358,7 @@ * Add to the Length field the length of the string */ user_prt->length += (*sub_object_list)->string.length; + user_prt->length = ROUND_UP_TO_4BYTES(user_prt->length); } else { @@ -369,6 +373,7 @@ * the u32 NULL */ user_prt->length += sizeof(u32); + user_prt->length = ROUND_UP_TO_4BYTES(user_prt->length); } else { diff -urN linux-2.4.0-test7/drivers/acpi/resources/rsio.c linux-2.4.0-test7-lia/drivers/acpi/resources/rsio.c --- linux-2.4.0-test7/drivers/acpi/resources/rsio.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rsio.c Fri Aug 25 01:05:36 2000 @@ -90,7 +90,7 @@ * Check Min_base Address */ buffer += 1; - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); output_struct->data.io.min_base_address = temp16; @@ -98,7 +98,7 @@ * Check Max_base Address */ buffer += 2; - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); output_struct->data.io.max_base_address = temp16; @@ -255,7 +255,7 @@ */ temp16 = (u16) linked_list->data.io.min_base_address; - *(u16 *)buffer = temp16; + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; @@ -264,7 +264,7 @@ */ temp16 = (u16) linked_list->data.io.max_base_address; - *(u16 *)buffer = temp16; + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; @@ -336,7 +336,7 @@ */ temp16 = (u16) linked_list->data.fixed_io.base_address; - *(u16 *)buffer = temp16; + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; diff -urN linux-2.4.0-test7/drivers/acpi/resources/rsirq.c linux-2.4.0-test7-lia/drivers/acpi/resources/rsirq.c --- linux-2.4.0-test7/drivers/acpi/resources/rsirq.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rsirq.c Fri Aug 25 01:05:40 2000 @@ -85,7 +85,7 @@ * Point to the 16-bits of Bytes 1 and 2 */ buffer += 1; - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); output_struct->data.irq.number_of_interrupts = 0; @@ -226,7 +226,7 @@ temp16 |= 0x1 << temp8; } - *(u16 *)buffer = temp16; + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; @@ -306,7 +306,7 @@ * Point past the Descriptor to get the number of bytes consumed */ buffer += 1; - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); *bytes_consumed = temp16 + 3; output_struct->id = extended_irq; @@ -426,7 +426,7 @@ * Struct_size to the next 32-bit boundry. */ temp8 = (u8) (index + 1); - temp8 = (u8) ROUND_UP_TO_32_bITS (temp8); + temp8 = (u8) ROUND_UP_TO_32_BITS (temp8); } else { diff -urN linux-2.4.0-test7/drivers/acpi/resources/rsmemory.c linux-2.4.0-test7-lia/drivers/acpi/resources/rsmemory.c --- linux-2.4.0-test7/drivers/acpi/resources/rsmemory.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rsmemory.c Fri Aug 25 01:05:47 2000 @@ -76,7 +76,7 @@ */ buffer += 1; - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); buffer += 2; @@ -96,7 +96,7 @@ /* * Get Min_base_address (Bytes 4-5) */ - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); buffer += 2; @@ -105,7 +105,7 @@ /* * Get Max_base_address (Bytes 6-7) */ - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); buffer += 2; @@ -114,7 +114,7 @@ /* * Get Alignment (Bytes 8-9) */ - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); buffer += 2; @@ -123,7 +123,7 @@ /* * Get Range_length (Bytes 10-11) */ - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); output_struct->data.memory24.range_length = temp16; diff -urN linux-2.4.0-test7/drivers/acpi/resources/rsmisc.c linux-2.4.0-test7-lia/drivers/acpi/resources/rsmisc.c --- linux-2.4.0-test7/drivers/acpi/resources/rsmisc.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/resources/rsmisc.c Fri Aug 25 01:05:52 2000 @@ -199,7 +199,7 @@ /* Dereference */ - temp16 = *(u16 *)buffer; + MOVE_UNALIGNED16_TO_16 (&temp16, buffer); /* Calculate bytes consumed */ @@ -242,7 +242,7 @@ * calculate the length of the vendor string and expand the * Struct_size to the next 32-bit boundry. */ - struct_size += ROUND_UP_TO_32_bITS (temp16); + struct_size += ROUND_UP_TO_32_BITS (temp16); /* * Set the Length parameter @@ -304,7 +304,7 @@ temp16 = (u16) linked_list->data.vendor_specific.length; - *(u16 *)buffer = temp16; + MOVE_UNALIGNED16_TO_16 (buffer, &temp16); buffer += 2; } diff -urN linux-2.4.0-test7/drivers/acpi/tables/tbtable.c linux-2.4.0-test7-lia/drivers/acpi/tables/tbtable.c --- linux-2.4.0-test7/drivers/acpi/tables/tbtable.c Wed Jul 5 11:23:13 2000 +++ linux-2.4.0-test7-lia/drivers/acpi/tables/tbtable.c Fri Aug 25 01:06:14 2000 @@ -111,9 +111,8 @@ /* Determine the number of tables pointed to by the RSDT */ - *number_of_tables = (s32) DIV_4 (acpi_gbl_RSDT->header.length - - sizeof (ACPI_TABLE_HEADER)); - + *number_of_tables = (s32) (acpi_gbl_RSDT->header.length - + sizeof (ACPI_TABLE_HEADER)) / sizeof(void *); return (status); } diff -urN linux-2.4.0-test7/drivers/char/Makefile linux-2.4.0-test7-lia/drivers/char/Makefile --- linux-2.4.0-test7/drivers/char/Makefile Thu Aug 24 08:17:31 2000 +++ linux-2.4.0-test7-lia/drivers/char/Makefile Fri Aug 25 01:06:50 2000 @@ -110,6 +110,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-test7/drivers/char/simserial.c linux-2.4.0-test7-lia/drivers/char/simserial.c --- linux-2.4.0-test7/drivers/char/simserial.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/char/simserial.c Fri Aug 11 14:56:04 2000 @@ -0,0 +1,1094 @@ +/* + * 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 SIMSERIAL_IRQ 0xee + +#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, SIMSERIAL_IRQ, 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(); + + /* connect the platform's keyboard interrupt to SIMSERIAL_IRQ */ + ia64_ssc_connect_irq(KEYBOARD_INTR, SIMSERIAL_IRQ); + + /* 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; + + 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-test7/drivers/media/radio/Makefile linux-2.4.0-test7-lia/drivers/media/radio/Makefile --- linux-2.4.0-test7/drivers/media/radio/Makefile Thu Aug 24 08:17:34 2000 +++ linux-2.4.0-test7-lia/drivers/media/radio/Makefile Fri Aug 25 01:08:08 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-test7/drivers/media/radio/dummy.c linux-2.4.0-test7-lia/drivers/media/radio/dummy.c --- linux-2.4.0-test7/drivers/media/radio/dummy.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/media/radio/dummy.c Fri Aug 25 01:08:14 2000 @@ -0,0 +1 @@ +/* just so the linker knows what kind of object files it's deadling with... */ diff -urN linux-2.4.0-test7/drivers/media/video/Makefile linux-2.4.0-test7-lia/drivers/media/video/Makefile --- linux-2.4.0-test7/drivers/media/video/Makefile Thu Aug 24 08:17:34 2000 +++ linux-2.4.0-test7-lia/drivers/media/video/Makefile Fri Aug 25 01:08:05 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-test7/drivers/media/video/dummy.c linux-2.4.0-test7-lia/drivers/media/video/dummy.c --- linux-2.4.0-test7/drivers/media/video/dummy.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/media/video/dummy.c Fri Aug 25 01:08: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-test7/drivers/net/Makefile linux-2.4.0-test7-lia/drivers/net/Makefile --- linux-2.4.0-test7/drivers/net/Makefile Thu Aug 24 08:17:34 2000 +++ linux-2.4.0-test7-lia/drivers/net/Makefile Fri Aug 25 00:12:27 2000 @@ -196,6 +196,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-test7/drivers/net/eepro100.c linux-2.4.0-test7-lia/drivers/net/eepro100.c --- linux-2.4.0-test7/drivers/net/eepro100.c Thu Aug 24 08:17:34 2000 +++ linux-2.4.0-test7-lia/drivers/net/eepro100.c Fri Aug 25 01:08:37 2000 @@ -41,9 +41,18 @@ static int txdmacount = 128; static int rxdmacount = 0; +#ifdef __ia64__ +/* + * Bug: this driver may generate unaligned accesses when not copying + * an incoming packet. Setting rx_copybreak to a large value force a + * copy and prevents unaligned accesses. + */ +static int rx_copybreak = 0x10000; +#else /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method. Lower values use more memory, but are faster. */ static int rx_copybreak = 200; +#endif /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static int max_interrupt_work = 20; @@ -429,14 +438,14 @@ /* 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; diff -urN linux-2.4.0-test7/drivers/net/simeth.c linux-2.4.0-test7-lia/drivers/net/simeth.c --- linux-2.4.0-test7/drivers/net/simeth.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/net/simeth.c Mon Jul 31 14:01:22 2000 @@ -0,0 +1,600 @@ +/* + * 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_IRQ 0xed +#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)); + /* + * XXX Fix me + * does not support more than one card ! + */ + dev->irq = SIMETH_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-test7/drivers/scsi/Makefile linux-2.4.0-test7-lia/drivers/scsi/Makefile --- linux-2.4.0-test7/drivers/scsi/Makefile Thu Aug 10 19:56:23 2000 +++ linux-2.4.0-test7-lia/drivers/scsi/Makefile Thu Aug 10 20:29:30 2000 @@ -40,6 +40,7 @@ obj-$(CONFIG_SCSI_PSI240I) += psi240i.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_A4000T_SCSI) += amiga7xx.o 53c7xx.o obj-$(CONFIG_A4091_SCSI) += amiga7xx.o 53c7xx.o diff -urN linux-2.4.0-test7/drivers/scsi/hosts.c linux-2.4.0-test7-lia/drivers/scsi/hosts.c --- linux-2.4.0-test7/drivers/scsi/hosts.c Tue Jul 11 11:17:45 2000 +++ linux-2.4.0-test7-lia/drivers/scsi/hosts.c Mon Jul 31 14:01:22 2000 @@ -325,6 +325,10 @@ #include "scsi_debug.h" #endif +#ifdef CONFIG_SCSI_SIM +#include "simscsi.h" +#endif + #ifdef CONFIG_SCSI_ACORNSCSI_3 #include "../acorn/scsi/acornscsi.h" #endif @@ -637,6 +641,9 @@ #endif #ifdef CONFIG_SCSI_PLUTO PLUTO, +#endif +#ifdef CONFIG_SCSI_SIM + SIMSCSI, #endif #ifdef CONFIG_ARCH_ACORN #ifdef CONFIG_SCSI_ACORNSCSI_3 diff -urN linux-2.4.0-test7/drivers/scsi/qla1280.c linux-2.4.0-test7-lia/drivers/scsi/qla1280.c --- linux-2.4.0-test7/drivers/scsi/qla1280.c Mon Jun 19 13:42:40 2000 +++ linux-2.4.0-test7-lia/drivers/scsi/qla1280.c Mon Jul 31 14:01:22 2000 @@ -809,6 +809,7 @@ index++, &pci_bus, &pci_devfn)) ) { #endif /* found a adapter */ + template->unchecked_isa_dma = 1; host = scsi_register(template, sizeof(scsi_qla_host_t)); ha = (scsi_qla_host_t *) host->hostdata; /* Clear our data area */ diff -urN linux-2.4.0-test7/drivers/scsi/simscsi.c linux-2.4.0-test7-lia/drivers/scsi/simscsi.c --- linux-2.4.0-test7/drivers/scsi/simscsi.c Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/scsi/simscsi.c Mon Jul 31 14:01:22 2000 @@ -0,0 +1,359 @@ +/* + * 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; +} diff -urN linux-2.4.0-test7/drivers/scsi/simscsi.h linux-2.4.0-test7-lia/drivers/scsi/simscsi.h --- linux-2.4.0-test7/drivers/scsi/simscsi.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/drivers/scsi/simscsi.h Mon Jul 31 14:01:22 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-test7/drivers/usb/ibmcam.c linux-2.4.0-test7-lia/drivers/usb/ibmcam.c --- linux-2.4.0-test7/drivers/usb/ibmcam.c Thu Aug 10 19:56:30 2000 +++ linux-2.4.0-test7-lia/drivers/usb/ibmcam.c Mon Jul 31 14:01:22 2000 @@ -62,7 +62,7 @@ #define FLAGS_SEPARATE_FRAMES (1 << 5) #define FLAGS_CLEAN_FRAMES (1 << 6) -static int flags = 0; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ +static int flags = FLAGS_RETRY_VIDIOCSYNC; /* FLAGS_DISPLAY_HINTS | FLAGS_OVERLAY_STATS; */ /* This is the size of V4L frame that we provide */ static const int imgwidth = V4L_FRAME_WIDTH_USED; diff -urN linux-2.4.0-test7/drivers/usb/uhci.c linux-2.4.0-test7-lia/drivers/usb/uhci.c --- linux-2.4.0-test7/drivers/usb/uhci.c Thu Aug 10 19:56:30 2000 +++ linux-2.4.0-test7-lia/drivers/usb/uhci.c Mon Jul 31 14:01:22 2000 @@ -33,7 +33,7 @@ #include #include #include -#define DEBUG +#undef DEBUG #include #include @@ -68,6 +68,46 @@ /* If a transfer is still active after this much time, turn off FSBR */ #define IDLE_TIMEOUT (HZ / 20) /* 50 ms */ +#ifdef CONFIG_ITANIUM_A1_SPECIFIC + +static struct uhci *guhci; + +void +disable_usb (void) +{ + unsigned short cmd; + unsigned int io_addr; + + if (guhci == NULL) + return; + + io_addr = guhci->io_addr; + + cmd = inw (io_addr + USBCMD); + + outw(cmd & ~ USBCMD_RS, io_addr+USBCMD); + + while ((inw (io_addr + USBSTS) & USBSTS_HCH) == 0); +} + +void +reenable_usb (void) +{ + unsigned int io_addr; + unsigned short cmd; + + if (guhci == NULL) + return; + + io_addr = guhci->io_addr; + + cmd = inw (io_addr + USBCMD); + + outw(cmd | USBCMD_RS, io_addr+USBCMD); +} + +#endif /* CONFIG_ITANIUM_A1_SPECIFIC */ + /* * Only the USB core should call uhci_alloc_dev and uhci_free_dev */ @@ -2356,6 +2396,11 @@ if (!uhci_start_root_hub(uhci)) { struct pm_dev *pmdev; +#ifdef CONFIG_ITANIUM_A1_SPECIFIC + guhci = uhci; + printk("%s: enabling Lion USB workaround io_addr=%x\n", + __FILE__, guhci->io_addr); +#endif pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(dev), handle_pm_event); diff -urN linux-2.4.0-test7/fs/binfmt_elf.c linux-2.4.0-test7-lia/fs/binfmt_elf.c --- linux-2.4.0-test7/fs/binfmt_elf.c Thu Aug 10 19:56:31 2000 +++ linux-2.4.0-test7-lia/fs/binfmt_elf.c Mon Jul 31 14:01:22 2000 @@ -482,6 +482,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-test7/fs/nfsd/nfsfh.c linux-2.4.0-test7-lia/fs/nfsd/nfsfh.c --- linux-2.4.0-test7/fs/nfsd/nfsfh.c Thu Aug 24 08:17:46 2000 +++ linux-2.4.0-test7-lia/fs/nfsd/nfsfh.c Fri Aug 25 00:12:34 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-test7/fs/proc/generic.c linux-2.4.0-test7-lia/fs/proc/generic.c --- linux-2.4.0-test7/fs/proc/generic.c Thu Aug 24 08:17:46 2000 +++ linux-2.4.0-test7-lia/fs/proc/generic.c Fri Aug 25 01:38:23 2000 @@ -43,7 +43,7 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif -/* 4K page size but our output routines use some slack for overruns */ +/* buffer size is one page but our output routines use some slack for overruns */ #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) static ssize_t diff -urN linux-2.4.0-test7/fs/readdir.c linux-2.4.0-test7-lia/fs/readdir.c --- linux-2.4.0-test7/fs/readdir.c Thu Aug 24 08:17:46 2000 +++ linux-2.4.0-test7-lia/fs/readdir.c Fri Aug 25 01:11:02 2000 @@ -325,4 +325,3 @@ out: return error; } - diff -urN linux-2.4.0-test7/include/asm-ia64/acpi-ext.h linux-2.4.0-test7-lia/include/asm-ia64/acpi-ext.h --- linux-2.4.0-test7/include/asm-ia64/acpi-ext.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/acpi-ext.h Fri Aug 25 01:16:49 2000 @@ -60,7 +60,7 @@ #define LSAPIC_PERFORMANCE_RESTRICTED (1<<1) #define LSAPIC_PRESENT (1<<2) -typedef struct { +typedef struct acpi_entry_lsapic { u8 type; u8 length; u16 acpi_processor_id; diff -urN linux-2.4.0-test7/include/asm-ia64/acpikcfg.h linux-2.4.0-test7-lia/include/asm-ia64/acpikcfg.h --- linux-2.4.0-test7/include/asm-ia64/acpikcfg.h Wed Dec 31 16:00:00 1969 +++ linux-2.4.0-test7-lia/include/asm-ia64/acpikcfg.h Fri Aug 25 02:06:53 2000 @@ -0,0 +1,29 @@ +#ifdef CONFIG_ACPI_KERNEL_CONFIG +/* + * acpikcfg.h - ACPI based Kernel Configuration Manager External Interfaces + * + * Copyright (C) 2000 Intel Corp. + * Copyright (C) 2000 J.I. Lee + */ + + +typedef u32 ACPI_STATUS; /* from actypes.h */ + +ACPI_STATUS __init acpi_cf_init (void * rsdp); +ACPI_STATUS __init acpi_cf_terminate (void ); + +ACPI_STATUS __init +acpi_cf_get_pci_vectors ( + struct pci_vector_struct **vectors, + int *num_pci_vectors + ); + + +#ifdef CONFIG_ACPI_KERNEL_CONFIG_DEBUG +void __init +acpi_cf_print_pci_vectors ( + struct pci_vector_struct *vectors, + int num_pci_vectors + ); +#endif +#endif /* CONFIG_ACPI_KERNEL_CONFIG */ diff -urN linux-2.4.0-test7/include/asm-ia64/fcntl.h linux-2.4.0-test7-lia/include/asm-ia64/fcntl.h --- linux-2.4.0-test7/include/asm-ia64/fcntl.h Wed Jul 5 11:13:39 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/fcntl.h Fri Aug 25 01:12:11 2000 @@ -3,8 +3,8 @@ /* * This is mostly compatible with Linux/x86. * - * 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 */ /* @@ -69,5 +69,9 @@ off_t l_len; pid_t l_pid; }; + +#ifdef __KERNEL__ +# define flock64 flock +#endif #endif /* _ASM_IA64_FCNTL_H */ diff -urN linux-2.4.0-test7/include/asm-ia64/hardirq.h linux-2.4.0-test7-lia/include/asm-ia64/hardirq.h --- linux-2.4.0-test7/include/asm-ia64/hardirq.h Thu Aug 10 19:56:31 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/hardirq.h Fri Aug 25 02:06:55 2000 @@ -39,8 +39,8 @@ # define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) # define hardirq_endlock(cpu) do { } while (0) -# define irq_enter(cpu, irq) (++local_irq_count(cpu)) -# define irq_exit(cpu, irq) (--local_irq_count(cpu)) +# define irq_enter(cpu, irq) (local_irq_count(cpu)++) +# define irq_exit(cpu, irq) (local_irq_count(cpu)--) # define synchronize_irq() barrier() #else @@ -72,7 +72,7 @@ static inline void irq_enter(int cpu, int irq) { - ++local_irq_count(cpu); + local_irq_count(cpu)++; while (test_bit(0,&global_irq_lock)) { /* nothing */; @@ -81,7 +81,7 @@ static inline void irq_exit(int cpu, int irq) { - --local_irq_count(cpu); + local_irq_count(cpu)--; } static inline int hardirq_trylock(int cpu) diff -urN linux-2.4.0-test7/include/asm-ia64/hw_irq.h linux-2.4.0-test7-lia/include/asm-ia64/hw_irq.h --- linux-2.4.0-test7/include/asm-ia64/hw_irq.h Fri Apr 21 15:21:24 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/hw_irq.h Fri Aug 25 02:06:54 2000 @@ -67,17 +67,7 @@ static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector) { - int my_cpu_id; - -#ifdef CONFIG_SMP - my_cpu_id = smp_processor_id(); -#else - __u64 lid; - - __asm__ ("mov %0=cr.lid" : "=r"(lid)); - my_cpu_id = (lid >> 24) & 0xff; /* extract id (ignore eid) */ -#endif - ipi_send(my_cpu_id, vector, IA64_IPI_DM_INT, 0); + ipi_send(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); } #endif /* _ASM_IA64_HW_IRQ_H */ diff -urN linux-2.4.0-test7/include/asm-ia64/offsets.h linux-2.4.0-test7-lia/include/asm-ia64/offsets.h --- linux-2.4.0-test7/include/asm-ia64/offsets.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/offsets.h Fri Aug 25 01:20:03 2000 @@ -11,7 +11,7 @@ #define PT_PTRACED_BIT 0 #define PT_TRACESYS_BIT 1 -#define IA64_TASK_SIZE 2864 /* 0xb30 */ +#define IA64_TASK_SIZE 2896 /* 0xb50 */ #define IA64_PT_REGS_SIZE 400 /* 0x190 */ #define IA64_SWITCH_STACK_SIZE 560 /* 0x230 */ #define IA64_SIGINFO_SIZE 128 /* 0x80 */ diff -urN linux-2.4.0-test7/include/asm-ia64/pci.h linux-2.4.0-test7-lia/include/asm-ia64/pci.h --- linux-2.4.0-test7/include/asm-ia64/pci.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/pci.h Fri Aug 25 02:08:04 2000 @@ -1,6 +1,7 @@ #ifndef _ASM_IA64_PCI_H #define _ASM_IA64_PCI_H +#include #include #include #include diff -urN linux-2.4.0-test7/include/asm-ia64/pgtable.h linux-2.4.0-test7-lia/include/asm-ia64/pgtable.h --- linux-2.4.0-test7/include/asm-ia64/pgtable.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/pgtable.h Fri Aug 25 02:07:29 2000 @@ -3,9 +3,9 @@ /* * This file contains the functions and defines necessary to modify and use - * the ia-64 page table tree. + * the IA-64 page table tree. * - * This hopefully works with any (fixed) ia-64 page-size, as defined + * This hopefully works with any (fixed) IA-64 page-size, as defined * in (currently 8192). * * Copyright (C) 1998-2000 Hewlett-Packard Co @@ -19,12 +19,6 @@ #define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */ -/* Is ADDR a valid kernel address? */ -#define kern_addr_valid(addr) ((addr) >= TASK_SIZE) - -/* Is ADDR a valid physical address? */ -#define phys_addr_valid(addr) (((addr) & my_cpu_data.unimpl_pa_mask) == 0) - /* * First, define the various bits in a PTE. Note that the PTE format * matches the VHPT short format, the firt doubleword of the VHPD long @@ -111,6 +105,7 @@ #include #include +#include #include /* @@ -166,7 +161,7 @@ * Given a pointer to an mem_map[] entry, return the kernel virtual * address corresponding to that page. */ -#define page_address(page) ((void *) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))) +#define page_address(page) ((page)->virtual) /* * Now for some cache flushing routines. This is the kind of stuff @@ -190,6 +185,28 @@ 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 +ia64_phys_addr_valid (unsigned long addr) +{ + return (addr & (my_cpu_data.unimpl_pa_mask)) == 0; +} + +/* + * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel + * memory. For the return value to be meaningful, ADDR must be >= + * PAGE_OFFSET. This operation can be relatively expensive (e.g., + * require a hash-, or multi-level tree-lookup or something of that + * sort) but it guarantees to return TRUE only if accessing the page + * at that address does not cause an error. Note that there may be + * addresses for which kern_addr_valid() returns FALSE even though an + * access would not cause an error (e.g., this is typically true for + * memory mapped I/O regions. + * + * XXX Need to implement this for IA-64. + */ +#define kern_addr_valid(addr) (1) + /* * Now come the defines and routines to manage and access the three-level * page table. @@ -248,14 +265,14 @@ #define pmd_set(pmdp, ptep) (pmd_val(*(pmdp)) = __pa(ptep)) #define pmd_none(pmd) (!pmd_val(pmd)) -#define pmd_bad(pmd) (!phys_addr_valid(pmd_val(pmd))) +#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd))) #define pmd_present(pmd) (pmd_val(pmd) != 0UL) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) #define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK)) #define pgd_set(pgdp, pmdp) (pgd_val(*(pgdp)) = __pa(pmdp)) #define pgd_none(pgd) (!pgd_val(pgd)) -#define pgd_bad(pgd) (!phys_addr_valid(pgd_val(pgd))) +#define pgd_bad(pgd) (!ia64_phys_addr_valid(pgd_val(pgd))) #define pgd_present(pgd) (pgd_val(pgd) != 0UL) #define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL) #define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & _PFN_MASK)) @@ -421,7 +438,7 @@ * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ -extern unsigned long empty_zero_page[1024]; +extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) # endif /* !__ASSEMBLY__ */ diff -urN linux-2.4.0-test7/include/asm-ia64/smp.h linux-2.4.0-test7-lia/include/asm-ia64/smp.h --- linux-2.4.0-test7/include/asm-ia64/smp.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/smp.h Fri Aug 25 02:06:54 2000 @@ -25,47 +25,64 @@ #define smp_processor_id() (current->processor) -struct smp_boot_data { +extern struct smp_boot_data { int cpu_count; - int cpu_map[NR_CPUS]; -}; + int cpu_phys_id[NR_CPUS]; +} smp_boot_data __initdata; extern unsigned long cpu_present_map; extern unsigned long cpu_online_map; extern unsigned long ipi_base_addr; extern int bootstrap_processor; -extern volatile int __cpu_number_map[NR_CPUS]; -extern volatile int __cpu_logical_map[NR_CPUS]; +extern volatile int __cpu_physical_id[NR_CPUS]; extern unsigned char smp_int_redirect; extern char no_int_routing; - -#define cpu_number_map(i) __cpu_number_map[i] -#define cpu_logical_map(i) __cpu_logical_map[i] +extern int smp_num_cpus; + +#define cpu_physical_id(i) __cpu_physical_id[i] +#define cpu_number_map(i) (i) +#define cpu_logical_map(i) (i) extern unsigned long ap_wakeup_vector; /* + * Function to map hard smp processor id to logical id. Slow, so + * don't use this in performance-critical code. + */ +extern __inline__ int +cpu_logical_id (int cpuid) +{ + int i; + + for (i=0; i NR_CPUS) - printk("WARNING: SMP ID %d > NR_CPUS\n", (lid.id << 8) | lid.eid); - return lid.id; -#endif + return lid.id << 8 | lid.eid; } #define NO_PROC_ID (-1) diff -urN linux-2.4.0-test7/include/asm-ia64/spinlock.h linux-2.4.0-test7-lia/include/asm-ia64/spinlock.h --- linux-2.4.0-test7/include/asm-ia64/spinlock.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/spinlock.h Fri Aug 25 02:06:54 2000 @@ -29,43 +29,37 @@ * Streamlined test_and_set_bit(0, (x)). We use test-and-test-and-set * rather than a simple xchg to avoid writing the cache-line when * there is contention. - * - * XXX Fix me: instead of preserving ar.pfs, we should just mark it - * XXX as "clobbered". Unfortunately, the Mar 2000 release of the compiler - * XXX doesn't let us do that. The August release fixes that. */ -#define spin_lock(x) \ -{ \ +#define spin_lock(x) \ +{ \ + register char *addr __asm__ ("r31") = (char *) &(x)->lock; \ + \ + __asm__ __volatile__ ( \ + "mov r30=1\n" \ + "mov ar.ccv=r0\n" \ + ";;\n" \ + IA64_SEMFIX"cmpxchg1.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" \ + ";;\n" \ + "1:\n" /* force a new bundle */ \ + :: "r"(addr) \ + : "ar.ccv", "ar.pfs", "b7", "p15", "r28", "r29", "r30", "memory"); \ +} + +#define spin_trylock(x) \ +({ \ register char *addr __asm__ ("r31") = (char *) &(x)->lock; \ - long saved_pfs; \ + register long result; \ \ __asm__ __volatile__ ( \ "mov r30=1\n" \ "mov ar.ccv=r0\n" \ ";;\n" \ - IA64_SEMFIX"cmpxchg1.acq r30=[%1],r30,ar.ccv\n" \ - ";;\n" \ - "cmp.ne p15,p0=r30,r0\n" \ - "mov %0=ar.pfs\n" \ - "(p15) br.call.spnt.few b7=ia64_spinlock_contention\n" \ - ";;\n" \ - "1: (p15) mov ar.pfs=%0;;\n" /* force a new bundle */ \ - : "=&r"(saved_pfs) : "r"(addr) \ - : "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) : "r30", "memory"); \ - (result == 0); \ + IA64_SEMFIX"cmpxchg1.acq %0=[%1],r30,ar.ccv\n" \ + : "=r"(result) : "r"(addr) : "ar.ccv", "r30", "memory"); \ + (result == 0); \ }) #define spin_is_locked(x) ((x)->lock != 0) @@ -91,16 +85,16 @@ "mov r29 = 1\n" \ ";;\n" \ "1:\n" \ - "ld4 r2 = %0\n" \ + "ld4 r2 = [%0]\n" \ ";;\n" \ "cmp4.eq p0,p7 = r0,r2\n" \ "(p7) br.cond.spnt.few 1b \n" \ - IA64_SEMFIX"cmpxchg4.acq r2 = %0, r29, ar.ccv\n" \ + IA64_SEMFIX"cmpxchg4.acq r2 = [%0], r29, ar.ccv\n" \ ";;\n" \ "cmp4.eq p0,p7 = r0, r2\n" \ "(p7) br.cond.spnt.few 1b\n" \ ";;\n" \ - :: "m" __atomic_fool_gcc((x)) : "r2", "r29", "memory") + :: "r"(&(x)->lock) : "r2", "r29", "memory") #define spin_is_locked(x) ((x)->lock != 0) #define spin_unlock(x) ({((spinlock_t *) x)->lock = 0; barrier();}) @@ -115,34 +109,34 @@ } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 } -#define read_lock(rw) \ -do { \ - int tmp = 0; \ - __asm__ __volatile__ ("1:\t"IA64_SEMFIX"fetchadd4.acq %0 = %1, 1\n" \ - ";;\n" \ - "tbit.nz p6,p0 = %0, 31\n" \ - "(p6) br.cond.sptk.few 2f\n" \ - ".section .text.lock,\"ax\"\n" \ - "2:\t"IA64_SEMFIX"fetchadd4.rel %0 = %1, -1\n" \ - ";;\n" \ - "3:\tld4.acq %0 = %1\n" \ - ";;\n" \ - "tbit.nz p6,p0 = %0, 31\n" \ - "(p6) br.cond.sptk.few 3b\n" \ - "br.cond.sptk.few 1b\n" \ - ";;\n" \ - ".previous\n" \ - : "=r" (tmp), "=m" (__atomic_fool_gcc(rw)) \ - :: "memory"); \ +#define read_lock(rw) \ +do { \ + int tmp = 0; \ + __asm__ __volatile__ ("1:\t"IA64_SEMFIX"fetchadd4.acq %0 = [%1], 1\n" \ + ";;\n" \ + "tbit.nz p6,p0 = %0, 31\n" \ + "(p6) br.cond.sptk.few 2f\n" \ + ".section .text.lock,\"ax\"\n" \ + "2:\t"IA64_SEMFIX"fetchadd4.rel %0 = [%1], -1\n" \ + ";;\n" \ + "3:\tld4.acq %0 = [%1]\n" \ + ";;\n" \ + "tbit.nz p6,p0 = %0, 31\n" \ + "(p6) br.cond.sptk.few 3b\n" \ + "br.cond.sptk.few 1b\n" \ + ";;\n" \ + ".previous\n" \ + : "=&r" (tmp) \ + : "r" (rw): "memory"); \ } while(0) -#define read_unlock(rw) \ -do { \ - int tmp = 0; \ - __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0 = %1, -1\n" \ - : "=r" (tmp) \ - : "m" (__atomic_fool_gcc(rw)) \ - : "memory"); \ +#define read_unlock(rw) \ +do { \ + int tmp = 0; \ + __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0 = [%1], -1\n" \ + : "=r" (tmp) \ + : "r" (rw) \ + : "memory"); \ } while(0) #define write_lock(rw) \ diff -urN linux-2.4.0-test7/include/asm-ia64/string.h linux-2.4.0-test7-lia/include/asm-ia64/string.h --- linux-2.4.0-test7/include/asm-ia64/string.h Wed Aug 2 18:54:53 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/string.h Fri Aug 25 02:06:53 2000 @@ -9,6 +9,9 @@ * Copyright (C) 1998-2000 David Mosberger-Tang */ +#include /* remove this once we remove the A-step workaround... */ +#ifndef CONFIG_ITANIUM_ASTEP_SPECIFIC + #define __HAVE_ARCH_STRLEN 1 /* see arch/ia64/lib/strlen.S */ #define __HAVE_ARCH_MEMSET 1 /* see arch/ia64/lib/memset.S */ #define __HAVE_ARCH_MEMCPY 1 /* see arch/ia64/lib/memcpy.S */ @@ -17,5 +20,7 @@ extern __kernel_size_t strlen (const char *); extern void *memset (void *, int, __kernel_size_t); extern void *memcpy (void *, const void *, __kernel_size_t); + +#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */ #endif /* _ASM_IA64_STRING_H */ diff -urN linux-2.4.0-test7/include/asm-ia64/system.h linux-2.4.0-test7-lia/include/asm-ia64/system.h --- linux-2.4.0-test7/include/asm-ia64/system.h Thu Aug 24 08:17:47 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/system.h Fri Aug 25 02:06:54 2000 @@ -240,15 +240,13 @@ ({ \ switch (sz) { \ case 4: \ - __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0=%1,%3" \ - : "=r"(tmp), "=m"(__atomic_fool_gcc(v)) \ - : "m" (__atomic_fool_gcc(v)), "i"(n)); \ + __asm__ __volatile__ (IA64_SEMFIX"fetchadd4.rel %0=[%1],%2" \ + : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ break; \ \ case 8: \ - __asm__ __volatile__ (IA64_SEMFIX"fetchadd8.rel %0=%1,%3" \ - : "=r"(tmp), "=m"(__atomic_fool_gcc(v)) \ - : "m" (__atomic_fool_gcc(v)), "i"(n)); \ + __asm__ __volatile__ (IA64_SEMFIX"fetchadd8.rel %0=[%1],%2" \ + : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ break; \ \ default: \ @@ -289,23 +287,23 @@ switch (size) { case 1: - __asm__ __volatile (IA64_SEMFIX"xchg1 %0=%1,%2" : "=r" (result) - : "m" (*(char *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg1 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; case 2: - __asm__ __volatile (IA64_SEMFIX"xchg2 %0=%1,%2" : "=r" (result) - : "m" (*(short *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg2 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; case 4: - __asm__ __volatile (IA64_SEMFIX"xchg4 %0=%1,%2" : "=r" (result) - : "m" (*(int *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg4 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; case 8: - __asm__ __volatile (IA64_SEMFIX"xchg8 %0=%1,%2" : "=r" (result) - : "m" (*(long *) ptr), "r" (x) : "memory"); + __asm__ __volatile (IA64_SEMFIX"xchg8 %0=[%1],%2" : "=r" (result) + : "r" (ptr), "r" (x) : "memory"); return result; } __xchg_called_with_bad_pointer(); @@ -329,9 +327,6 @@ */ extern long __cmpxchg_called_with_bad_pointer(void); -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) (*(struct __xchg_dummy *)(x)) - #define ia64_cmpxchg(sem,ptr,old,new,size) \ ({ \ __typeof__(ptr) _p_ = (ptr); \ @@ -348,27 +343,23 @@ __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_)); \ switch (size) { \ case 1: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg1."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg1."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ case 2: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg2."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg2."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ case 4: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg4."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg4."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ case 8: \ - __asm__ __volatile__ (IA64_SEMFIX"cmpxchg8."sem" %0=%2,%3,ar.ccv" \ - : "=r"(_r_), "=m"(__xg(_p_)) \ - : "m"(__xg(_p_)), "r"(_n_)); \ + __asm__ __volatile__ (IA64_SEMFIX"cmpxchg8."sem" %0=[%1],%2,ar.ccv" \ + : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ break; \ \ default: \ diff -urN linux-2.4.0-test7/include/asm-ia64/uaccess.h linux-2.4.0-test7-lia/include/asm-ia64/uaccess.h --- linux-2.4.0-test7/include/asm-ia64/uaccess.h Fri Apr 21 15:21:24 2000 +++ linux-2.4.0-test7-lia/include/asm-ia64/uaccess.h Fri Aug 25 02:06:56 2000 @@ -136,7 +136,7 @@ #define __m(x) (*(struct __large_struct *)(x)) #define __get_user_64(addr) \ - __asm__ ("\n1:\tld8 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __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" \ @@ -146,7 +146,7 @@ : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_32(addr) \ - __asm__ ("\n1:\tld4 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __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" \ @@ -156,7 +156,7 @@ : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_16(addr) \ - __asm__ ("\n1:\tld2 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __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" \ @@ -166,7 +166,7 @@ : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_8(addr) \ - __asm__ ("\n1:\tld1 %0=%2\t// %0 and %1 get overwritten by exception handler\n" \ + __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" \ @@ -215,7 +215,7 @@ */ #define __put_user_64(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst8 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\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" \ @@ -226,7 +226,7 @@ #define __put_user_32(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst4 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\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" \ @@ -237,7 +237,7 @@ #define __put_user_16(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst2 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\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" \ @@ -248,7 +248,7 @@ #define __put_user_8(x,addr) \ __asm__ __volatile__ ( \ - "\n1:\tst1 %1=%r2\t// %0 gets overwritten by exception handler\n" \ + "\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" \ diff -urN linux-2.4.0-test7/include/linux/irq.h linux-2.4.0-test7-lia/include/linux/irq.h --- linux-2.4.0-test7/include/linux/irq.h Fri Jul 14 17:19:28 2000 +++ linux-2.4.0-test7-lia/include/linux/irq.h Fri Aug 25 02:06:55 2000 @@ -56,6 +56,7 @@ #include /* the arch dependent stuff */ +extern unsigned int do_IRQ (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-test7/include/linux/mmzone.h linux-2.4.0-test7-lia/include/linux/mmzone.h --- linux-2.4.0-test7/include/linux/mmzone.h Fri Jul 14 17:19:28 2000 +++ linux-2.4.0-test7-lia/include/linux/mmzone.h Fri Aug 25 02:06:58 2000 @@ -26,10 +26,10 @@ * Commonly accessed fields: */ spinlock_t lock; - unsigned long offset; - unsigned long free_pages; char low_on_memory; char zone_wake_kswapd; + unsigned long offset; + unsigned long free_pages; unsigned long pages_min, pages_low, pages_high; /* diff -urN linux-2.4.0-test7/include/linux/sched.h linux-2.4.0-test7-lia/include/linux/sched.h --- linux-2.4.0-test7/include/linux/sched.h Thu Aug 24 08:17:48 2000 +++ linux-2.4.0-test7-lia/include/linux/sched.h Fri Aug 25 02:06:55 2000 @@ -704,7 +704,8 @@ extern int expand_fdset(struct files_struct *, int nr); extern void free_fdset(fd_set *, int); -extern int copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); +extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, + struct pt_regs *); extern void flush_thread(void); extern void exit_thread(void); @@ -715,7 +716,7 @@ extern void daemonize(void); extern int do_execve(char *, char **, char **, struct pt_regs *); -extern int do_fork(unsigned long, unsigned long, struct pt_regs *); +extern int do_fork(unsigned long, unsigned long, unsigned long, struct pt_regs *); extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); diff -urN linux-2.4.0-test7/init/main.c linux-2.4.0-test7-lia/init/main.c --- linux-2.4.0-test7/init/main.c Thu Aug 24 08:17:48 2000 +++ linux-2.4.0-test7-lia/init/main.c Fri Aug 25 00:12:37 2000 @@ -111,6 +111,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 @@ -552,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-test7/kernel/fork.c linux-2.4.0-test7-lia/kernel/fork.c --- linux-2.4.0-test7/kernel/fork.c Thu Aug 24 08:17:48 2000 +++ linux-2.4.0-test7-lia/kernel/fork.c Fri Aug 25 00:12:37 2000 @@ -528,10 +528,15 @@ /* * Ok, this is the main fork-routine. It copies the system process - * information (task[nr]) and sets up the necessary registers. It - * also copies the data segment in its entirety. + * information (task[nr]) and sets up the necessary registers. It also + * copies the data segment in its entirety. The "stack_start" and + * "stack_top" arguments are simply passed along to the platform + * specific copy_thread() routine. Most platforms ignore stack_top. + * For an example that's using stack_top, see + * arch/ia64/kernel/process.c. */ -int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) +int do_fork(unsigned long clone_flags, unsigned long stack_start, unsigned long stack_top, + struct pt_regs *regs) { int retval = -ENOMEM; struct task_struct *p; @@ -628,7 +633,7 @@ goto bad_fork_cleanup_fs; if (copy_mm(clone_flags, p)) goto bad_fork_cleanup_sighand; - retval = copy_thread(0, clone_flags, usp, p, regs); + retval = copy_thread(0, clone_flags, stack_start, stack_top, p, regs); if (retval) goto bad_fork_cleanup_sighand; p->semundo = NULL; diff -urN linux-2.4.0-test7/kernel/printk.c linux-2.4.0-test7-lia/kernel/printk.c --- linux-2.4.0-test7/kernel/printk.c Wed Jul 5 11:00:21 2000 +++ linux-2.4.0-test7-lia/kernel/printk.c Fri Aug 11 19:10:10 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 *)0x00000000000b8000) + +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-test7/kernel/timer.c linux-2.4.0-test7-lia/kernel/timer.c --- linux-2.4.0-test7/kernel/timer.c Thu Aug 24 08:17:49 2000 +++ linux-2.4.0-test7-lia/kernel/timer.c Fri Aug 25 00:12:40 2000 @@ -678,7 +678,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 */